diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index d6bb852e208f9..d8c1096049dce 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8660,6 +8660,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred, if (LHSSafe && RHSSafe) { // Both operands are known non-NaN. NaNBehavior = SPNB_RETURNS_ANY; + 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 053b233cb5f04..b622c8636eccb 100644 --- a/llvm/test/Transforms/InstCombine/fcmp-select.ll +++ b/llvm/test/Transforms/InstCombine/fcmp-select.ll @@ -270,12 +270,36 @@ 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: [[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 + %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: [[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 + %sel = select nnan nsz i1 %cmp, float %x, float -0.000000e+00 + ret float %sel +} diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index e23005b60891d..6031898f7f679 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -187,6 +187,15 @@ 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, 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}); }