Skip to content

Commit c179dfa

Browse files
[InstCombine] fold float clamp pattern into llvm.max/min
%v0 = fcmp nsz ogt float %arg0, 0.000000e+00 %v1 = select nsz i1 %v0, float %arg0, float 0.000000e+00 ==== %v0 = call float @llvm.maxnum.f32(float %arg0, float 0.000000e+00[) ==== fcmp + select patterns can be folded into fmax/fmin. This patch handles this transformation for OGT and OLT. Fixes #157486
1 parent e2040f5 commit c179dfa

File tree

14 files changed

+126
-122
lines changed

14 files changed

+126
-122
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,6 +3963,60 @@ static Value *foldSelectIntoAddConstant(SelectInst &SI,
39633963
return nullptr;
39643964
}
39653965

3966+
// fcmp + sel patterns into max/min intrinsic.
3967+
static Value *foldSelectICmpIntoMaxMin(SelectInst &SI,
3968+
InstCombiner::BuilderTy &Builder) {
3969+
3970+
auto TryFoldIntoMaxMinIntrinsic =
3971+
[&Builder, &SI](CmpInst::Predicate Pred, Value *CmpLHS, Value *CmpRHS,
3972+
Value *TVal, Value *FVal) -> Value * {
3973+
// Early exit if the operands are not in the expected form.
3974+
if ((CmpRHS != TVal || CmpLHS != FVal) &&
3975+
(CmpLHS != TVal || CmpRHS != FVal))
3976+
return nullptr;
3977+
3978+
bool isSwapped = (CmpLHS == FVal && CmpRHS == TVal);
3979+
// Only these relational predicates can be transformed into maxnum/minnum
3980+
// intrinsic.
3981+
// X > C ? X : C --> maxnum(X, C)
3982+
// X > C ? C : X --> minnum(X, C)
3983+
if (Pred == CmpInst::FCMP_OGT) {
3984+
Intrinsic::ID MaxMinIID =
3985+
isSwapped ? Intrinsic::minnum : Intrinsic::maxnum;
3986+
return Builder.CreateIntrinsic(SI.getType(), MaxMinIID, {TVal, FVal},
3987+
&SI);
3988+
}
3989+
3990+
// X < C ? X : C --> minnum(X, C)
3991+
// X < C ? C : X --> maxnum(X, C)
3992+
if (Pred == CmpInst::FCMP_OLT) {
3993+
Intrinsic::ID MaxMinIID =
3994+
isSwapped ? Intrinsic::maxnum : Intrinsic::minnum;
3995+
return Builder.CreateIntrinsic(SI.getType(), MaxMinIID, {TVal, FVal},
3996+
&SI);
3997+
}
3998+
3999+
return nullptr;
4000+
};
4001+
4002+
// select((fcmp Pred, X, Y), X, Y)
4003+
// => minnum/maxnum(X, Y)
4004+
//
4005+
// Pred := OGT and OLT
4006+
Value *X, *Y;
4007+
Value *TVal, *FVal;
4008+
CmpPredicate Pred;
4009+
4010+
// Note: OneUse check for `Cmp` is necessary because it makes sure that other
4011+
// InstCombine folds don't undo this transformation and cause an infinite
4012+
// loop. Furthermore, it could also increase the operation count.
4013+
if (match(&SI, m_OneUse(m_Select(m_OneUse(m_FCmp(Pred, m_Value(X), m_Value(Y))),
4014+
m_Value(TVal), m_Value(FVal)))))
4015+
return TryFoldIntoMaxMinIntrinsic(Pred, X, Y, TVal, FVal);
4016+
4017+
return nullptr;
4018+
}
4019+
39664020
static Value *foldSelectBitTest(SelectInst &Sel, Value *CondVal, Value *TrueVal,
39674021
Value *FalseVal,
39684022
InstCombiner::BuilderTy &Builder,
@@ -4455,6 +4509,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
44554509
if (Value *V = foldSelectIntoAddConstant(SI, Builder))
44564510
return replaceInstUsesWith(SI, V);
44574511

4512+
if (Value *V = foldSelectICmpIntoMaxMin(SI, Builder))
4513+
return replaceInstUsesWith(SI, V);
4514+
44584515
// select(mask, mload(,,mask,0), 0) -> mload(,,mask,0)
44594516
// Load inst is intentionally not checked for hasOneUse()
44604517
if (match(FalseVal, m_Zero()) &&

llvm/test/Transforms/InstCombine/clamp-to-minmax.ll

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
; (X < C1) ? C1 : MIN(X, C2)
66
define float @clamp_float_fast_ordered_strict_maxmin(float %x) {
77
; CHECK-LABEL: @clamp_float_fast_ordered_strict_maxmin(
8-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
9-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
10-
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
11-
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
8+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
9+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast olt float [[X]], 1.000000e+00
10+
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
1211
; CHECK-NEXT: ret float [[R1]]
1312
;
1413
%cmp2 = fcmp fast olt float %x, 255.0
@@ -21,10 +20,9 @@ define float @clamp_float_fast_ordered_strict_maxmin(float %x) {
2120
; (X <= C1) ? C1 : MIN(X, C2)
2221
define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) {
2322
; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_maxmin(
24-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
25-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
26-
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
27-
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
23+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
24+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ole float [[X]], 1.000000e+00
25+
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
2826
; CHECK-NEXT: ret float [[R1]]
2927
;
3028
%cmp2 = fcmp fast olt float %x, 255.0
@@ -37,10 +35,9 @@ define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) {
3735
; (X > C1) ? C1 : MAX(X, C2)
3836
define float @clamp_float_fast_ordered_strict_minmax(float %x) {
3937
; CHECK-LABEL: @clamp_float_fast_ordered_strict_minmax(
40-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
41-
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
42-
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
43-
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
38+
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
39+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ogt float [[X]], 2.550000e+02
40+
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
4441
; CHECK-NEXT: ret float [[R1]]
4542
;
4643
%cmp2 = fcmp fast ogt float %x, 1.0
@@ -53,10 +50,9 @@ define float @clamp_float_fast_ordered_strict_minmax(float %x) {
5350
; (X >= C1) ? C1 : MAX(X, C2)
5451
define float @clamp_float_fast_ordered_nonstrict_minmax(float %x) {
5552
; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_minmax(
56-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
57-
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
58-
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
59-
; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
53+
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
54+
; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast oge float [[X]], 2.550000e+02
55+
; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
6056
; CHECK-NEXT: ret float [[R1]]
6157
;
6258
%cmp2 = fcmp fast ogt float %x, 1.0
@@ -191,8 +187,7 @@ define float @clamp_negative_same_op(float %x) {
191187
; First, check that we don't do bad things in the presence of signed zeros
192188
define float @clamp_float_with_zero1(float %x) {
193189
; CHECK-LABEL: @clamp_float_with_zero1(
194-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
195-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
190+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
196191
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ole float [[X]], 0.000000e+00
197192
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 0.000000e+00, float [[MIN]]
198193
; CHECK-NEXT: ret float [[R]]
@@ -206,8 +201,7 @@ define float @clamp_float_with_zero1(float %x) {
206201

207202
define float @clamp_float_with_zero2(float %x) {
208203
; CHECK-LABEL: @clamp_float_with_zero2(
209-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
210-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
204+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
211205
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 0.000000e+00
212206
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 0.000000e+00, float [[MIN]]
213207
; CHECK-NEXT: ret float [[R]]
@@ -228,8 +222,7 @@ define float @clamp_float_with_zero2(float %x) {
228222
; (X < C1) ? C1 : MIN(X, C2)
229223
define float @clamp_float_ordered_strict_maxmin1(float %x) {
230224
; CHECK-LABEL: @clamp_float_ordered_strict_maxmin1(
231-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
232-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
225+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
233226
; CHECK-NEXT: [[CMP1:%.*]] = fcmp olt float [[X]], 1.000000e+00
234227
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
235228
; CHECK-NEXT: ret float [[R]]
@@ -259,8 +252,7 @@ define float @clamp_float_ordered_strict_maxmin2(float %x) {
259252
; (X <= C1) ? C1 : MIN(X, C2)
260253
define float @clamp_float_ordered_nonstrict_maxmin1(float %x) {
261254
; CHECK-LABEL: @clamp_float_ordered_nonstrict_maxmin1(
262-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
263-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
255+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
264256
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ole float [[X]], 1.000000e+00
265257
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
266258
; CHECK-NEXT: ret float [[R]]
@@ -290,8 +282,7 @@ define float @clamp_float_ordered_nonstrict_maxmin2(float %x) {
290282
; (X > C1) ? C1 : MAX(X, C2)
291283
define float @clamp_float_ordered_strict_minmax1(float %x) {
292284
; CHECK-LABEL: @clamp_float_ordered_strict_minmax1(
293-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
294-
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
285+
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
295286
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt float [[X]], 2.550000e+02
296287
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
297288
; CHECK-NEXT: ret float [[R]]
@@ -321,8 +312,7 @@ define float @clamp_float_ordered_strict_minmax2(float %x) {
321312
; (X >= C1) ? C1 : MAX(X, C2)
322313
define float @clamp_float_ordered_nonstrict_minmax1(float %x) {
323314
; CHECK-LABEL: @clamp_float_ordered_nonstrict_minmax1(
324-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
325-
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
315+
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
326316
; CHECK-NEXT: [[CMP1:%.*]] = fcmp oge float [[X]], 2.550000e+02
327317
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
328318
; CHECK-NEXT: ret float [[R]]
@@ -355,8 +345,7 @@ define float @clamp_float_ordered_nonstrict_minmax2(float %x) {
355345
; (X < C1) ? C1 : MIN(X, C2)
356346
define float @clamp_float_unordered_strict_maxmin1(float %x) {
357347
; CHECK-LABEL: @clamp_float_unordered_strict_maxmin1(
358-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
359-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
348+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
360349
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ult float [[X]], 1.000000e+00
361350
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
362351
; CHECK-NEXT: ret float [[R]]
@@ -386,8 +375,7 @@ define float @clamp_float_unordered_strict_maxmin2(float %x) {
386375
; (X <= C1) ? C1 : MIN(X, C2)
387376
define float @clamp_float_unordered_nonstrict_maxmin1(float %x) {
388377
; CHECK-LABEL: @clamp_float_unordered_nonstrict_maxmin1(
389-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt float [[X:%.*]], 2.550000e+02
390-
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
378+
; CHECK-NEXT: [[MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
391379
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ule float [[X]], 1.000000e+00
392380
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
393381
; CHECK-NEXT: ret float [[R]]
@@ -417,8 +405,7 @@ define float @clamp_float_unordered_nonstrict_maxmin2(float %x) {
417405
; (X > C1) ? C1 : MAX(X, C2)
418406
define float @clamp_float_unordered_strict_minmax1(float %x) {
419407
; CHECK-LABEL: @clamp_float_unordered_strict_minmax1(
420-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
421-
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
408+
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
422409
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ugt float [[X]], 2.550000e+02
423410
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
424411
; CHECK-NEXT: ret float [[R]]
@@ -448,8 +435,7 @@ define float @clamp_float_unordered_strict_minmax2(float %x) {
448435
; (X >= C1) ? C1 : MAX(X, C2)
449436
define float @clamp_float_unordered_nonstrict_minmax1(float %x) {
450437
; CHECK-LABEL: @clamp_float_unordered_nonstrict_minmax1(
451-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[X:%.*]], 1.000000e+00
452-
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
438+
; CHECK-NEXT: [[MAX:%.*]] = call float @llvm.maxnum.f32(float [[X:%.*]], float 1.000000e+00)
453439
; CHECK-NEXT: [[CMP1:%.*]] = fcmp uge float [[X]], 2.550000e+02
454440
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
455441
; CHECK-NEXT: ret float [[R]]
@@ -527,8 +513,7 @@ define float @mixed_clamp_to_float_1(i32 %x) {
527513

528514
define i32 @mixed_clamp_to_i32_1(float %x) {
529515
; CHECK-LABEL: @mixed_clamp_to_i32_1(
530-
; CHECK-NEXT: [[FLOAT_MIN_CMP:%.*]] = fcmp ogt float [[X:%.*]], 2.550000e+02
531-
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = select i1 [[FLOAT_MIN_CMP]], float 2.550000e+02, float [[X]]
516+
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
532517
; CHECK-NEXT: [[I32_MIN:%.*]] = fptosi float [[FLOAT_MIN]] to i32
533518
; CHECK-NEXT: [[I32_X:%.*]] = fptosi float [[X]] to i32
534519
; CHECK-NEXT: [[LO_CMP:%.*]] = icmp eq i32 [[I32_X]], 0
@@ -561,8 +546,7 @@ define float @mixed_clamp_to_float_2(i32 %x) {
561546

562547
define i32 @mixed_clamp_to_i32_2(float %x) {
563548
; CHECK-LABEL: @mixed_clamp_to_i32_2(
564-
; CHECK-NEXT: [[FLOAT_MIN_CMP:%.*]] = fcmp ogt float [[X:%.*]], 2.550000e+02
565-
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = select i1 [[FLOAT_MIN_CMP]], float 2.550000e+02, float [[X]]
549+
; CHECK-NEXT: [[FLOAT_MIN:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float 2.550000e+02)
566550
; CHECK-NEXT: [[I32_MIN:%.*]] = fptosi float [[FLOAT_MIN]] to i32
567551
; CHECK-NEXT: [[LO_CMP:%.*]] = fcmp olt float [[X]], 1.000000e+00
568552
; CHECK-NEXT: [[R:%.*]] = select i1 [[LO_CMP]], i32 1, i32 [[I32_MIN]]

llvm/test/Transforms/InstCombine/fcmp-select.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,8 @@ define <2 x i1> @test_fcmp_select_const_const_vec(<2 x double> %x) {
202202

203203
define double @test_fcmp_select_clamp(double %x) {
204204
; CHECK-LABEL: @test_fcmp_select_clamp(
205-
; CHECK-NEXT: [[CMP1:%.*]] = fcmp ogt double [[X:%.*]], 9.000000e-01
206-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], double 9.000000e-01, double [[X]]
207-
; CHECK-NEXT: [[CMP2:%.*]] = fcmp olt double [[SEL1]], 5.000000e-01
208-
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], double 5.000000e-01, double [[SEL1]]
205+
; CHECK-NEXT: [[SEL1:%.*]] = call double @llvm.minnum.f64(double [[X:%.*]], double 9.000000e-01)
206+
; CHECK-NEXT: [[SEL2:%.*]] = call double @llvm.maxnum.f64(double [[SEL1]], double 5.000000e-01)
209207
; CHECK-NEXT: ret double [[SEL2]]
210208
;
211209
%cmp1 = fcmp ogt double %x, 9.000000e-01
@@ -284,8 +282,7 @@ define i1 @test_fcmp_ord_select_fcmp_oeq_var_const(double %x) {
284282

285283
define float @test_select_nnan_nsz_fcmp_olt(float %x) {
286284
; CHECK-LABEL: @test_select_nnan_nsz_fcmp_olt(
287-
; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
288-
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
285+
; CHECK-NEXT: [[SEL1:%.*]] = call float @llvm.minnum.f32(float [[X:%.*]], float -0.000000e+00)
289286
; CHECK-NEXT: ret float [[SEL1]]
290287
;
291288
%cmp = fcmp olt float %x, 0.000000e+00

llvm/test/Transforms/InstCombine/fptrunc.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,9 @@ define half @fptrunc_select_true_val_extra_use(half %x, float %y, i1 %cond) {
116116

117117
define half @fptrunc_max(half %arg) {
118118
; CHECK-LABEL: @fptrunc_max(
119-
; CHECK-NEXT: [[CMP:%.*]] = fcmp olt half [[ARG:%.*]], 0xH0000
120-
; CHECK-NEXT: [[NARROW_SEL:%.*]] = select i1 [[CMP]], half 0xH0000, half [[ARG]]
119+
; CHECK-NEXT: [[EXT:%.*]] = fpext half [[ARG:%.*]] to double
120+
; CHECK-NEXT: [[MAX:%.*]] = call double @llvm.maxnum.f64(double [[EXT]], double 0.000000e+00)
121+
; CHECK-NEXT: [[NARROW_SEL:%.*]] = fptrunc double [[MAX]] to half
121122
; CHECK-NEXT: ret half [[NARROW_SEL]]
122123
;
123124
%ext = fpext half %arg to double

llvm/test/Transforms/InstCombine/load-bitcast-select.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ define void @_Z3foov() {
2020
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw float, ptr @b, i64 [[TMP0]]
2121
; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX]], align 4
2222
; CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX2]], align 4
23-
; CHECK-NEXT: [[CMP_I:%.*]] = fcmp fast olt float [[TMP1]], [[TMP2]]
24-
; CHECK-NEXT: [[DOTV:%.*]] = select i1 [[CMP_I]], float [[TMP2]], float [[TMP1]]
23+
; CHECK-NEXT: [[DOTV:%.*]] = call float @llvm.maxnum.f32(float [[TMP2]], float [[TMP1]])
2524
; CHECK-NEXT: store float [[DOTV]], ptr [[ARRAYIDX]], align 4
2625
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
2726
; CHECK-NEXT: br label [[FOR_COND]]
@@ -79,8 +78,7 @@ define void @bitcasted_minmax_with_select_of_pointers(ptr %loadaddr1, ptr %loada
7978
; CHECK-LABEL: @bitcasted_minmax_with_select_of_pointers(
8079
; CHECK-NEXT: [[LD1:%.*]] = load float, ptr [[LOADADDR1:%.*]], align 4
8180
; CHECK-NEXT: [[LD2:%.*]] = load float, ptr [[LOADADDR2:%.*]], align 4
82-
; CHECK-NEXT: [[COND:%.*]] = fcmp ogt float [[LD1]], [[LD2]]
83-
; CHECK-NEXT: [[LD_V:%.*]] = select i1 [[COND]], float [[LD1]], float [[LD2]]
81+
; CHECK-NEXT: [[LD_V:%.*]] = call float @llvm.maxnum.f32(float [[LD1]], float [[LD2]])
8482
; CHECK-NEXT: store float [[LD_V]], ptr [[STOREADDR:%.*]], align 4
8583
; CHECK-NEXT: ret void
8684
;

0 commit comments

Comments
 (0)