Skip to content

Commit fe41e3e

Browse files
committed
[InstCombine] Add an additional nnan constraint for xfrm fcmp + sel => fmax/fmin
Add an additional `nnan` constraint on the `fcmp` instruction for the `fcmp` + `select` => `fmax`/`fmin` xfrm. Without the `nnan` constraint, this transformation is incorrect. Alive2 with and without the fix: https://alive2.llvm.org/ce/z/Hpo7WX
1 parent 93f7398 commit fe41e3e

File tree

6 files changed

+36
-33
lines changed

6 files changed

+36
-33
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3864,9 +3864,12 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
38643864
if (SIFPOp) {
38653865
// TODO: Try to forward-propagate FMF from select arms to the select.
38663866

3867+
auto *FCmp = dyn_cast<FCmpInst>(CondVal);
3868+
38673869
// Canonicalize select of FP values where NaN and -0.0 are not valid as
38683870
// minnum/maxnum intrinsics.
3869-
if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
3871+
if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros() && FCmp &&
3872+
FCmp->hasNoNaNs()) {
38703873
Value *X, *Y;
38713874
if (match(&SI, m_OrdOrUnordFMax(m_Value(X), m_Value(Y))))
38723875
return replaceInstUsesWith(

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

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ define float @test_fcmp_ogt_fadd_select_constant(float %in) {
1010
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
1111
; CHECK-NEXT: ret float [[ADD_NEW]]
1212
;
13-
%cmp1 = fcmp ogt float %in, 0.000000e+00
13+
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
1414
%add = fadd float %in, 1.000000e+00
1515
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
1616
ret float %sel
@@ -23,7 +23,7 @@ define float @test_fcmp_ogt_fadd_select_constant_swapped(float %in) {
2323
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
2424
; CHECK-NEXT: ret float [[ADD_NEW]]
2525
;
26-
%cmp1 = fcmp ogt float %in, 0.000000e+00
26+
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
2727
%add = fadd float %in, 1.000000e+00
2828
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
2929
ret float %sel
@@ -36,7 +36,7 @@ define float @test_fcmp_ogt_fadd_select_neg_constant(float %in) {
3636
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
3737
; CHECK-NEXT: ret float [[ADD_NEW]]
3838
;
39-
%cmp1 = fcmp ogt float %in, -0.000000e+00
39+
%cmp1 = fcmp nnan ogt float %in, -0.000000e+00
4040
%add = fadd float %in, 1.000000e+00
4141
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
4242
ret float %sel
@@ -49,7 +49,7 @@ define float @test_fcmp_ogt_fadd_select_fastmath_preserve(float %in) {
4949
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
5050
; CHECK-NEXT: ret float [[ADD_NEW]]
5151
;
52-
%cmp1 = fcmp ogt float %in, 0.000000e+00
52+
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
5353
%add = fadd nnan float %in, 1.000000e+00
5454
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
5555
ret float %sel
@@ -62,7 +62,7 @@ define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(<2 x float> %in)
6262
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
6363
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
6464
;
65-
%cmp1 = fcmp ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
65+
%cmp1 = fcmp nnan ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
6666
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
6767
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
6868
ret <2 x float> %sel
@@ -78,7 +78,7 @@ define float @test_fcmp_olt_fadd_select_constant(float %in) {
7878
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
7979
; CHECK-NEXT: ret float [[ADD_NEW]]
8080
;
81-
%cmp1 = fcmp olt float %in, 0.000000e+00
81+
%cmp1 = fcmp nnan olt float %in, 0.000000e+00
8282
%add = fadd float %in, 1.000000e+00
8383
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
8484
ret float %sel
@@ -91,7 +91,7 @@ define float @test_fcmp_olt_fadd_select_constant_swapped(float %in) {
9191
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
9292
; CHECK-NEXT: ret float [[ADD_NEW]]
9393
;
94-
%cmp1 = fcmp olt float %in, 0.000000e+00
94+
%cmp1 = fcmp nnan olt float %in, 0.000000e+00
9595
%add = fadd float %in, 1.000000e+00
9696
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
9797
ret float %sel
@@ -104,7 +104,7 @@ define float @test_fcmp_olt_fadd_select_neg_constant(float %in) {
104104
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
105105
; CHECK-NEXT: ret float [[ADD_NEW]]
106106
;
107-
%cmp1 = fcmp olt float %in, -0.000000e+00
107+
%cmp1 = fcmp nnan olt float %in, -0.000000e+00
108108
%add = fadd float %in, 1.000000e+00
109109
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
110110
ret float %sel
@@ -117,7 +117,7 @@ define float @test_fcmp_olt_fadd_select_fastmath_preserve(float %in) {
117117
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
118118
; CHECK-NEXT: ret float [[ADD_NEW]]
119119
;
120-
%cmp1 = fcmp olt float %in, 0.000000e+00
120+
%cmp1 = fcmp nnan olt float %in, 0.000000e+00
121121
%add = fadd nnan float %in, 1.000000e+00
122122
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
123123
ret float %sel
@@ -130,7 +130,7 @@ define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(<2 x float> %in)
130130
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
131131
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
132132
;
133-
%cmp1 = fcmp olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
133+
%cmp1 = fcmp nnan olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
134134
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
135135
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
136136
ret <2 x float> %sel
@@ -146,7 +146,7 @@ define float @test_fcmp_oge_fadd_select_constant(float %in) {
146146
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
147147
; CHECK-NEXT: ret float [[ADD_NEW]]
148148
;
149-
%cmp1 = fcmp oge float %in, 0.000000e+00
149+
%cmp1 = fcmp nnan oge float %in, 0.000000e+00
150150
%add = fadd float %in, 1.000000e+00
151151
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
152152
ret float %sel
@@ -159,7 +159,7 @@ define float @test_fcmp_oge_fadd_select_constant_swapped(float %in) {
159159
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
160160
; CHECK-NEXT: ret float [[ADD_NEW]]
161161
;
162-
%cmp1 = fcmp oge float %in, 0.000000e+00
162+
%cmp1 = fcmp nnan oge float %in, 0.000000e+00
163163
%add = fadd float %in, 1.000000e+00
164164
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
165165
ret float %sel
@@ -172,7 +172,7 @@ define float @test_fcmp_oge_fadd_select_neg_constant(float %in) {
172172
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
173173
; CHECK-NEXT: ret float [[ADD_NEW]]
174174
;
175-
%cmp1 = fcmp oge float %in, -0.000000e+00
175+
%cmp1 = fcmp nnan oge float %in, -0.000000e+00
176176
%add = fadd float %in, 1.000000e+00
177177
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
178178
ret float %sel
@@ -185,7 +185,7 @@ define float @test_fcmp_oge_fadd_select_fastmath_preserve(float %in) {
185185
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
186186
; CHECK-NEXT: ret float [[ADD_NEW]]
187187
;
188-
%cmp1 = fcmp oge float %in, 0.000000e+00
188+
%cmp1 = fcmp nnan oge float %in, 0.000000e+00
189189
%add = fadd nnan float %in, 1.000000e+00
190190
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
191191
ret float %sel
@@ -198,7 +198,7 @@ define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(<2 x float> %in)
198198
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
199199
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
200200
;
201-
%cmp1 = fcmp oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
201+
%cmp1 = fcmp nnan oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
202202
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
203203
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
204204
ret <2 x float> %sel
@@ -214,7 +214,7 @@ define float @test_fcmp_ole_fadd_select_constant(float %in) {
214214
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
215215
; CHECK-NEXT: ret float [[ADD_NEW]]
216216
;
217-
%cmp1 = fcmp ole float %in, 0.000000e+00
217+
%cmp1 = fcmp nnan ole float %in, 0.000000e+00
218218
%add = fadd float %in, 1.000000e+00
219219
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
220220
ret float %sel
@@ -227,7 +227,7 @@ define float @test_fcmp_ole_fadd_select_constant_swapped(float %in) {
227227
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
228228
; CHECK-NEXT: ret float [[ADD_NEW]]
229229
;
230-
%cmp1 = fcmp ole float %in, 0.000000e+00
230+
%cmp1 = fcmp nnan ole float %in, 0.000000e+00
231231
%add = fadd float %in, 1.000000e+00
232232
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
233233
ret float %sel
@@ -240,7 +240,7 @@ define float @test_fcmp_ole_fadd_select_neg_constant(float %in) {
240240
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
241241
; CHECK-NEXT: ret float [[ADD_NEW]]
242242
;
243-
%cmp1 = fcmp ole float %in, -0.000000e+00
243+
%cmp1 = fcmp nnan ole float %in, -0.000000e+00
244244
%add = fadd float %in, 1.000000e+00
245245
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
246246
ret float %sel
@@ -253,7 +253,7 @@ define float @test_fcmp_ole_fadd_select_fastmath_preserve(float %in) {
253253
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
254254
; CHECK-NEXT: ret float [[ADD_NEW]]
255255
;
256-
%cmp1 = fcmp ole float %in, 0.000000e+00
256+
%cmp1 = fcmp nnan ole float %in, 0.000000e+00
257257
%add = fadd nnan float %in, 1.000000e+00
258258
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
259259
ret float %sel
@@ -266,7 +266,7 @@ define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(<2 x float> %in)
266266
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
267267
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
268268
;
269-
%cmp1 = fcmp ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
269+
%cmp1 = fcmp nnan ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
270270
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
271271
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
272272
ret <2 x float> %sel
@@ -641,7 +641,7 @@ define float @test_fcmp_ogt_fadd_select_rewrite_flags1(float %in) {
641641
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd reassoc nnan nsz arcp contract afn float [[SEL_NEW]], 1.000000e+00
642642
; CHECK-NEXT: ret float [[ADD_NEW]]
643643
;
644-
%cmp1 = fcmp ogt float %in, 0.000000e+00
644+
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
645645
%add = fadd reassoc afn arcp contract float %in, 1.000000e+00
646646
%sel = select nnan nsz reassoc afn arcp contract i1 %cmp1, float %add, float 1.000000e+00
647647
ret float %sel
@@ -654,7 +654,7 @@ define float @test_fcmp_ogt_fadd_select_rewrite_flags2(float %in) {
654654
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
655655
; CHECK-NEXT: ret float [[ADD_NEW]]
656656
;
657-
%cmp1 = fcmp ogt float %in, 0.000000e+00
657+
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
658658
%add = fadd reassoc float %in, 1.000000e+00
659659
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
660660
ret float %sel
@@ -667,7 +667,7 @@ define float @test_fcmp_ogt_fadd_select_rewrite_and_fastmath(float %in) {
667667
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd fast float [[SEL_NEW]], 1.000000e+00
668668
; CHECK-NEXT: ret float [[ADD_NEW]]
669669
;
670-
%cmp1 = fcmp ogt float %in, 0.000000e+00
670+
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
671671
%add = fadd fast reassoc float %in, 1.000000e+00
672672
%sel = select fast i1 %cmp1, float %add, float 1.000000e+00
673673
ret float %sel

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,9 @@ define double @test_fcmp_select_maxnum(double %x) {
223223
; CHECK-NEXT: [[SEL2:%.*]] = call nnan nsz double @llvm.minnum.f64(double [[SEL1]], double 2.550000e+02)
224224
; CHECK-NEXT: ret double [[SEL2]]
225225
;
226-
%cmp1 = fcmp ogt double %x, 1.0
226+
%cmp1 = fcmp nnan ogt double %x, 1.0
227227
%sel1 = select nnan nsz i1 %cmp1, double %x, double 1.0
228-
%cmp2 = fcmp olt double %sel1, 255.0
228+
%cmp2 = fcmp nnan olt double %sel1, 255.0
229229
%sel2 = select nnan nsz i1 %cmp2, double %sel1, double 255.0
230230
ret double %sel2
231231
}

llvm/test/Transforms/InstCombine/fneg.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ define float @test_fneg_select_maxnum(float %x) {
11031103
; CHECK-NEXT: [[NEG:%.*]] = fneg float [[SEL1]]
11041104
; CHECK-NEXT: ret float [[NEG]]
11051105
;
1106-
%cmp1 = fcmp ogt float %x, 1.0
1106+
%cmp1 = fcmp nnan ogt float %x, 1.0
11071107
%sel1 = select nnan nsz i1 %cmp1, float %x, float 1.0
11081108
%neg = fneg float %sel1
11091109
ret float %neg

llvm/test/Transforms/InstCombine/minmax-fp.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ define float @maxnum_ogt_fmf_on_select(float %a, float %b) {
324324
; CHECK-NEXT: [[F:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
325325
; CHECK-NEXT: ret float [[F]]
326326
;
327-
%cond = fcmp ogt float %a, %b
327+
%cond = fcmp nnan ogt float %a, %b
328328
%f = select nnan nsz i1 %cond, float %a, float %b
329329
ret float %f
330330
}
@@ -334,7 +334,7 @@ define <2 x float> @maxnum_oge_fmf_on_select(<2 x float> %a, <2 x float> %b) {
334334
; CHECK-NEXT: [[F:%.*]] = call nnan ninf nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
335335
; CHECK-NEXT: ret <2 x float> [[F]]
336336
;
337-
%cond = fcmp oge <2 x float> %a, %b
337+
%cond = fcmp nnan oge <2 x float> %a, %b
338338
%f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
339339
ret <2 x float> %f
340340
}
@@ -388,7 +388,7 @@ define float @minnum_olt_fmf_on_select(float %a, float %b) {
388388
; CHECK-NEXT: [[F:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
389389
; CHECK-NEXT: ret float [[F]]
390390
;
391-
%cond = fcmp olt float %a, %b
391+
%cond = fcmp nnan olt float %a, %b
392392
%f = select nnan nsz i1 %cond, float %a, float %b
393393
ret float %f
394394
}
@@ -398,7 +398,7 @@ define <2 x float> @minnum_ole_fmf_on_select(<2 x float> %a, <2 x float> %b) {
398398
; CHECK-NEXT: [[F:%.*]] = call nnan ninf nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
399399
; CHECK-NEXT: ret <2 x float> [[F]]
400400
;
401-
%cond = fcmp ole <2 x float> %a, %b
401+
%cond = fcmp nnan ole <2 x float> %a, %b
402402
%f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
403403
ret <2 x float> %f
404404
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ declare void @foo(i1)
113113

114114
define float @select_max_ugt_2_use_cmp(float %a, float %b) {
115115
; CHECK-LABEL: @select_max_ugt_2_use_cmp(
116-
; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ugt float [[A:%.*]], [[B:%.*]]
116+
; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc nnan ugt float [[A:%.*]], [[B:%.*]]
117117
; CHECK-NEXT: call void @foo(i1 [[CMP]])
118118
; CHECK-NEXT: [[SEL:%.*]] = call fast float @llvm.maxnum.f32(float [[A]], float [[B]])
119119
; CHECK-NEXT: ret float [[SEL]]
120120
;
121-
%cmp = fcmp reassoc ugt float %a, %b
121+
%cmp = fcmp nnan reassoc ugt float %a, %b
122122
call void @foo(i1 %cmp)
123123
%sel = select fast i1 %cmp, float %a, float %b
124124
ret float %sel

0 commit comments

Comments
 (0)