Skip to content

Commit 0e1a52f

Browse files
authored
ValueTracking: Handle compare gt to -inf in class identification (#72086)
This apparently shows up somewhere in chromium. We also are missing a canonicalization to an equality compare with inf.
1 parent 45a92ac commit 0e1a52f

File tree

3 files changed

+88
-14
lines changed

3 files changed

+88
-14
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4181,8 +4181,14 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
41814181
}
41824182
case FCmpInst::FCMP_OGE:
41834183
case FCmpInst::FCMP_ULT: {
4184-
if (ConstRHS->isNegative()) // TODO
4185-
return {nullptr, fcAllFlags};
4184+
if (ConstRHS->isNegative()) {
4185+
// fcmp oge x, -inf -> ~fcNan
4186+
// fcmp oge fabs(x), -inf -> ~fcNan
4187+
// fcmp ult x, -inf -> fcNan
4188+
// fcmp ult fabs(x), -inf -> fcNan
4189+
Mask = ~fcNan;
4190+
break;
4191+
}
41864192

41874193
// fcmp oge fabs(x), +inf -> fcInf
41884194
// fcmp oge x, +inf -> fcPosInf
@@ -4195,8 +4201,14 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
41954201
}
41964202
case FCmpInst::FCMP_OGT:
41974203
case FCmpInst::FCMP_ULE: {
4198-
if (ConstRHS->isNegative())
4199-
return {nullptr, fcAllFlags};
4204+
if (ConstRHS->isNegative()) {
4205+
// fcmp ogt x, -inf -> fcmp one x, -inf
4206+
// fcmp ogt fabs(x), -inf -> fcmp ord x, x
4207+
// fcmp ule x, -inf -> fcmp ueq x, -inf
4208+
// fcmp ule fabs(x), -inf -> fcmp uno x, x
4209+
Mask = IsFabs ? ~fcNan : ~(fcNegInf | fcNan);
4210+
break;
4211+
}
42004212

42014213
// No value is ordered and greater than infinity.
42024214
Mask = fcNone;

llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3047,8 +3047,7 @@ define i1 @assume_ogt_neginf_one_neginf(float %arg) {
30473047
; CHECK-SAME: float [[ARG:%.*]]) {
30483048
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[ARG]], 0xFFF0000000000000
30493049
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3050-
; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[ARG]], 0xFFF0000000000000
3051-
; CHECK-NEXT: ret i1 [[CMP]]
3050+
; CHECK-NEXT: ret i1 true
30523051
;
30533052
%cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
30543053
call void @llvm.assume(i1 %cmp.ogt.neginf)
@@ -3089,8 +3088,7 @@ define i1 @assume_ult_neginf_oeq_neginf(float %arg) {
30893088
; CHECK-SAME: float [[ARG:%.*]]) {
30903089
; CHECK-NEXT: [[CMP_ULT_NEGINF:%.*]] = fcmp ult float [[ARG]], 0xFFF0000000000000
30913090
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ULT_NEGINF]])
3092-
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
3093-
; CHECK-NEXT: ret i1 [[CMP]]
3091+
; CHECK-NEXT: ret i1 false
30943092
;
30953093
%cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
30963094
call void @llvm.assume(i1 %cmp.ult.neginf)
@@ -3136,8 +3134,7 @@ define i1 @assume_fabs_ule_neginf_oeq_neginf(float %arg) {
31363134
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
31373135
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ule float [[FABS_ARG]], 0xFFF0000000000000
31383136
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
3139-
; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
3140-
; CHECK-NEXT: ret i1 [[CMP]]
3137+
; CHECK-NEXT: ret i1 false
31413138
;
31423139
%fabs.arg = call float @llvm.fabs.f32(float %arg)
31433140
%cmp.ogt.neginf = fcmp ule float %fabs.arg, 0xFFF0000000000000

llvm/unittests/Analysis/ValueTrackingTest.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,8 @@ TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_NInf) {
18301830
" %A2 = fcmp uge double %arg, 0xFFF0000000000000"
18311831
" %A3 = fcmp ogt double %arg, 0xFFF0000000000000"
18321832
" %A4 = fcmp ule double %arg, 0xFFF0000000000000"
1833+
" %A5 = fcmp oge double %arg, 0xFFF0000000000000"
1834+
" %A6 = fcmp ult double %arg, 0xFFF0000000000000"
18331835
" ret i1 %A\n"
18341836
"}\n");
18351837

