-
Notifications
You must be signed in to change notification settings - Fork 12.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[InstCombine] Add an additional nnan constraint for xfrm fcmp + sel => fmax/fmin #117977
base: main
Are you sure you want to change the base?
[InstCombine] Add an additional nnan constraint for xfrm fcmp + sel => fmax/fmin #117977
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Rajat Bajpai (rajatbajpai) ChangesAdd an additional Alive2 with and without the fix: https://alive2.llvm.org/ce/z/Hpo7WX Full diff: https://github.com/llvm/llvm-project/pull/117977.diff 6 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index e5525133e5dbb5..46473af3f99dfc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -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(
diff --git a/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll b/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
index c49aea3e82b562..0019bb1023d565 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 028de1ff8a99fa..24f9fab05f1ae8 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -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
}
diff --git a/llvm/test/Transforms/InstCombine/fneg.ll b/llvm/test/Transforms/InstCombine/fneg.ll
index 9692005edf2b6a..c531ee52842708 100644
--- a/llvm/test/Transforms/InstCombine/fneg.ll
+++ b/llvm/test/Transforms/InstCombine/fneg.ll
@@ -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
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index 1276b7b3e3867d..6625458b575b5c 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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
}
diff --git a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
index b164dd983a8925..9042c3c1fa346d 100644
--- a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
@@ -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
|
@arsenm Could you please review this fix? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like the nnan is required, you just can't always preserve it? https://alive2.llvm.org/ce/z/4Dj45b
Right now we try to preserve it even if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://alive2.llvm.org/ce/z/4PKqnZ
You should drop nnan
in the new maxnum/minnum
instead of blocking this transform.
Ignore me. @nikic already pointed out this. |
Preserve `nnan` constraint only if present on both the instructions: `fcmp` and `select`. Alive2: https://alive2.llvm.org/ce/z/ZNDjzt
fe41e3e
to
36ade16
Compare
Add an additional
nnan
constraint on thefcmp
instruction for thefcmp
+select
=>fmax
/fmin
xfrm. Without thennan
constraint, this transformation is incorrect.Alive2 with and without the fix: https://alive2.llvm.org/ce/z/Hpo7WX