[llvm] 8dc9889 - [SCEV] Handle non-positive case in isImpliedViaOperations

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 4 20:07:58 PST 2020


Author: Max Kazantsev
Date: 2020-11-05T11:07:37+07:00
New Revision: 8dc98897c4af20aeb52f1f19f538c08e55793283

URL: https://github.com/llvm/llvm-project/commit/8dc98897c4af20aeb52f1f19f538c08e55793283
DIFF: https://github.com/llvm/llvm-project/commit/8dc98897c4af20aeb52f1f19f538c08e55793283.diff

LOG: [SCEV] Handle non-positive case in isImpliedViaOperations

We already handle non-negative case there. Add support for non-positive.

Added: 
    

Modified: 
    llvm/lib/Analysis/ScalarEvolution.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 77fc2d47785d..a385cd4e8dc2 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10653,21 +10653,32 @@ bool ScalarEvolution::isImpliedViaOperations(ICmpInst::Predicate Pred,
   }
 
   // For unsigned, try to reduce it to corresponding signed comparison.
-  if (Pred == ICmpInst::ICMP_UGT)
+  if (Pred == ICmpInst::ICMP_UGT) {
     // We can replace unsigned predicate with its signed counterpart if all
-    // involved values are non-negative.
+    // involved values are non-negative or non-positive.
     // TODO: We could have better support for unsigned.
-    if (isKnownNonNegative(FoundLHS) && isKnownNonNegative(FoundRHS)) {
-      // Knowing that both FoundLHS and FoundRHS are non-negative, and knowing
-      // FoundLHS >u FoundRHS, we also know that FoundLHS >s FoundRHS. Let us
-      // use this fact to prove that LHS and RHS are non-negative.
+    auto IsNonNegativeOrNonPositive = [this](const SCEV *S) {
+      return isKnownNonNegative(S) || isKnownNonPositive(S);
+    };
+    if (IsNonNegativeOrNonPositive(FoundLHS) &&
+        IsNonNegativeOrNonPositive(FoundRHS)) {
+      // Knowing that both FoundLHS and FoundRHS are non-negative/non-
+      // positive, and knowing FoundLHS >u FoundRHS, we also know that
+      // FoundLHS >s FoundRHS. Let us use this fact to prove that LHS and RHS
+      // are non-negative or non-positive.
+      const SCEV *One = getMinusOne(LHS->getType());
       const SCEV *MinusOne = getMinusOne(LHS->getType());
-      if (isImpliedCondOperands(ICmpInst::ICMP_SGT, LHS, MinusOne, FoundLHS,
-                                FoundRHS) &&
-          isImpliedCondOperands(ICmpInst::ICMP_SGT, RHS, MinusOne, FoundLHS,
-                                FoundRHS))
+      auto IsImpliedNonNegativeOrNonPositive = [&](const SCEV *S) {
+        return isImpliedCondOperands(ICmpInst::ICMP_SGT, S, MinusOne, FoundLHS,
+                                     FoundRHS) ||
+               isImpliedCondOperands(ICmpInst::ICMP_SGT, One, S, FoundLHS,
+                                     FoundRHS);
+      };
+      if (IsImpliedNonNegativeOrNonPositive(LHS) &&
+          IsImpliedNonNegativeOrNonPositive(RHS))
         Pred = ICmpInst::ICMP_SGT;
     }
+  }
 
   if (Pred != ICmpInst::ICMP_SGT)
     return false;


        


More information about the llvm-commits mailing list