[PATCH] D110518: [SCEV] Prove isKnown(Non)Negative using CtxI when possible

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 26 23:05:36 PDT 2021


mkazantsev created this revision.
mkazantsev added reviewers: reames, nikic, lebedev.ri, fhahn, efriedma.
Herald added a subscriber: hiraditya.
mkazantsev requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Sometimes the (non)negativity of something may only be inferred via context.
Use it when it is available.


https://reviews.llvm.org/D110518

Files:
  llvm/lib/Analysis/ScalarEvolution.cpp
  llvm/test/Transforms/IndVarSimplify/outer_phi.ll


Index: llvm/test/Transforms/IndVarSimplify/outer_phi.ll
===================================================================
--- llvm/test/Transforms/IndVarSimplify/outer_phi.ll
+++ llvm/test/Transforms/IndVarSimplify/outer_phi.ll
@@ -79,7 +79,6 @@
   ret i32 1
 }
 
-; FIXME: iv <u b, b >=s 0 --> iv <s b. We should be able to remove the 2nd check.
 define i32 @test_01a(i32 %a, i32 %b) {
 ; CHECK-LABEL: @test_01a(
 ; CHECK-NEXT:  entry:
@@ -95,8 +94,7 @@
 ; CHECK-NEXT:    [[SIGNED_COND:%.*]] = icmp ult i32 [[IV]], [[B]]
 ; CHECK-NEXT:    br i1 [[SIGNED_COND]], label [[INNER_1:%.*]], label [[SIDE_EXIT:%.*]]
 ; CHECK:       inner.1:
-; CHECK-NEXT:    [[UNSIGNED_COND:%.*]] = icmp slt i32 [[IV]], [[B]]
-; CHECK-NEXT:    br i1 [[UNSIGNED_COND]], label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
+; CHECK-NEXT:    br i1 true, label [[INNER_BACKEDGE]], label [[SIDE_EXIT]]
 ; CHECK:       inner.backedge:
 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
 ; CHECK-NEXT:    [[INNER_LOOP_COND:%.*]] = call i1 @cond()
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -10711,13 +10711,25 @@
   if (IsSignFlippedPredicate(Pred, FoundPred)) {
     // Unsigned comparison is the same as signed comparison when both the
     // operands are non-negative or negative.
-    if ((isKnownNonNegative(FoundLHS) && isKnownNonNegative(FoundRHS)) ||
-        (isKnownNegative(FoundLHS) && isKnownNegative(FoundRHS)))
+    auto IsKnownNonNegative = [&](const SCEV *S) {
+      if (CtxI)
+        return isKnownPredicateAt(ICmpInst::ICMP_SGE, S, getZero(S->getType()),
+                                  CtxI);
+      return isKnownNonNegative(S);
+    };
+    auto IsKnownNegative = [&](const SCEV *S) {
+      if (CtxI)
+        return isKnownPredicateAt(ICmpInst::ICMP_SLT, S, getZero(S->getType()),
+                                  CtxI);
+      return isKnownNegative(S);
+    };
+    if ((IsKnownNonNegative(FoundLHS) && IsKnownNonNegative(FoundRHS)) ||
+        (IsKnownNegative(FoundLHS) && IsKnownNegative(FoundRHS)))
       return isImpliedCondOperands(Pred, LHS, RHS, FoundLHS, FoundRHS, CtxI);
     // TODO: A symmetrical fact should be provable for replacing an unsigned
     // predicate with signed.
     if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SLE)
-      if (isKnownNonNegative(RHS))
+      if (IsKnownNonNegative(RHS))
         // We need to prove that LHS <s RHS. Knowing that RHS is non-negative,
         // if we can prove that LHS <u RHS, this will automatically imply the
         // fact we need.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110518.375146.patch
Type: text/x-patch
Size: 2680 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210927/d3f0d4c8/attachment.bin>


More information about the llvm-commits mailing list