-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ValueTracking: Handle compare gt to -inf in class identification #72086
Conversation
…fication This apparently shows up somewhere in chromium. We also are missing a canonicalization to an equality compare with inf.
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-llvm-analysis Author: Matt Arsenault (arsenm) Changes…fication This apparently shows up somewhere in chromium. We also are missing a canonicalization to an equality compare with inf. Full diff: https://github.com/llvm/llvm-project/pull/72086.diff 3 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 923ff043fe71057..dc3c90ba9db1664 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4181,8 +4181,14 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
}
case FCmpInst::FCMP_OGE:
case FCmpInst::FCMP_ULT: {
- if (ConstRHS->isNegative()) // TODO
- return {nullptr, fcAllFlags};
+ if (ConstRHS->isNegative()) {
+ // fcmp oge x, -inf -> ~fcNan
+ // fcmp oge fabs(x), -inf -> ~fcNan
+ // fcmp ult x, -inf -> fcNan
+ // fcmp ult fabs(x), -inf -> fcNan
+ Mask = ~fcNan;
+ break;
+ }
// fcmp oge fabs(x), +inf -> fcInf
// fcmp oge x, +inf -> fcPosInf
@@ -4195,8 +4201,14 @@ llvm::fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
}
case FCmpInst::FCMP_OGT:
case FCmpInst::FCMP_ULE: {
- if (ConstRHS->isNegative())
- return {nullptr, fcAllFlags};
+ if (ConstRHS->isNegative()) {
+ // fcmp ogt x, -inf -> fcmp one x, -inf
+ // fcmp ogt fabs(x), -inf -> fcmp ord x, x
+ // fcmp ule x, -inf -> fcmp ueq x, -inf
+ // fcmp ule fabs(x), -inf -> fcmp uno x, x
+ Mask = IsFabs ? ~fcNan : ~(fcNegInf | fcNan);
+ break;
+ }
// No value is ordered and greater than infinity.
Mask = fcNone;
diff --git a/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll b/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
index ec4e3c3092414aa..7970f3ce6bf09d8 100644
--- a/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
+++ b/llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll
@@ -3047,8 +3047,7 @@ define i1 @assume_ogt_neginf_one_neginf(float %arg) {
; CHECK-SAME: float [[ARG:%.*]]) {
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ogt float [[ARG]], 0xFFF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
-; CHECK-NEXT: [[CMP:%.*]] = fcmp one float [[ARG]], 0xFFF0000000000000
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%cmp.ogt.neginf = fcmp ogt float %arg, 0xFFF0000000000000
call void @llvm.assume(i1 %cmp.ogt.neginf)
@@ -3089,8 +3088,7 @@ define i1 @assume_ult_neginf_oeq_neginf(float %arg) {
; CHECK-SAME: float [[ARG:%.*]]) {
; CHECK-NEXT: [[CMP_ULT_NEGINF:%.*]] = fcmp ult float [[ARG]], 0xFFF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ULT_NEGINF]])
-; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%cmp.ult.neginf = fcmp ult float %arg, 0xFFF0000000000000
call void @llvm.assume(i1 %cmp.ult.neginf)
@@ -3136,8 +3134,7 @@ define i1 @assume_fabs_ule_neginf_oeq_neginf(float %arg) {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]])
; CHECK-NEXT: [[CMP_OGT_NEGINF:%.*]] = fcmp ule float [[FABS_ARG]], 0xFFF0000000000000
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_OGT_NEGINF]])
-; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float [[ARG]], 0xFFF0000000000000
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%cmp.ogt.neginf = fcmp ule float %fabs.arg, 0xFFF0000000000000
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 5bd1bb37e678e96..1190550340efbb6 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1830,6 +1830,8 @@ TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_NInf) {
" %A2 = fcmp uge double %arg, 0xFFF0000000000000"
" %A3 = fcmp ogt double %arg, 0xFFF0000000000000"
" %A4 = fcmp ule double %arg, 0xFFF0000000000000"
+ " %A5 = fcmp oge double %arg, 0xFFF0000000000000"
+ " %A6 = fcmp ult double %arg, 0xFFF0000000000000"
" ret i1 %A\n"
"}\n");
@@ -1847,14 +1849,77 @@ TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_NInf) {
auto [OgtVal, OgtClass] =
fcmpToClassTest(CmpInst::FCMP_OGT, *A3->getFunction(), A3->getOperand(0),
A3->getOperand(1));
- EXPECT_EQ(nullptr, OgtVal);
- EXPECT_EQ(fcAllFlags, OgtClass);
+ EXPECT_EQ(A3->getOperand(0), OgtVal);
+ EXPECT_EQ(~(fcNegInf | fcNan), OgtClass);
auto [UleVal, UleClass] =
fcmpToClassTest(CmpInst::FCMP_ULE, *A4->getFunction(), A4->getOperand(0),
A4->getOperand(1));
- EXPECT_EQ(nullptr, UleVal);
- EXPECT_EQ(fcAllFlags, UleClass);
+ EXPECT_EQ(A4->getOperand(0), UleVal);
+ EXPECT_EQ(fcNegInf | fcNan, UleClass);
+
+ auto [OgeVal, OgeClass] =
+ fcmpToClassTest(CmpInst::FCMP_OGE, *A5->getFunction(), A5->getOperand(0),
+ A5->getOperand(1));
+ EXPECT_EQ(A5->getOperand(0), OgeVal);
+ EXPECT_EQ(~fcNan, OgeClass);
+
+ auto [UltVal, UltClass] =
+ fcmpToClassTest(CmpInst::FCMP_ULT, *A6->getFunction(), A6->getOperand(0),
+ A6->getOperand(1));
+ EXPECT_EQ(A6->getOperand(0), UltVal);
+ EXPECT_EQ(fcNan, UltClass);
+}
+
+TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_FabsNInf) {
+ parseAssembly("declare double @llvm.fabs.f64(double)\n"
+ "define i1 @test(double %arg) {\n"
+ " %fabs.arg = call double @llvm.fabs.f64(double %arg)\n"
+ " %A = fcmp olt double %fabs.arg, 0xFFF0000000000000"
+ " %A2 = fcmp uge double %fabs.arg, 0xFFF0000000000000"
+ " %A3 = fcmp ogt double %fabs.arg, 0xFFF0000000000000"
+ " %A4 = fcmp ule double %fabs.arg, 0xFFF0000000000000"
+ " %A5 = fcmp oge double %fabs.arg, 0xFFF0000000000000"
+ " %A6 = fcmp ult double %fabs.arg, 0xFFF0000000000000"
+ " ret i1 %A\n"
+ "}\n");
+
+ Value *ArgVal = F->getArg(0);
+
+ auto [OltVal, OltClass] = fcmpToClassTest(
+ CmpInst::FCMP_OLT, *A->getFunction(), A->getOperand(0), A->getOperand(1));
+ EXPECT_EQ(ArgVal, OltVal);
+ EXPECT_EQ(fcNone, OltClass);
+
+ auto [UgeVal, UgeClass] =
+ fcmpToClassTest(CmpInst::FCMP_UGE, *A2->getFunction(), A2->getOperand(0),
+ A2->getOperand(1));
+ EXPECT_EQ(ArgVal, UgeVal);
+ EXPECT_EQ(fcAllFlags, UgeClass);
+
+ auto [OgtVal, OgtClass] =
+ fcmpToClassTest(CmpInst::FCMP_OGT, *A3->getFunction(), A3->getOperand(0),
+ A3->getOperand(1));
+ EXPECT_EQ(ArgVal, OgtVal);
+ EXPECT_EQ(~fcNan, OgtClass);
+
+ auto [UleVal, UleClass] =
+ fcmpToClassTest(CmpInst::FCMP_ULE, *A4->getFunction(), A4->getOperand(0),
+ A4->getOperand(1));
+ EXPECT_EQ(ArgVal, UleVal);
+ EXPECT_EQ(fcNan, UleClass);
+
+ auto [OgeVal, OgeClass] =
+ fcmpToClassTest(CmpInst::FCMP_OGE, *A5->getFunction(), A5->getOperand(0),
+ A5->getOperand(1));
+ EXPECT_EQ(ArgVal, OgeVal);
+ EXPECT_EQ(~fcNan, OgeClass);
+
+ auto [UltVal, UltClass] =
+ fcmpToClassTest(CmpInst::FCMP_ULT, *A6->getFunction(), A6->getOperand(0),
+ A6->getOperand(1));
+ EXPECT_EQ(ArgVal, UltVal);
+ EXPECT_EQ(fcNan, UltClass);
}
TEST_F(ComputeKnownFPClassTest, FCmpToClassTest_PInf) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
…m#72086) This apparently shows up somewhere in chromium. We also are missing a canonicalization to an equality compare with inf.
This apparently shows up somewhere in chromium. We also are missing a canonicalization to an equality compare with inf.