Skip to content

Commit 2f15637

Browse files
authored
[ValueTracking] Update Ordered when both operands are non-NaN. (llvm#143349)
When the original predicate is ordered and both operands are non-NaN, `Ordered` should be set to true. This variable still matters even if both operands are non-NaN because FMF only applies to select, not fcmp. Closes llvm#143123.
1 parent 5d3899d commit 2f15637

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8660,6 +8660,7 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
86608660
if (LHSSafe && RHSSafe) {
86618661
// Both operands are known non-NaN.
86628662
NaNBehavior = SPNB_RETURNS_ANY;
8663+
Ordered = CmpInst::isOrdered(Pred);
86638664
} else if (CmpInst::isOrdered(Pred)) {
86648665
// An ordered comparison will return false when given a NaN, so it
86658666
// returns the RHS.

llvm/test/Transforms/InstCombine/fcmp-select.ll

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,12 +270,36 @@ define i1 @test_fcmp_select_var_const_unordered(double %x, double %y) {
270270
}
271271

272272
define i1 @test_fcmp_ord_select_fcmp_oeq_var_const(double %x) {
273-
; CHECK-LABEL: @test_fcmp_ord_select_fcmp_oeq_var_const(
274-
; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[X:%.*]], 1.000000e+00
275-
; CHECK-NEXT: ret i1 [[CMP1]]
273+
; CHECK-LABEL: @test_fcmp_ord_select_fcmp_oeq_var_const(
274+
; CHECK-NEXT: [[TMP1:%.*]] = fcmp oeq double [[X:%.*]], 1.000000e+00
275+
; CHECK-NEXT: ret i1 [[TMP1]]
276276
;
277277
%cmp1 = fcmp ord double %x, 0.000000e+00
278278
%sel = select i1 %cmp1, double %x, double 0.000000e+00
279279
%cmp2 = fcmp oeq double %sel, 1.000000e+00
280280
ret i1 %cmp2
281281
}
282+
283+
; Make sure that we recognize the SPF correctly.
284+
285+
define float @test_select_nnan_nsz_fcmp_olt(float %x) {
286+
; CHECK-LABEL: @test_select_nnan_nsz_fcmp_olt(
287+
; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[X:%.*]], -0.000000e+00
288+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[TMP1]], float [[X]], float -0.000000e+00
289+
; CHECK-NEXT: ret float [[SEL1]]
290+
;
291+
%cmp = fcmp olt float %x, 0.000000e+00
292+
%sel = select nnan nsz i1 %cmp, float %x, float -0.000000e+00
293+
ret float %sel
294+
}
295+
296+
define float @test_select_nnan_nsz_fcmp_ult(float %x) {
297+
; CHECK-LABEL: @test_select_nnan_nsz_fcmp_ult(
298+
; CHECK-NEXT: [[DOTINV:%.*]] = fcmp oge float [[X:%.*]], 0.000000e+00
299+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[DOTINV]], float -0.000000e+00, float [[X]]
300+
; CHECK-NEXT: ret float [[SEL1]]
301+
;
302+
%cmp = fcmp ult float %x, 0.000000e+00
303+
%sel = select nnan nsz i1 %cmp, float %x, float -0.000000e+00
304+
ret float %sel
305+
}

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ TEST_F(MatchSelectPatternTest, FastFMin) {
187187
" %A = select i1 %1, float %a, float 5.0\n"
188188
" ret float %A\n"
189189
"}\n");
190+
expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, true});
191+
}
192+
193+
TEST_F(MatchSelectPatternTest, FastFMinUnordered) {
194+
parseAssembly("define float @test(float %a) {\n"
195+
" %1 = fcmp nnan ult float %a, 5.0\n"
196+
" %A = select i1 %1, float %a, float 5.0\n"
197+
" ret float %A\n"
198+
"}\n");
190199
expectPattern({SPF_FMINNUM, SPNB_RETURNS_ANY, false});
191200
}
192201

0 commit comments

Comments
 (0)