[llvm] [InstCombine] Fix miscompilation for `FCmp` (PR #177872)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 25 11:26:25 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Tirthankar Mazumder (wermos)
<details>
<summary>Changes</summary>
Fixes #<!-- -->177541
This PR fixes the miscompilation reported in #<!-- -->177541 by preventing InstCombine from trying to optimize a clamp-like construct into a min/max canonical form if it requires using a more poisonous intermediate variable.
---
Full diff: https://github.com/llvm/llvm-project/pull/177872.diff
5 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+22-3)
- (modified) llvm/test/Transforms/InstCombine/clamp-to-minmax.ll (+37-19)
- (modified) llvm/test/Transforms/InstCombine/fcmp-select.ll (+4-4)
- (modified) llvm/test/Transforms/InstCombine/minmax-fp.ll (+24-24)
- (modified) llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll (+2-2)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 6ead1fd52403d..79f80042ac4a2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4479,6 +4479,11 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
bool IsCastNeeded = LHS->getType() != SelType;
Value *CmpLHS = cast<CmpInst>(CondVal)->getOperand(0);
Value *CmpRHS = cast<CmpInst>(CondVal)->getOperand(1);
+ // dbgs() << "CmpLHS = " << *CmpLHS << "\nCmpRHS = " << *CmpRHS << "\n";
+ // dbgs() << "SI = " << SI << "\nSI.getCondition() = " <<
+ // *SI.getCondition() << '\n'; dbgs() << "SI.getName() = " << SI.getName()
+ // << "\n"; dbgs() << "LHS = " << *LHS << "\nRHS = " << *RHS << '\n';
+ // dbgs() << "CmpLHS = " << *CmpLHS << "\nCmpRHS = " << *CmpRHS << '\n';
if (IsCastNeeded ||
(LHS->getType()->isFPOrFPVectorTy() &&
((CmpLHS != LHS && CmpLHS != RHS) ||
@@ -4486,13 +4491,27 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
CmpInst::Predicate MinMaxPred = getMinMaxPred(SPF, SPR.Ordered);
Value *Cmp;
- if (CmpInst::isIntPredicate(MinMaxPred))
+ Value *NewSI;
+ if (CmpInst::isIntPredicate(MinMaxPred)) {
Cmp = Builder.CreateICmp(MinMaxPred, LHS, RHS);
- else
+ NewSI = Builder.CreateSelect(Cmp, LHS, RHS, SI.getName(), &SI);
+ } else {
+ if (!isGuaranteedNotToBePoison(LHS) ||
+ !isGuaranteedNotToBePoison(RHS))
+ return nullptr;
+
+ // dbgs() << "Got here... somehow\n";
Cmp = Builder.CreateFCmpFMF(MinMaxPred, LHS, RHS,
cast<Instruction>(SI.getCondition()));
- Value *NewSI = Builder.CreateSelect(Cmp, LHS, RHS, SI.getName(), &SI);
+ // Preserve existing select FMF if it already had any.
+ if (SI.hasNoNaNs() || SI.hasNoInfs())
+ NewSI =
+ Builder.CreateSelectFMF(Cmp, LHS, RHS, SI.getFastMathFlags());
+ else
+ NewSI = Builder.CreateSelect(Cmp, LHS, RHS, SI.getName(), &SI);
+ }
+
if (!IsCastNeeded)
return replaceInstUsesWith(SI, NewSI);
diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
index 0ccaa9c393654..33a1884bd77a4 100644
--- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
+++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
@@ -7,8 +7,8 @@ define float @clamp_float_fast_ordered_strict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_strict_maxmin(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
-; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast olt float [[X]], 1.000000e+00
+; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast olt float %x, 255.0
@@ -23,8 +23,8 @@ define float @clamp_float_fast_ordered_nonstrict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_maxmin(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast olt float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], float [[X]], float 2.550000e+02
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
-; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ole float [[X]], 1.000000e+00
+; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast olt float %x, 255.0
@@ -39,8 +39,8 @@ define float @clamp_float_fast_ordered_strict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_strict_minmax(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
-; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ogt float [[X]], 2.550000e+02
+; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast ogt float %x, 1.0
@@ -55,8 +55,8 @@ define float @clamp_float_fast_ordered_nonstrict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_ordered_nonstrict_minmax(
; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ogt float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], float [[X]], float 1.000000e+00
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
-; CHECK-NEXT: [[R1:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast oge float [[X]], 2.550000e+02
+; CHECK-NEXT: [[R1:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R1]]
;
%cmp2 = fcmp fast ogt float %x, 1.0
@@ -74,8 +74,8 @@ define float @clamp_float_fast_unordered_strict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_strict_maxmin(
; CHECK-NEXT: [[CMP2_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select nnan ninf i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
-; CHECK-NEXT: [[R:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ult float [[X]], 1.000000e+00
+; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
;
%cmp2 = fcmp fast ult float %x, 255.0
@@ -90,8 +90,8 @@ define float @clamp_float_fast_unordered_nonstrict_maxmin(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_nonstrict_maxmin(
; CHECK-NEXT: [[CMP2_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[MIN:%.*]] = select nnan ninf i1 [[CMP2_INV]], float 2.550000e+02, float [[X]]
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast oge float [[MIN]], 1.000000e+00
-; CHECK-NEXT: [[R:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MIN]], float 1.000000e+00
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ule float [[X]], 1.000000e+00
+; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
;
%cmp2 = fcmp fast ult float %x, 255.0
@@ -106,8 +106,8 @@ define float @clamp_float_fast_unordered_strict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_strict_minmax(
; CHECK-NEXT: [[CMP2_INV:%.*]] = fcmp fast ole float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select nnan ninf i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
-; CHECK-NEXT: [[R:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast ugt float [[X]], 2.550000e+02
+; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
;
%cmp2 = fcmp fast ugt float %x, 1.0
@@ -122,8 +122,8 @@ define float @clamp_float_fast_unordered_nonstrict_minmax(float %x) {
; CHECK-LABEL: @clamp_float_fast_unordered_nonstrict_minmax(
; CHECK-NEXT: [[CMP2_INV:%.*]] = fcmp fast ole float [[X:%.*]], 1.000000e+00
; CHECK-NEXT: [[MAX:%.*]] = select nnan ninf i1 [[CMP2_INV]], float 1.000000e+00, float [[X]]
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp fast ole float [[MAX]], 2.550000e+02
-; CHECK-NEXT: [[R:%.*]] = select nnan ninf i1 [[DOTINV]], float [[MAX]], float 2.550000e+02
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp fast uge float [[X]], 2.550000e+02
+; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], float 2.550000e+02, float [[MAX]]
; CHECK-NEXT: ret float [[R]]
;
%cmp2 = fcmp fast ugt float %x, 1.0
@@ -140,8 +140,8 @@ define float @clamp_test_1(float %x) {
; CHECK-LABEL: @clamp_test_1(
; CHECK-NEXT: [[INNER_CMP_INV:%.*]] = fcmp fast oge float [[X:%.*]], 2.550000e+02
; CHECK-NEXT: [[INNER_SEL:%.*]] = select nnan ninf i1 [[INNER_CMP_INV]], float 2.550000e+02, float [[X]]
-; CHECK-NEXT: [[OUTER_CMP:%.*]] = fcmp fast oge float [[INNER_SEL]], 1.000000e+00
-; CHECK-NEXT: [[R:%.*]] = select nnan ninf i1 [[OUTER_CMP]], float [[INNER_SEL]], float 1.000000e+00
+; CHECK-NEXT: [[OUTER_CMP:%.*]] = fcmp fast ugt float [[X]], 1.000000e+00
+; CHECK-NEXT: [[R:%.*]] = select i1 [[OUTER_CMP]], float [[INNER_SEL]], float 1.000000e+00
; CHECK-NEXT: ret float [[R]]
;
%inner_cmp = fcmp fast ult float %x, 255.0
@@ -574,7 +574,6 @@ define i32 @mixed_clamp_to_i32_2(float %x) {
ret i32 %r
}
-
define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) {
; CHECK-LABEL: @mixed_clamp_to_float_vec(
; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN:%.*]], <2 x i32> splat (i32 1))
@@ -590,3 +589,22 @@ define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) {
%r = select <2 x i1> %lo_cmp, <2 x float> <float 1.0, float 1.0>, <2 x float> %f_min
ret <2 x float> %r
}
+
+; The min/max clamp code should NOT fire here because doing so results
+; in a form that is more poisonous than the original.
+define float @clamp_select_with_poison(float %x) {
+; CHECK-LABEL: @clamp_select_with_poison(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[A_INV:%.*]] = fcmp nnan ninf oge float [[X:%.*]], 2.550000e+02
+; CHECK-NEXT: [[B:%.*]] = select nnan ninf i1 [[A_INV]], float [[X]], float 2.550000e+02
+; CHECK-NEXT: [[C:%.*]] = fcmp nnan ugt float [[X]], 5.120000e+02
+; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], float 5.120000e+02, float [[B]]
+; CHECK-NEXT: ret float [[R]]
+;
+entry:
+ %a = fcmp nnan ninf ult float %x, 255.0
+ %b = select i1 %a, float 255.0, float %x
+ %c = fcmp nnan ugt float %x, 512.0
+ %r = select i1 %c, float 512.0, float %b
+ ret float %r
+}
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index bb41f18c74f5f..21430e21d994d 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: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
+; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select nnan nsz i1 [[CMP]], float [[X]], float -0.000000e+00
; CHECK-NEXT: ret float [[SEL1]]
;
%cmp = fcmp olt float %x, 0.000000e+00
@@ -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: [[DOTINV:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ult float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select nnan nsz i1 [[CMP]], float [[X]], float -0.000000e+00
; CHECK-NEXT: ret float [[SEL1]]
;
%cmp = fcmp ult float %x, 0.000000e+00
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index b0af1c7b89838..ced31fa563eb0 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -18,10 +18,10 @@ define double @t1(float %a) {
; Check this is converted into canonical form, as above.
define double @t2(float %a) {
; CHECK-LABEL: @t2(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 5.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float 5.000000e+00, float [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp ult float [[TMP1:%.*]], 5.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[TMP1]] to double
-; CHECK-NEXT: ret double [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], double [[TMP2]], double 5.000000e+00
+; CHECK-NEXT: ret double [[TMP3]]
;
%1 = fcmp ult float %a, 5.0
%2 = fpext float %a to double
@@ -32,10 +32,10 @@ define double @t2(float %a) {
; Same again, with trunc.
define float @t4(double %a) {
; CHECK-LABEL: @t4(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge double [[A:%.*]], 5.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], double 5.000000e+00, double [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp ult double [[TMP1:%.*]], 5.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fptrunc double [[TMP1]] to float
-; CHECK-NEXT: ret float [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], float [[TMP2]], float 5.000000e+00
+; CHECK-NEXT: ret float [[TMP3]]
;
%1 = fcmp ult double %a, 5.0
%2 = fptrunc double %a to float
@@ -75,10 +75,10 @@ define float @not_maxnum(float %x) {
define double @t6(float %a) {
; CHECK-LABEL: @t6(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp ult float [[TMP1:%.*]], 0.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fpext float [[TMP1]] to double
-; CHECK-NEXT: ret double [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], double [[TMP2]], double 0.000000e+00
+; CHECK-NEXT: ret double [[TMP3]]
;
%1 = fcmp ult float %a, -0.0
%2 = fpext float %a to double
@@ -133,10 +133,10 @@ define float @fmax_fmax_zero_mismatch(float noundef %x) {
define i64 @t8(float %a) {
; CHECK-LABEL: @t8(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 5.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float 5.000000e+00, float [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp ult float [[TMP1:%.*]], 5.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fptoui float [[TMP1]] to i64
-; CHECK-NEXT: ret i64 [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], i64 [[TMP2]], i64 5
+; CHECK-NEXT: ret i64 [[TMP3]]
;
%1 = fcmp ult float %a, 5.0
%2 = fptoui float %a to i64
@@ -146,10 +146,10 @@ define i64 @t8(float %a) {
define i8 @t9(float %a) {
; CHECK-LABEL: @t9(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp ult float [[TMP1:%.*]], 0.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
-; CHECK-NEXT: ret i8 [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], i8 [[TMP2]], i8 0
+; CHECK-NEXT: ret i8 [[TMP3]]
;
%1 = fcmp ult float %a, 0.0
%2 = fptosi float %a to i8
@@ -202,10 +202,10 @@ define i8 @t13(float %a) {
; %a could be -0.0, but it doesn't matter because the conversion to int is the same for 0.0 or -0.0.
define i8 @t14(float %a) {
; CHECK-LABEL: @t14(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp ule float [[TMP1:%.*]], 0.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
-; CHECK-NEXT: ret i8 [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], i8 [[TMP2]], i8 0
+; CHECK-NEXT: ret i8 [[TMP3]]
;
%1 = fcmp ule float %a, 0.0
%2 = fptosi float %a to i8
@@ -215,10 +215,10 @@ define i8 @t14(float %a) {
define i8 @t14_commute(float %a) {
; CHECK-LABEL: @t14_commute(
-; CHECK-NEXT: [[TMP1:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
-; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], float [[A]], float 0.000000e+00
+; CHECK-NEXT: [[TMP1:%.*]] = fcmp ule float [[TMP2:%.*]], 0.000000e+00
; CHECK-NEXT: [[TMP3:%.*]] = fptosi float [[TMP2]] to i8
-; CHECK-NEXT: ret i8 [[TMP3]]
+; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i8 0, i8 [[TMP3]]
+; CHECK-NEXT: ret i8 [[TMP4]]
;
%1 = fcmp ule float %a, 0.0
%2 = fptosi float %a to i8
@@ -228,10 +228,10 @@ define i8 @t14_commute(float %a) {
define i8 @t15(float %a) {
; CHECK-LABEL: @t15(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00
-; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
+; CHECK-NEXT: [[TMP4:%.*]] = fcmp nsz ule float [[TMP1:%.*]], 0.000000e+00
; CHECK-NEXT: [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
-; CHECK-NEXT: ret i8 [[TMP2]]
+; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP4]], i8 [[TMP2]], i8 0
+; CHECK-NEXT: ret i8 [[TMP3]]
;
%1 = fcmp nsz ule float %a, 0.0
%2 = fptosi float %a to i8
diff --git a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
index ad86f2ed2fa59..24b41aa998ef0 100644
--- a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
@@ -152,8 +152,8 @@ define float @pr141017(float %x) {
define float @pr141017_select_nsz(float %x) {
; CHECK-LABEL: @pr141017_select_nsz(
-; CHECK-NEXT: [[DOTINV:%.*]] = fcmp ole float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[X]]
+; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
+; CHECK-NEXT: [[SEL1:%.*]] = select nsz i1 [[CMP]], float -0.000000e+00, float [[X]]
; CHECK-NEXT: ret float [[SEL1]]
;
%cmp = fcmp olt float %x, 0.0
``````````
</details>
https://github.com/llvm/llvm-project/pull/177872
More information about the llvm-commits
mailing list