[llvm] ValueTracking: Handle compare gt to negative infinity in class identi… (PR #72086)

via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 12 22:26:45 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>

…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:

- (modified) llvm/lib/Analysis/ValueTracking.cpp (+16-4) 
- (modified) llvm/test/Transforms/InstSimplify/assume-fcmp-constant-implies-class.ll (+3-6) 
- (modified) llvm/unittests/Analysis/ValueTrackingTest.cpp (+69-4) 


``````````diff
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) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/72086


More information about the llvm-commits mailing list