Skip to content

Commit

Permalink
[InstCombine] Add an additional nnan constraint for xfrm fcmp + sel =…
Browse files Browse the repository at this point in the history
…> 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
  • Loading branch information
rajatbajpai committed Nov 28, 2024
1 parent 93f7398 commit fe41e3e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 33 deletions.
5 changes: 4 additions & 1 deletion llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3864,9 +3864,12 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (SIFPOp) {
// TODO: Try to forward-propagate FMF from select arms to the select.

auto *FCmp = dyn_cast<FCmpInst>(CondVal);

// Canonicalize select of FP values where NaN and -0.0 are not valid as
// minnum/maxnum intrinsics.
if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros()) {
if (SIFPOp->hasNoNaNs() && SIFPOp->hasNoSignedZeros() && FCmp &&
FCmp->hasNoNaNs()) {
Value *X, *Y;
if (match(&SI, m_OrdOrUnordFMax(m_Value(X), m_Value(Y))))
return replaceInstUsesWith(
Expand Down
46 changes: 23 additions & 23 deletions llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ define float @test_fcmp_ogt_fadd_select_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, 0.000000e+00
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -23,7 +23,7 @@ define float @test_fcmp_ogt_fadd_select_constant_swapped(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, 0.000000e+00
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
Expand All @@ -36,7 +36,7 @@ define float @test_fcmp_ogt_fadd_select_neg_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, -0.000000e+00
%cmp1 = fcmp nnan ogt float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -49,7 +49,7 @@ define float @test_fcmp_ogt_fadd_select_fastmath_preserve(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, 0.000000e+00
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -62,7 +62,7 @@ define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(<2 x float> %in)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
%cmp1 = fcmp ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%cmp1 = fcmp nnan ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
Expand All @@ -78,7 +78,7 @@ define float @test_fcmp_olt_fadd_select_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp olt float %in, 0.000000e+00
%cmp1 = fcmp nnan olt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -91,7 +91,7 @@ define float @test_fcmp_olt_fadd_select_constant_swapped(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp olt float %in, 0.000000e+00
%cmp1 = fcmp nnan olt float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
Expand All @@ -104,7 +104,7 @@ define float @test_fcmp_olt_fadd_select_neg_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp olt float %in, -0.000000e+00
%cmp1 = fcmp nnan olt float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -117,7 +117,7 @@ define float @test_fcmp_olt_fadd_select_fastmath_preserve(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp olt float %in, 0.000000e+00
%cmp1 = fcmp nnan olt float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -130,7 +130,7 @@ define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(<2 x float> %in)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
%cmp1 = fcmp olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%cmp1 = fcmp nnan olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
Expand All @@ -146,7 +146,7 @@ define float @test_fcmp_oge_fadd_select_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp oge float %in, 0.000000e+00
%cmp1 = fcmp nnan oge float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -159,7 +159,7 @@ define float @test_fcmp_oge_fadd_select_constant_swapped(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp oge float %in, 0.000000e+00
%cmp1 = fcmp nnan oge float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
Expand All @@ -172,7 +172,7 @@ define float @test_fcmp_oge_fadd_select_neg_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp oge float %in, -0.000000e+00
%cmp1 = fcmp nnan oge float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -185,7 +185,7 @@ define float @test_fcmp_oge_fadd_select_fastmath_preserve(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp oge float %in, 0.000000e+00
%cmp1 = fcmp nnan oge float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -198,7 +198,7 @@ define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(<2 x float> %in)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
%cmp1 = fcmp oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%cmp1 = fcmp nnan oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
Expand All @@ -214,7 +214,7 @@ define float @test_fcmp_ole_fadd_select_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ole float %in, 0.000000e+00
%cmp1 = fcmp nnan ole float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -227,7 +227,7 @@ define float @test_fcmp_ole_fadd_select_constant_swapped(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ole float %in, 0.000000e+00
%cmp1 = fcmp nnan ole float %in, 0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
ret float %sel
Expand All @@ -240,7 +240,7 @@ define float @test_fcmp_ole_fadd_select_neg_constant(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ole float %in, -0.000000e+00
%cmp1 = fcmp nnan ole float %in, -0.000000e+00
%add = fadd float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -253,7 +253,7 @@ define float @test_fcmp_ole_fadd_select_fastmath_preserve(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ole float %in, 0.000000e+00
%cmp1 = fcmp nnan ole float %in, 0.000000e+00
%add = fadd nnan float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -266,7 +266,7 @@ define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(<2 x float> %in)
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
; CHECK-NEXT: ret <2 x float> [[ADD_NEW]]
;
%cmp1 = fcmp ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%cmp1 = fcmp nnan ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
%add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
%sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
ret <2 x float> %sel
Expand Down Expand Up @@ -641,7 +641,7 @@ define float @test_fcmp_ogt_fadd_select_rewrite_flags1(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd reassoc nnan nsz arcp contract afn float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, 0.000000e+00
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd reassoc afn arcp contract float %in, 1.000000e+00
%sel = select nnan nsz reassoc afn arcp contract i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -654,7 +654,7 @@ define float @test_fcmp_ogt_fadd_select_rewrite_flags2(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, 0.000000e+00
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd reassoc float %in, 1.000000e+00
%sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand All @@ -667,7 +667,7 @@ define float @test_fcmp_ogt_fadd_select_rewrite_and_fastmath(float %in) {
; CHECK-NEXT: [[ADD_NEW:%.*]] = fadd fast float [[SEL_NEW]], 1.000000e+00
; CHECK-NEXT: ret float [[ADD_NEW]]
;
%cmp1 = fcmp ogt float %in, 0.000000e+00
%cmp1 = fcmp nnan ogt float %in, 0.000000e+00
%add = fadd fast reassoc float %in, 1.000000e+00
%sel = select fast i1 %cmp1, float %add, float 1.000000e+00
ret float %sel
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/InstCombine/fcmp-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@ define double @test_fcmp_select_maxnum(double %x) {
; CHECK-NEXT: [[SEL2:%.*]] = call nnan nsz double @llvm.minnum.f64(double [[SEL1]], double 2.550000e+02)
; CHECK-NEXT: ret double [[SEL2]]
;
%cmp1 = fcmp ogt double %x, 1.0
%cmp1 = fcmp nnan ogt double %x, 1.0
%sel1 = select nnan nsz i1 %cmp1, double %x, double 1.0
%cmp2 = fcmp olt double %sel1, 255.0
%cmp2 = fcmp nnan olt double %sel1, 255.0
%sel2 = select nnan nsz i1 %cmp2, double %sel1, double 255.0
ret double %sel2
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/InstCombine/fneg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ define float @test_fneg_select_maxnum(float %x) {
; CHECK-NEXT: [[NEG:%.*]] = fneg float [[SEL1]]
; CHECK-NEXT: ret float [[NEG]]
;
%cmp1 = fcmp ogt float %x, 1.0
%cmp1 = fcmp nnan ogt float %x, 1.0
%sel1 = select nnan nsz i1 %cmp1, float %x, float 1.0
%neg = fneg float %sel1
ret float %neg
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/Transforms/InstCombine/minmax-fp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ define float @maxnum_ogt_fmf_on_select(float %a, float %b) {
; CHECK-NEXT: [[F:%.*]] = call nnan nsz float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[F]]
;
%cond = fcmp ogt float %a, %b
%cond = fcmp nnan ogt float %a, %b
%f = select nnan nsz i1 %cond, float %a, float %b
ret float %f
}
Expand All @@ -334,7 +334,7 @@ define <2 x float> @maxnum_oge_fmf_on_select(<2 x float> %a, <2 x float> %b) {
; CHECK-NEXT: [[F:%.*]] = call nnan ninf nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
; CHECK-NEXT: ret <2 x float> [[F]]
;
%cond = fcmp oge <2 x float> %a, %b
%cond = fcmp nnan oge <2 x float> %a, %b
%f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
ret <2 x float> %f
}
Expand Down Expand Up @@ -388,7 +388,7 @@ define float @minnum_olt_fmf_on_select(float %a, float %b) {
; CHECK-NEXT: [[F:%.*]] = call nnan nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
; CHECK-NEXT: ret float [[F]]
;
%cond = fcmp olt float %a, %b
%cond = fcmp nnan olt float %a, %b
%f = select nnan nsz i1 %cond, float %a, float %b
ret float %f
}
Expand All @@ -398,7 +398,7 @@ define <2 x float> @minnum_ole_fmf_on_select(<2 x float> %a, <2 x float> %b) {
; CHECK-NEXT: [[F:%.*]] = call nnan ninf nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
; CHECK-NEXT: ret <2 x float> [[F]]
;
%cond = fcmp ole <2 x float> %a, %b
%cond = fcmp nnan ole <2 x float> %a, %b
%f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
ret <2 x float> %f
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ declare void @foo(i1)

define float @select_max_ugt_2_use_cmp(float %a, float %b) {
; CHECK-LABEL: @select_max_ugt_2_use_cmp(
; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc ugt float [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = fcmp reassoc nnan ugt float [[A:%.*]], [[B:%.*]]
; CHECK-NEXT: call void @foo(i1 [[CMP]])
; CHECK-NEXT: [[SEL:%.*]] = call fast float @llvm.maxnum.f32(float [[A]], float [[B]])
; CHECK-NEXT: ret float [[SEL]]
;
%cmp = fcmp reassoc ugt float %a, %b
%cmp = fcmp nnan reassoc ugt float %a, %b
call void @foo(i1 %cmp)
%sel = select fast i1 %cmp, float %a, float %b
ret float %sel
Expand Down

0 comments on commit fe41e3e

Please sign in to comment.