[llvm] e038b60 - Revert "[IndVars] Remove monotonic checks with unknown exit count"

Raphael Isemann via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 27 07:32:53 PDT 2020


Author: Raphael Isemann
Date: 2020-10-27T15:31:37+01:00
New Revision: e038b60d9169733367393f733058f0ff23c28d3f

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

LOG: Revert "[IndVars] Remove monotonic checks with unknown exit count"

This reverts commit c6ca26c0bfedb8f80d6f8cb9adde25b1d6aac1c5.
This breaks stage2 builds due to hitting this assert:
```
   Assertion failed: (WeightSum <= UINT32_MAX && "Expected weights to scale down to 32 bits"), function calcMetadataWeights
```
when compiling AArch64RegisterBankInfo.cpp in LLVM.

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/ScalarEvolution.h
    llvm/lib/Analysis/ScalarEvolution.cpp
    llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
    llvm/test/Transforms/IndVarSimplify/monotonic_checks.ll
    llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 9a580f742572..6dc3f2e952e4 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -961,17 +961,6 @@ class ScalarEvolution {
                                 const SCEV *&InvariantLHS,
                                 const SCEV *&InvariantRHS);
 
-  /// Return true if the result of the predicate LHS `Pred` RHS is loop
-  /// invariant with respect to L at given Context during at least first
-  /// MaxIter iterations.  Set InvariantPred, InvariantLHS and InvariantLHS so
-  /// that InvariantLHS `InvariantPred` InvariantRHS is the loop invariant form
-  /// of LHS `Pred` RHS. The predicate should be the loop's exit condition.
-  bool isLoopInvariantExitCondDuringFirstIterations(
-      ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
-      const Instruction *Context, const SCEV *MaxIter,
-      ICmpInst::Predicate &InvariantPred, const SCEV *&InvariantLHS,
-      const SCEV *&InvariantRHS);
-
   /// Simplify LHS and RHS in a comparison with predicate Pred. Return true
   /// iff any changes were made. If the operands are provably equal or
   /// unequal, LHS and RHS are set to the same value and Pred is set to either

diff  --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index eebb2d4f64c2..17f9c12921ef 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9279,75 +9279,6 @@ bool ScalarEvolution::isLoopInvariantPredicate(
   return true;
 }
 
