[llvm] [ValueTracking] Fix signed zero handling in minnum/maxnum matching (PR #210077)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 16 07:58:54 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-nvptx
Author: Nikita Popov (nikic)
<details>
<summary>Changes</summary>
The SPF float min/max matching skipped the check that either the select is nsz or one of the ops non-zero in the case where the zero used in the fcmp and select is the same one. This does not make any sense, because which zero is used in the fcmp is just completely irrelevant.
This leads to miscompiles where the SPF pattern is lowered to hardware minnum/maxnum operations. These have ordered zero, rather than picking whichever zero is specified in the select. It can still be accidentally correct if the zero happens to be the right one for min/max.
I believe the current assumption is that SPF only matches in cases where signed zero behavior does not matter. An alternative way to fix this would be to match the specific zero that's required to match ordered zero semantics. Though I'd rather we match that in DAGCombine, not the SPF based SDAGBuilder code.
Fixes https://github.com/llvm/llvm-project/issues/93414.
---
Full diff: https://github.com/llvm/llvm-project/pull/210077.diff
8 Files Affected:
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+3-16)
- (modified) llvm/test/CodeGen/AArch64/arm64-fmax.ll (+6-3)
- (modified) llvm/test/CodeGen/NVPTX/fma-relu-contract.ll (+22-10)
- (modified) llvm/test/CodeGen/NVPTX/masked-load-3xhalf.ll (+44-34)
- (modified) llvm/test/Transforms/InstCombine/fcmp-select.ll (+3-3)
- (modified) llvm/test/Transforms/InstCombine/minmax-fp.ll (+3-3)
- (modified) llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll (+2-2)
- (modified) llvm/test/Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll (+2-2)
``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index efc14f9a639da..feba17a7a6a7e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8989,7 +8989,6 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
Value *TrueVal, Value *FalseVal,
Value *&LHS, Value *&RHS,
unsigned Depth) {
- bool HasMismatchedZeros = false;
if (CmpInst::isFPPredicate(Pred)) {
// IEEE-754 ignores the sign of 0.0 in comparisons. So if the select has one
// 0.0 operand, set the compare's 0.0 operands to that same value for the
@@ -9004,14 +9003,10 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
OutputZeroVal = FalseVal;
if (OutputZeroVal) {
- if (match(CmpLHS, m_AnyZeroFP()) && CmpLHS != OutputZeroVal) {
- HasMismatchedZeros = true;
+ if (match(CmpLHS, m_AnyZeroFP()) && CmpLHS != OutputZeroVal)
CmpLHS = OutputZeroVal;
- }
- if (match(CmpRHS, m_AnyZeroFP()) && CmpRHS != OutputZeroVal) {
- HasMismatchedZeros = true;
+ if (match(CmpRHS, m_AnyZeroFP()) && CmpRHS != OutputZeroVal)
CmpRHS = OutputZeroVal;
- }
}
}
@@ -9023,15 +9018,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
// minNum(0.0, -0.0) // May return -0.0 or 0.0 (IEEE 754-2008 5.3.1)
// Therefore, we behave conservatively and only proceed if at least one of the
// operands is known to not be zero or if we don't care about signed zero.
- switch (Pred) {
- default: break;
- case CmpInst::FCMP_OGT: case CmpInst::FCMP_OLT:
- case CmpInst::FCMP_UGT: case CmpInst::FCMP_ULT:
- if (!HasMismatchedZeros)
- break;
- [[fallthrough]];
- case CmpInst::FCMP_OGE: case CmpInst::FCMP_OLE:
- case CmpInst::FCMP_UGE: case CmpInst::FCMP_ULE:
+ if (CmpInst::isFPPredicate(Pred)) {
if (!FMF.noSignedZeros() && !isKnownNonZero(CmpLHS) &&
!isKnownNonZero(CmpRHS))
return {SPF_UNKNOWN, SPNB_NA, false};
diff --git a/llvm/test/CodeGen/AArch64/arm64-fmax.ll b/llvm/test/CodeGen/AArch64/arm64-fmax.ll
index f311139e193a5..ff1f60cfe8bbc 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fmax.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fmax.ll
@@ -5,7 +5,8 @@ define double @test_direct(float %in) {
; CHECK-LABEL: test_direct:
; CHECK: // %bb.0:
; CHECK-NEXT: movi d1, #0000000000000000
-; CHECK-NEXT: fmaxnm s0, s0, s1
+; CHECK-NEXT: fcmp s0, #0.0
+; CHECK-NEXT: fcsel s0, s1, s0, lt
; CHECK-NEXT: fcvt d0, s0
; CHECK-NEXT: ret
%cmp = fcmp nnan olt float %in, 0.000000e+00
@@ -18,7 +19,8 @@ define double @test_cross(float %in) {
; CHECK-LABEL: test_cross:
; CHECK: // %bb.0:
; CHECK-NEXT: movi d1, #0000000000000000
-; CHECK-NEXT: fminnm s0, s0, s1
+; CHECK-NEXT: fcmp s0, #0.0
+; CHECK-NEXT: fcsel s0, s0, s1, lt
; CHECK-NEXT: fcvt d0, s0
; CHECK-NEXT: ret
%cmp = fcmp nnan ult float %in, 0.000000e+00
@@ -33,7 +35,8 @@ define double @test_cross_fail_nan(float %in) {
; CHECK-LABEL: test_cross_fail_nan:
; CHECK: // %bb.0:
; CHECK-NEXT: movi d1, #0000000000000000
-; CHECK-NEXT: fminnm s0, s0, s1
+; CHECK-NEXT: fcmp s0, #0.0
+; CHECK-NEXT: fcsel s0, s0, s1, lt
; CHECK-NEXT: fcvt d0, s0
; CHECK-NEXT: ret
%cmp = fcmp nnan olt float %in, 0.000000e+00
diff --git a/llvm/test/CodeGen/NVPTX/fma-relu-contract.ll b/llvm/test/CodeGen/NVPTX/fma-relu-contract.ll
index 275938c830a60..dfcbe2118a604 100644
--- a/llvm/test/CodeGen/NVPTX/fma-relu-contract.ll
+++ b/llvm/test/CodeGen/NVPTX/fma-relu-contract.ll
@@ -122,6 +122,7 @@ define half @fma_f16_expanded_no_nans_multiple_uses_of_fma(half %a, half %b, hal
define half @fma_f16_expanded_unsafe_with_nans(half %a, half %b, half %c) {
; CHECK-LABEL: fma_f16_expanded_unsafe_with_nans(
; CHECK: {
+; CHECK-NEXT: .reg .pred %p<2>;
; CHECK-NEXT: .reg .b16 %rs<7>;
; CHECK-EMPTY:
; CHECK-NEXT: // %bb.0:
@@ -130,12 +131,14 @@ define half @fma_f16_expanded_unsafe_with_nans(half %a, half %b, half %c) {
; CHECK-NEXT: ld.param.b16 %rs3, [fma_f16_expanded_unsafe_with_nans_param_2];
; CHECK-NEXT: fma.rn.f16 %rs4, %rs1, %rs2, %rs3;
; CHECK-NEXT: mov.b16 %rs5, 0x0000;
-; CHECK-NEXT: max.f16 %rs6, %rs4, %rs5;
+; CHECK-NEXT: setp.gt.f16 %p1, %rs4, %rs5;
+; CHECK-NEXT: selp.b16 %rs6, %rs4, 0x0000, %p1;
; CHECK-NEXT: st.param.b16 [func_retval0], %rs6;
; CHECK-NEXT: ret;
;
; CHECK-FTZ-LABEL: fma_f16_expanded_unsafe_with_nans(
; CHECK-FTZ: {
+; CHECK-FTZ-NEXT: .reg .pred %p<2>;
; CHECK-FTZ-NEXT: .reg .b16 %rs<7>;
; CHECK-FTZ-EMPTY:
; CHECK-FTZ-NEXT: // %bb.0:
@@ -144,7 +147,8 @@ define half @fma_f16_expanded_unsafe_with_nans(half %a, half %b, half %c) {
; CHECK-FTZ-NEXT: ld.param.b16 %rs3, [fma_f16_expanded_unsafe_with_nans_param_2];
; CHECK-FTZ-NEXT: fma.rn.ftz.f16 %rs4, %rs1, %rs2, %rs3;
; CHECK-FTZ-NEXT: mov.b16 %rs5, 0x0000;
-; CHECK-FTZ-NEXT: max.ftz.f16 %rs6, %rs4, %rs5;
+; CHECK-FTZ-NEXT: setp.gt.ftz.f16 %p1, %rs4, %rs5;
+; CHECK-FTZ-NEXT: selp.b16 %rs6, %rs4, 0x0000, %p1;
; CHECK-FTZ-NEXT: st.param.b16 [func_retval0], %rs6;
; CHECK-FTZ-NEXT: ret;
;
@@ -219,30 +223,38 @@ define half @fma_f16_expanded_maxnum_no_nans(half %a, half %b, half %c) {
define bfloat @fma_bf16_expanded_unsafe_with_nans(bfloat %a, bfloat %b, bfloat %c) {
; CHECK-LABEL: fma_bf16_expanded_unsafe_with_nans(
; CHECK: {
-; CHECK-NEXT: .reg .b16 %rs<7>;
+; CHECK-NEXT: .reg .pred %p<2>;
+; CHECK-NEXT: .reg .b16 %rs<6>;
+; CHECK-NEXT: .reg .b32 %r<3>;
; CHECK-EMPTY:
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: ld.param.b16 %rs1, [fma_bf16_expanded_unsafe_with_nans_param_0];
; CHECK-NEXT: ld.param.b16 %rs2, [fma_bf16_expanded_unsafe_with_nans_param_1];
; CHECK-NEXT: ld.param.b16 %rs3, [fma_bf16_expanded_unsafe_with_nans_param_2];
; CHECK-NEXT: fma.rn.bf16 %rs4, %rs1, %rs2, %rs3;
-; CHECK-NEXT: mov.b16 %rs5, 0x0000;
-; CHECK-NEXT: max.bf16 %rs6, %rs4, %rs5;
-; CHECK-NEXT: st.param.b16 [func_retval0], %rs6;
+; CHECK-NEXT: cvt.u32.u16 %r1, %rs4;
+; CHECK-NEXT: shl.b32 %r2, %r1, 16;
+; CHECK-NEXT: setp.gt.f32 %p1, %r2, 0f00000000;
+; CHECK-NEXT: selp.b16 %rs5, %rs4, 0x0000, %p1;
+; CHECK-NEXT: st.param.b16 [func_retval0], %rs5;
; CHECK-NEXT: ret;
;
; CHECK-FTZ-LABEL: fma_bf16_expanded_unsafe_with_nans(
; CHECK-FTZ: {
-; CHECK-FTZ-NEXT: .reg .b16 %rs<7>;
+; CHECK-FTZ-NEXT: .reg .pred %p<2>;
+; CHECK-FTZ-NEXT: .reg .b16 %rs<6>;
+; CHECK-FTZ-NEXT: .reg .b32 %r<3>;
; CHECK-FTZ-EMPTY:
; CHECK-FTZ-NEXT: // %bb.0:
; CHECK-FTZ-NEXT: ld.param.b16 %rs1, [fma_bf16_expanded_unsafe_with_nans_param_0];
; CHECK-FTZ-NEXT: ld.param.b16 %rs2, [fma_bf16_expanded_unsafe_with_nans_param_1];
; CHECK-FTZ-NEXT: ld.param.b16 %rs3, [fma_bf16_expanded_unsafe_with_nans_param_2];
; CHECK-FTZ-NEXT: fma.rn.bf16 %rs4, %rs1, %rs2, %rs3;
-; CHECK-FTZ-NEXT: mov.b16 %rs5, 0x0000;
-; CHECK-FTZ-NEXT: max.bf16 %rs6, %rs4, %rs5;
-; CHECK-FTZ-NEXT: st.param.b16 [func_retval0], %rs6;
+; CHECK-FTZ-NEXT: cvt.u32.u16 %r1, %rs4;
+; CHECK-FTZ-NEXT: shl.b32 %r2, %r1, 16;
+; CHECK-FTZ-NEXT: setp.gt.ftz.f32 %p1, %r2, 0f00000000;
+; CHECK-FTZ-NEXT: selp.b16 %rs5, %rs4, 0x0000, %p1;
+; CHECK-FTZ-NEXT: st.param.b16 [func_retval0], %rs5;
; CHECK-FTZ-NEXT: ret;
;
; CHECK-SM70-LABEL: fma_bf16_expanded_unsafe_with_nans(
diff --git a/llvm/test/CodeGen/NVPTX/masked-load-3xhalf.ll b/llvm/test/CodeGen/NVPTX/masked-load-3xhalf.ll
index bba240c694040..8f150e29d95b5 100644
--- a/llvm/test/CodeGen/NVPTX/masked-load-3xhalf.ll
+++ b/llvm/test/CodeGen/NVPTX/masked-load-3xhalf.ll
@@ -7,8 +7,9 @@
define void @halfx3_extend_chain(ptr align 16 captures(none) %rd0) {
; CHECK-LABEL: halfx3_extend_chain(
; CHECK: {
-; CHECK-NEXT: .reg .b16 %rs<7>;
-; CHECK-NEXT: .reg .b32 %r<12>;
+; CHECK-NEXT: .reg .pred %p<7>;
+; CHECK-NEXT: .reg .b16 %rs<14>;
+; CHECK-NEXT: .reg .b32 %r<5>;
; CHECK-NEXT: .reg .b64 %rd<2>;
; CHECK-EMPTY:
; CHECK-NEXT: // %bb.0:
@@ -16,20 +17,25 @@ define void @halfx3_extend_chain(ptr align 16 captures(none) %rd0) {
; CHECK-NEXT: .pragma "used_bytes_mask 0xfff";
; CHECK-NEXT: ld.v4.b32 {%r1, %r2, %r3, %r4}, [%rd1];
; CHECK-NEXT: mov.b32 {%rs1, %rs2}, %r3;
-; CHECK-NEXT: mov.b32 {_, %rs3}, %r2;
-; CHECK-NEXT: mov.b32 %r5, {%rs3, %rs1};
-; CHECK-NEXT: mov.b32 %r6, {%rs2, %rs4};
-; CHECK-NEXT: mov.b32 %r7, 0;
-; CHECK-NEXT: max.f16x2 %r8, %r2, %r7;
-; CHECK-NEXT: max.f16x2 %r9, %r1, %r7;
-; CHECK-NEXT: st.b32 [%rd1], %r9;
-; CHECK-NEXT: mov.b32 {%rs5, _}, %r8;
-; CHECK-NEXT: st.b16 [%rd1+4], %rs5;
-; CHECK-NEXT: max.f16x2 %r10, %r6, %r7;
-; CHECK-NEXT: max.f16x2 %r11, %r5, %r7;
-; CHECK-NEXT: st.b32 [%rd1+6], %r11;
-; CHECK-NEXT: mov.b32 {%rs6, _}, %r10;
-; CHECK-NEXT: st.b16 [%rd1+10], %rs6;
+; CHECK-NEXT: mov.b32 {%rs3, %rs4}, %r2;
+; CHECK-NEXT: mov.b32 {%rs5, %rs6}, %r1;
+; CHECK-NEXT: mov.b16 %rs7, 0x0000;
+; CHECK-NEXT: setp.gt.f16 %p1, %rs5, %rs7;
+; CHECK-NEXT: setp.gt.f16 %p2, %rs6, %rs7;
+; CHECK-NEXT: setp.gt.f16 %p3, %rs3, %rs7;
+; CHECK-NEXT: selp.b16 %rs8, %rs3, 0x0000, %p3;
+; CHECK-NEXT: selp.b16 %rs9, %rs6, 0x0000, %p2;
+; CHECK-NEXT: selp.b16 %rs10, %rs5, 0x0000, %p1;
+; CHECK-NEXT: st.v2.b16 [%rd1], {%rs10, %rs9};
+; CHECK-NEXT: st.b16 [%rd1+4], %rs8;
+; CHECK-NEXT: setp.gt.f16 %p4, %rs4, %rs7;
+; CHECK-NEXT: setp.gt.f16 %p5, %rs1, %rs7;
+; CHECK-NEXT: setp.gt.f16 %p6, %rs2, %rs7;
+; CHECK-NEXT: selp.b16 %rs11, %rs2, 0x0000, %p6;
+; CHECK-NEXT: selp.b16 %rs12, %rs1, 0x0000, %p5;
+; CHECK-NEXT: selp.b16 %rs13, %rs4, 0x0000, %p4;
+; CHECK-NEXT: st.v2.b16 [%rd1+6], {%rs13, %rs12};
+; CHECK-NEXT: st.b16 [%rd1+10], %rs11;
; CHECK-NEXT: ret;
%load1 = load <3 x half>, ptr %rd0, align 16
%p1 = fcmp ogt <3 x half> %load1, zeroinitializer
@@ -47,29 +53,33 @@ define void @halfx3_extend_chain(ptr align 16 captures(none) %rd0) {
define void @halfx3_no_align(ptr align 4 captures(none) %rd0) {
; CHECK-LABEL: halfx3_no_align(
; CHECK: {
-; CHECK-NEXT: .reg .b16 %rs<7>;
-; CHECK-NEXT: .reg .b32 %r<10>;
+; CHECK-NEXT: .reg .pred %p<7>;
+; CHECK-NEXT: .reg .b16 %rs<14>;
; CHECK-NEXT: .reg .b64 %rd<2>;
; CHECK-EMPTY:
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: ld.param.b64 %rd1, [halfx3_no_align_param_0];
; CHECK-NEXT: ld.b16 %rs1, [%rd1+4];
-; CHECK-NEXT: mov.b32 %r1, {%rs1, %rs2};
-; CHECK-NEXT: ld.b32 %r2, [%rd1];
-; CHECK-NEXT: mov.b32 %r3, 0;
-; CHECK-NEXT: max.f16x2 %r4, %r1, %r3;
-; CHECK-NEXT: max.f16x2 %r5, %r2, %r3;
-; CHECK-NEXT: st.b32 [%rd1], %r5;
-; CHECK-NEXT: mov.b32 {%rs3, _}, %r4;
-; CHECK-NEXT: st.b16 [%rd1+4], %rs3;
-; CHECK-NEXT: ld.b16 %rs4, [%rd1+10];
-; CHECK-NEXT: mov.b32 %r6, {%rs4, %rs5};
-; CHECK-NEXT: ld.b32 %r7, [%rd1+6];
-; CHECK-NEXT: max.f16x2 %r8, %r6, %r3;
-; CHECK-NEXT: max.f16x2 %r9, %r7, %r3;
-; CHECK-NEXT: st.b32 [%rd1+6], %r9;
-; CHECK-NEXT: mov.b32 {%rs6, _}, %r8;
-; CHECK-NEXT: st.b16 [%rd1+10], %rs6;
+; CHECK-NEXT: ld.v2.b16 {%rs2, %rs3}, [%rd1];
+; CHECK-NEXT: mov.b16 %rs4, 0x0000;
+; CHECK-NEXT: setp.gt.f16 %p1, %rs2, %rs4;
+; CHECK-NEXT: setp.gt.f16 %p2, %rs3, %rs4;
+; CHECK-NEXT: setp.gt.f16 %p3, %rs1, %rs4;
+; CHECK-NEXT: selp.b16 %rs5, %rs1, 0x0000, %p3;
+; CHECK-NEXT: selp.b16 %rs6, %rs3, 0x0000, %p2;
+; CHECK-NEXT: selp.b16 %rs7, %rs2, 0x0000, %p1;
+; CHECK-NEXT: st.v2.b16 [%rd1], {%rs7, %rs6};
+; CHECK-NEXT: st.b16 [%rd1+4], %rs5;
+; CHECK-NEXT: ld.b16 %rs8, [%rd1+10];
+; CHECK-NEXT: ld.v2.b16 {%rs9, %rs10}, [%rd1+6];
+; CHECK-NEXT: setp.gt.f16 %p4, %rs9, %rs4;
+; CHECK-NEXT: setp.gt.f16 %p5, %rs10, %rs4;
+; CHECK-NEXT: setp.gt.f16 %p6, %rs8, %rs4;
+; CHECK-NEXT: selp.b16 %rs11, %rs8, 0x0000, %p6;
+; CHECK-NEXT: selp.b16 %rs12, %rs10, 0x0000, %p5;
+; CHECK-NEXT: selp.b16 %rs13, %rs9, 0x0000, %p4;
+; CHECK-NEXT: st.v2.b16 [%rd1+6], {%rs13, %rs12};
+; CHECK-NEXT: st.b16 [%rd1+10], %rs11;
; CHECK-NEXT: ret;
%load1 = load <3 x half>, ptr %rd0, align 4
%p1 = fcmp ogt <3 x half> %load1, zeroinitializer
diff --git a/llvm/test/Transforms/InstCombine/fcmp-select.ll b/llvm/test/Transforms/InstCombine/fcmp-select.ll
index 2115cd7f232e2..2d26a385e0f6b 100644
--- a/llvm/test/Transforms/InstCombine/fcmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll
@@ -532,7 +532,7 @@ define double @test_fcmp_ord_select_fabs_fcmp_intersect_drop_nnan(double %x, dou
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: [[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]]
;
@@ -543,8 +543,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: [[TMP1:%.*]] = fcmp ult 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
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index 15fc42f4bc97a..cb7a662458ee1 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -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
diff --git a/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll b/llvm/test/Transforms/InstCombine/unordered-fcmp-select.ll
index 8afcaa1c1a822..5865e2d7c9300 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: [[TMP1:%.*]] = fcmp ugt 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.0
diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll
index ff182ae3f56de..5dda18a7efb56 100644
--- a/llvm/test/Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll
+++ b/llvm/test/Transforms/SLPVectorizer/RISCV/remarks_cmp_sel_min_max.ll
@@ -8,7 +8,7 @@
; YAML-NEXT: Function: min_double
; YAML-NEXT: Args:
; YAML-NEXT: - String: 'Stores SLP vectorized with cost '
-; YAML-NEXT: - Cost: '-1'
+; YAML-NEXT: - Cost: '-3'
; YAML-NEXT: - String: ' and with tree size '
; YAML-NEXT: - TreeSize: '7'
define i32 @min_double(ptr noalias nocapture %A, ptr noalias nocapture %B) {
@@ -76,7 +76,7 @@ entry:
; YAML-NEXT: Function: max_double
; YAML-NEXT: Args:
; YAML-NEXT: - String: 'Stores SLP vectorized with cost '
-; YAML-NEXT: - Cost: '-1'
+; YAML-NEXT: - Cost: '-3'
; YAML-NEXT: - String: ' and with tree size '
; YAML-NEXT: - TreeSize: '7'
define i32 @max_double(ptr noalias nocapture %A, ptr noalias nocapture %B) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/210077
More information about the llvm-commits
mailing list