[llvm] [InstCombine] Fix miscompilation for `select` + `FCmp` (PR #177872)

Tirthankar Mazumder via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 25 23:05:24 PST 2026


https://github.com/wermos updated https://github.com/llvm/llvm-project/pull/177872

>From 8fce9711db26acaf58e2ae09baa4e4ea8ea4d5d6 Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Mon, 26 Jan 2026 00:31:57 +0530
Subject: [PATCH 1/3] Pre-commit test

---
 .../Transforms/InstCombine/clamp-to-minmax.ll | 24 ++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
index 0ccaa9c393654..2b0b16cf0c199 100644
--- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
+++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
@@ -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:    [[DOTINV:%.*]] = fcmp fast oge float [[INNER_SEL]], 1.000000e+00
+; CHECK-NEXT:    [[R:%.*]] = select nnan ninf i1 [[DOTINV]], 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:    [[DOTINV:%.*]] = fcmp nnan ole float [[B]], 5.120000e+02
+; CHECK-NEXT:    [[R:%.*]] = select nnan i1 [[DOTINV]], float [[B]], float 5.120000e+02
+; 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
+}

>From c9bb45fb0f2a74322ab4eb9865e6ef13fae2aa5f Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Mon, 26 Jan 2026 00:33:01 +0530
Subject: [PATCH 2/3] Don't fold `FCmp` if one of the operands might be poison.

---
 .../Transforms/InstCombine/InstCombineSelect.cpp   | 14 +++++++++++---
 .../test/Transforms/InstCombine/clamp-to-minmax.ll |  4 ++--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 00f4118d538d8..172b9574577db 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4510,13 +4510,21 @@ 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;
+
           Cmp = Builder.CreateFCmpFMF(MinMaxPred, LHS, RHS,
                                       cast<Instruction>(SI.getCondition()));
 
-        Value *NewSI = Builder.CreateSelect(Cmp, LHS, RHS, SI.getName(), &SI);
+          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 2b0b16cf0c199..a6f8020db8a00 100644
--- a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
+++ b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
@@ -597,8 +597,8 @@ define float @clamp_select_with_poison(float %x) {
 ; 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:    [[DOTINV:%.*]] = fcmp nnan ole float [[B]], 5.120000e+02
-; CHECK-NEXT:    [[R:%.*]] = select nnan i1 [[DOTINV]], float [[B]], float 5.120000e+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:

>From 91684d5fb208f026c1055e6f8cea438c7648e510 Mon Sep 17 00:00:00 2001
From: Tirthankar Mazumder <tmazumder.github at gmail.com>
Date: Mon, 26 Jan 2026 00:46:15 +0530
Subject: [PATCH 3/3] Commit changes in other tests

---
 .../Transforms/InstCombine/clamp-to-minmax.ll | 36 +++++++-------
 .../Transforms/InstCombine/fcmp-select.ll     |  8 ++--
 llvm/test/Transforms/InstCombine/minmax-fp.ll | 48 +++++++++----------
 .../InstCombine/unordered-fcmp-select.ll      |  4 +-
 4 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
index a6f8020db8a00..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:    [[DOTINV:%.*]] = fcmp fast oge float [[INNER_SEL]], 1.000000e+00
-; CHECK-NEXT:    [[R:%.*]] = select nnan ninf i1 [[DOTINV]], 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
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 268cd4675c6cc..aed40ee1aa40f 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 15fc42f4bc97a..4707e448a94e6 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 8afcaa1c1a822..2fe52e05b85ba 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



More information about the llvm-commits mailing list