-bool ScalarEvolution::isLoopInvariantExitCondDuringFirstIterations(
-    ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, const Loop *L,
-    const Instruction *Context, const SCEV *MaxIter,
-    ICmpInst::Predicate &InvariantPred, const SCEV *&InvariantLHS,
-    const SCEV *&InvariantRHS) {
-  // Try to prove the following set of facts:
-  // - The predicate is monotonic.
-  // - If the check does not fail on the 1st iteration:
-  //   - No overflow will happen during first MaxIter iterations;
-  //   - It will not fail on the MaxIter'th iteration.
-  // If the check does fail on the 1st iteration, we leave the loop and no
-  // other checks matter.
-
-  // If there is a loop-invariant, force it into the RHS, otherwise bail out.
-  if (!isLoopInvariant(RHS, L)) {
-    if (!isLoopInvariant(LHS, L))
-      return false;
-
-    std::swap(LHS, RHS);
-    Pred = ICmpInst::getSwappedPredicate(Pred);
-  }
-
-  auto *AR = dyn_cast<SCEVAddRecExpr>(LHS);
-  // TODO: Lift affinity limitation in the future.
-  if (!AR || AR->getLoop() != L || !AR->isAffine())
-    return false;
-
-  // The predicate must be relational (i.e. <, <=, >=, >).
-  if (!ICmpInst::isRelational(Pred))
-    return false;
-
-  // TODO: Support steps other than +/- 1.
-  const SCEV *Step = AR->getOperand(1);
-  auto *One = getOne(Step->getType());
-  auto *MinusOne = getNegativeSCEV(One);
-  if (Step != One && Step != MinusOne)
-    return false;
-
-  // Type mismatch here means that MaxIter is potentially larger than max
-  // unsigned value in start type, which mean we cannot prove no wrap for the
-  // indvar.
-  if (AR->getType() != MaxIter->getType())
-    return false;
-
-  // Value of IV on suggested last iteration.
-  const SCEV *Last = AR->evaluateAtIteration(MaxIter, *this);
-  // Does it still meet the requirement?
-  if (!isKnownPredicateAt(Pred, Last, RHS, Context))
-    return false;
-  // Because step is +/- 1 and MaxIter has same type as Start (i.e. it does
-  // not exceed max unsigned value of this type), this effectively proves
-  // that there is no wrap during the iteration. To prove that there is no
-  // signed/unsigned wrap, we need to check that
-  // Start <= Last for step = 1 or Start >= Last for step = -1.
-  ICmpInst::Predicate NoOverflowPred =
-      CmpInst::isSigned(Pred) ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
-  if (Step == MinusOne)
-    NoOverflowPred = CmpInst::getSwappedPredicate(NoOverflowPred);
-  const SCEV *Start = AR->getStart();
-  if (!isKnownPredicateAt(NoOverflowPred, Start, Last, Context))
-    return false;
-
-  // Everything is fine.
-  InvariantPred = Pred;
-  InvariantLHS = Start;
-  InvariantRHS = RHS;
-  return true;
-}
-
 bool ScalarEvolution::isKnownPredicateViaConstantRanges(
     ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS) {
   if (HasSameValue(LHS, RHS))

diff  --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
index 00976d44b665..ca242898caa2 100644
--- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
+++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -2307,9 +2307,9 @@ bool IndVarSimplify::sinkUnusedInvariants(Loop *L) {
 }
 
 // Returns true if the condition of \p BI being checked is invariant and can be
-// proved to be trivially true during at least first \p MaxIter iterations.
+// proved to be trivially true.
 static bool isTrivialCond(const Loop *L, BranchInst *BI, ScalarEvolution *SE,
-                          bool ProvingLoopExit, const SCEV *MaxIter) {
+                          bool ProvingLoopExit) {
   ICmpInst::Predicate Pred;
   Value *LHS, *RHS;
   using namespace PatternMatch;
@@ -2335,20 +2335,7 @@ static bool isTrivialCond(const Loop *L, BranchInst *BI, ScalarEvolution *SE,
   if (SE->isKnownPredicateAt(Pred, LHSS, RHSS, BI))
     return true;
 
-  if (ProvingLoopExit)
-    return false;
-
-  ICmpInst::Predicate InvariantPred;
-  const SCEV *InvariantLHS, *InvariantRHS;
-
-  // Check if there is a loop-invariant predicate equivalent to our check.
-  if (!SE->isLoopInvariantExitCondDuringFirstIterations(
-           Pred, LHSS, RHSS, L, BI, MaxIter, InvariantPred, InvariantLHS,
-           InvariantRHS))
-    return false;
-
-  // Can we prove it to be trivially true?
-  return SE->isKnownPredicateAt(InvariantPred, InvariantLHS, InvariantRHS, BI);
+  return false;
 }
 
 bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
@@ -2429,15 +2416,14 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
       // Okay, we do not know the exit count here. Can we at least prove that it
       // will remain the same within iteration space?
       auto *BI = cast<BranchInst>(ExitingBB->getTerminator());
-      auto OptimizeCond = [&](bool Inverted, const SCEV *MaxIter) {
-        if (isTrivialCond(L, BI, SE, Inverted, MaxIter)) {
+      auto OptimizeCond = [&](bool Inverted) {
+        if (isTrivialCond(L, BI, SE, Inverted)) {
           FoldExit(ExitingBB, Inverted);
           return true;
         }
         return false;
       };
-      if (OptimizeCond(false, MaxExitCount) ||
-          OptimizeCond(true, MaxExitCount))
+      if (OptimizeCond(false) || OptimizeCond(true))
         Changed = true;
       continue;
     }

diff  --git a/llvm/test/Transforms/IndVarSimplify/monotonic_checks.ll b/llvm/test/Transforms/IndVarSimplify/monotonic_checks.ll
index 475409246f3a..048254427c5f 100644
--- a/llvm/test/Transforms/IndVarSimplify/monotonic_checks.ll
+++ b/llvm/test/Transforms/IndVarSimplify/monotonic_checks.ll
@@ -12,7 +12,8 @@ define i32 @test_01(i32* %p) {
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], -1
-; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i32 [[IV_NEXT]], [[LEN]]
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[FAIL:%.*]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
@@ -92,7 +93,8 @@ define i32 @test_02(i32* %p) {
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
 ; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
-; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
+; CHECK-NEXT:    [[RC:%.*]] = icmp sgt i32 [[IV_NEXT]], [[LEN]]
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[FAIL:%.*]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
@@ -170,7 +172,8 @@ define i32 @test_03(i32* %p) {
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
-; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
+; CHECK-NEXT:    [[RC:%.*]] = icmp ugt i32 [[IV_NEXT]], [[LEN]]
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[FAIL:%.*]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 1000
 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
@@ -208,7 +211,8 @@ define i32 @test_04(i32* %p) {
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[LEN]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], -1
-; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
+; CHECK-NEXT:    [[RC:%.*]] = icmp slt i32 [[IV_NEXT]], [[LEN]]
+; CHECK-NEXT:    br i1 [[RC]], label [[BACKEDGE]], label [[FAIL:%.*]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0
 ; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]

diff  --git a/llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll b/llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
index 9e6908c308d2..cfcd931b6f5b 100644
--- a/llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
+++ b/llvm/test/Transforms/IndVarSimplify/predicated_ranges.ll
@@ -71,7 +71,8 @@ define void @test_predicated_simple_signed(i32* %p, i32* %arr) {
 ; CHECK-NEXT:    br i1 [[ZERO_COND]], label [[EXIT:%.*]], label [[RANGE_CHECK_BLOCK:%.*]]
 ; CHECK:       range_check_block:
 ; CHECK-NEXT:    [[IV_NEXT]] = sub i32 [[IV]], 1
-; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[FAIL:%.*]]
+; CHECK-NEXT:    [[RANGE_CHECK:%.*]] = icmp slt i32 [[IV_NEXT]], [[LEN]]
+; CHECK-NEXT:    br i1 [[RANGE_CHECK]], label [[BACKEDGE]], label [[FAIL:%.*]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, i32* [[P]], i32 [[IV]]
 ; CHECK-NEXT:    [[EL:%.*]] = load i32, i32* [[EL_PTR]], align 4


        


More information about the llvm-commits mailing list