@@ -1847,14 +1849,77 @@ TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_NInf) {
18471849
auto [OgtVal, OgtClass] =
18481850
fcmpToClassTest(CmpInst::FCMP_OGT, *A3->getFunction(), A3->getOperand(0),
18491851
A3->getOperand(1));
1850-
EXPECT_EQ(nullptr, OgtVal);
1851-
EXPECT_EQ(fcAllFlags, OgtClass);
1852+
EXPECT_EQ(A3->getOperand(0), OgtVal);
1853+
EXPECT_EQ(~(fcNegInf | fcNan), OgtClass);
18521854

18531855
auto [UleVal, UleClass] =
18541856
fcmpToClassTest(CmpInst::FCMP_ULE, *A4->getFunction(), A4->getOperand(0),
18551857
A4->getOperand(1));
1856-
EXPECT_EQ(nullptr, UleVal);
1857-
EXPECT_EQ(fcAllFlags, UleClass);
1858+
EXPECT_EQ(A4->getOperand(0), UleVal);
1859+
EXPECT_EQ(fcNegInf | fcNan, UleClass);
1860+
1861+
auto [OgeVal, OgeClass] =
1862+
fcmpToClassTest(CmpInst::FCMP_OGE, *A5->getFunction(), A5->getOperand(0),
1863+
A5->getOperand(1));
1864+
EXPECT_EQ(A5->getOperand(0), OgeVal);
1865+
EXPECT_EQ(~fcNan, OgeClass);
1866+
1867+
auto [UltVal, UltClass] =
1868+
fcmpToClassTest(CmpInst::FCMP_ULT, *A6->getFunction(), A6->getOperand(0),
1869+
A6->getOperand(1));
1870+
EXPECT_EQ(A6->getOperand(0), UltVal);
1871+
EXPECT_EQ(fcNan, UltClass);
1872+
}
1873+
1874+
TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_FabsNInf) {
1875+
parseAssembly("declare double @llvm.fabs.f64(double)\n"
1876+
"define i1 @test(double %arg) {\n"
1877+
" %fabs.arg = call double @llvm.fabs.f64(double %arg)\n"
1878+
" %A = fcmp olt double %fabs.arg, 0xFFF0000000000000"
1879+
" %A2 = fcmp uge double %fabs.arg, 0xFFF0000000000000"
1880+
" %A3 = fcmp ogt double %fabs.arg, 0xFFF0000000000000"
1881+
" %A4 = fcmp ule double %fabs.arg, 0xFFF0000000000000"
1882+
" %A5 = fcmp oge double %fabs.arg, 0xFFF0000000000000"
1883+
" %A6 = fcmp ult double %fabs.arg, 0xFFF0000000000000"
1884+
" ret i1 %A\n"
1885+
"}\n");
1886+
1887+
Value *ArgVal = F->getArg(0);
1888+
1889+
auto [OltVal, OltClass] = fcmpToClassTest(
1890+
CmpInst::FCMP_OLT, *A->getFunction(), A->getOperand(0), A->getOperand(1));
1891+
EXPECT_EQ(ArgVal, OltVal);
1892+
EXPECT_EQ(fcNone, OltClass);
1893+
1894+
auto [UgeVal, UgeClass] =
1895+
fcmpToClassTest(CmpInst::FCMP_UGE, *A2->getFunction(), A2->getOperand(0),
1896+
A2->getOperand(1));
1897+
EXPECT_EQ(ArgVal, UgeVal);
1898+
EXPECT_EQ(fcAllFlags, UgeClass);
1899+
1900+
auto [OgtVal, OgtClass] =
1901+
fcmpToClassTest(CmpInst::FCMP_OGT, *A3->getFunction(), A3->getOperand(0),
1902+
A3->getOperand(1));
1903+
EXPECT_EQ(ArgVal, OgtVal);
1904+
EXPECT_EQ(~fcNan, OgtClass);
1905+
1906+
auto [UleVal, UleClass] =
1907+
fcmpToClassTest(CmpInst::FCMP_ULE, *A4->getFunction(), A4->getOperand(0),
1908+
A4->getOperand(1));
1909+
EXPECT_EQ(ArgVal, UleVal);
1910+
EXPECT_EQ(fcNan, UleClass);
1911+
1912+
auto [OgeVal, OgeClass] =
1913+
fcmpToClassTest(CmpInst::FCMP_OGE, *A5->getFunction(), A5->getOperand(0),
1914+
A5->getOperand(1));
1915+
EXPECT_EQ(ArgVal, OgeVal);
1916+
EXPECT_EQ(~fcNan, OgeClass);
1917+
1918+
auto [UltVal, UltClass] =
1919+
fcmpToClassTest(CmpInst::FCMP_ULT, *A6->getFunction(), A6->getOperand(0),
1920+
A6->getOperand(1));
1921+
EXPECT_EQ(ArgVal, UltVal);
1922+
EXPECT_EQ(fcNan, UltClass);
18581923
}
18591924

18601925
TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_PInf) {

0 commit comments

Comments
 (0)