[llvm] [ValueTracking] Update `Ordered` when both operands are non-NaN. (PR #143349)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 8 23:30:19 PDT 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/143349
>From 23aebb7c81ac0591a6ec8d3ab928df4c55061886 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 13:48:12 +0800
Subject: [PATCH 1/5] [InstCombine] Add pre-commit tests. NFC.
---
.../Transforms/InstCombine/fcmp-select.ll | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 053b233cb5f04..705afee255d18 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -270,12 +270,25 @@ define i1 @test_fcmp_select_var_const_unordered(double %x, double %y) {
}
define i1 @test_fcmp_ord_select_fcmp_oeq_var_const(double %x) {
-; CHECK-LABEL: @test_fcmp_ord_select_fcmp_oeq_var_const(
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[X:%.*]], 1.000000e+00
-; CHECK-NEXT: ret i1 [[CMP1]]
+; CHECK-LABEL: @test_fcmp_ord_select_fcmp_oeq_var_const(
+; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq double [[X:%.*]], 1.000000e+00
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%cmp1 = fcmp ord double %x, 0.000000e+00
%sel = select i1 %cmp1, double %x, double 0.000000e+00
%cmp2 = fcmp oeq double %sel, 1.000000e+00
ret i1 %cmp2
}
+
+; Make sure that we recognize the SPF correctly.
+
+define float @test_select_nnan_nsz_fcmp_olt(float %x) {
+; CHECK-LABEL: @test_select_nnan_nsz_fcmp_olt(
+; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[X]]
+; CHECK-NEXT: ret float [[SEL1]]
+;
+ %cmp = fcmp olt float %x, 0.000000e+00
+ %sel = select nnan nsz i1 %cmp, float %x, float -0.000000e+00
+ ret float %sel
+}
>From ef884b52ec771248a26a82b0284bfb2dea928cdf Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 13:49:32 +0800
Subject: [PATCH 2/5] [ValueTracking] Set Ordered to true when both operands
are non-NaN.
---
llvm/lib/Analysis/ValueTracking.cpp | 2 ++
llvm/test/Transforms/InstCombine/fcmp-select.ll | 4 ++--
llvm/unittests/Analysis/ValueTrackingTest.cpp | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d6bb852e208f9..e65e34cda95ac 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8660,6 +8660,8 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
if (LHSSafe && RHSSafe) {
// Both operands are known non-NaN.
NaNBehavior = SPNB_RETURNS_ANY;
+ // It is always safe to convert the comparison to an ordered one.
+ Ordered = true;
} else if (CmpInst::isOrdered(Pred)) {
// An ordered comparison will return false when given a NaN, so it
// returns the RHS.
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 705afee255d18..9434f6da0b9b3 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -284,8 +284,8 @@ define i1 @test_fcmp_ord_select_fcmp_oeq_var_const(double %x) {
define float @test_select_nnan_nsz_fcmp_olt(float %x) {
; CHECK-LABEL: @test_select_nnan_nsz_fcmp_olt(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[X]]
+; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
; CHECK-NEXT: ret float [[SEL1]]
;
%cmp = fcmp olt float %x, 0.000000e+00
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index e23005b60891d..faf72bb17880b 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -187,7 +187,7 @@ TEST_F(MatchSelectPatternTest, FastFMin) {
" %A = select i1 %1, float %a, float 5.0\n"
" ret float %A\n"
"}\n");
- expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
+ expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, true});
}
TEST_F(MatchSelectPatternTest, FMinConstantZero) {
>From fd2ef5b024b45026de36ea3fe5535370993448ec Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 14:17:24 +0800
Subject: [PATCH 3/5] [InstCombine] Add regressions tests. NFC.
---
llvm/test/Transforms/InstCombine/fcmp-select.ll | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 9434f6da0b9b3..6f7a5d094b687 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -292,3 +292,14 @@ define float @test_select_nnan_nsz_fcmp_olt(float %x) {
%sel = select nnan nsz i1 %cmp, float %x, float -0.000000e+00
ret float %sel
}
+
+define float @test_select_nnan_nsz_fcmp_ult(float %x) {
+; CHECK-LABEL: @test_select_nnan_nsz_fcmp_ult(
+; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
+; CHECK-NEXT: ret float [[SEL1]]
+;
+ %cmp = fcmp ult float %x, 0.000000e+00
+ %sel = select nnan nsz i1 %cmp, float %x, float -0.000000e+00
+ ret float %sel
+}
>From de90b0a140a511becbd90fa2c1c5c660d717cb75 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 14:19:25 +0800
Subject: [PATCH 4/5] [VakueTracking] Fix miscompilation
---
llvm/lib/Analysis/ValueTracking.cpp | 3 +--
llvm/test/Transforms/InstCombine/fcmp-select.ll | 4 ++--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e65e34cda95ac..d8c1096049dce 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8660,8 +8660,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
if (LHSSafe && RHSSafe) {
// Both operands are known non-NaN.
NaNBehavior = SPNB_RETURNS_ANY;
- // It is always safe to convert the comparison to an ordered one.
- Ordered = true;
+ Ordered = CmpInst::isOrdered(Pred);
} else if (CmpInst::isOrdered(Pred)) {
// An ordered comparison will return false when given a NaN, so it
// returns the RHS.
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 6f7a5d094b687..b622c8636eccb 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -295,8 +295,8 @@ define float @test_select_nnan_nsz_fcmp_olt(float %x) {
define float @test_select_nnan_nsz_fcmp_ult(float %x) {
; CHECK-LABEL: @test_select_nnan_nsz_fcmp_ult(
-; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
+; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[X]]
; CHECK-NEXT: ret float [[SEL1]]
;
%cmp = fcmp ult float %x, 0.000000e+00
>From 68cd11b238514ccdbd46d741e0759c312cff052e Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 9 Jun 2025 14:20:47 +0800
Subject: [PATCH 5/5] [ValueTracking] Add unit tests. NFC.
---
llvm/unittests/Analysis/ValueTrackingTest.cpp | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index faf72bb17880b..6031898f7f679 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -190,6 +190,15 @@ TEST_F(MatchSelectPatternTest, FastFMin) {
expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, true});
}
+TEST_F(MatchSelectPatternTest, FastFMinUnordered) {
+ parseAssembly("define float @test(float %a) {\n"
+ " %1 = fcmp nnan ult float %a, 5.0\n"
+ " %A = select i1 %1, float %a, float 5.0\n"
+ " ret float %A\n"
+ "}\n");
+ expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
+}
+
TEST_F(MatchSelectPatternTest, FMinConstantZero) {
parseAssembly(
"define float @test(float %a) {\n"
More information about the llvm-commits
mailing list