[llvm] r327363 - Revert [SCEV] Fix isKnownPredicate

Serguei Katkov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 12 23:36:00 PDT 2018


Author: skatkov
Date: Mon Mar 12 23:36:00 2018
New Revision: 327363

URL: http://llvm.org/viewvc/llvm-project?rev=327363&view=rev
Log:
Revert [SCEV] Fix isKnownPredicate

It is a revert of rL327362 which causes build bot failures with assert like

Assertion `isAvailableAtLoopEntry(RHS, L) && "RHS is not available at Loop Entry"' failed.

Removed:
    llvm/trunk/test/Transforms/IndVarSimplify/inner-loop-by-latch-cond.ll
Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=327363&r1=327362&r2=327363&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Mon Mar 12 23:36:00 2018
@@ -829,25 +829,6 @@ public:
   /// Test if the given expression is known to be non-zero.
   bool isKnownNonZero(const SCEV *S);
 
-  /// Splits SCEV expression \p S into two SCEVs. One of them is obtained from
-  /// \p S by substitution of all AddRec sub-expression related to loop \p L
-  /// with initial value of that SCEV. The second is obtained from \p S by
-  /// substitution of all AddRec sub-expressions related to loop \p L with post
-  /// increment of this AddRec in the loop \p L. In both cases all other AddRec
-  /// sub-expressions (not related to \p L) remain the same.
-  /// If the \p S contains non-invariant unknown SCEV the function returns
-  /// CouldNotCompute SCEV in both values of std::pair.
-  /// For example, for SCEV S={0, +, 1}<L1> + {0, +, 1}<L2> and loop L=L1
-  /// the function returns pair:
-  /// first = {0, +, 1}<L2>
-  /// second = {1, +, 1}<L1> + {0, +, 1}<L2>
-  /// We can see that for the first AddRec sub-expression it was replaced with
-  /// 0 (initial value) for the first element and to {1, +, 1}<L1> (post
-  /// increment value) for the second one. In both cases AddRec expression
-  /// related to L2 remains the same.
-  std::pair<const SCEV *, const SCEV *> SplitIntoInitAndPostInc(const Loop *L,
-                                                                const SCEV *S);
-
   /// Test if the given expression is known to satisfy the condition described
   /// by Pred, LHS, and RHS.
   bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS,

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=327363&r1=327362&r2=327363&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Mar 12 23:36:00 2018
@@ -8727,78 +8727,38 @@ bool ScalarEvolution::isKnownNonZero(con
   return isKnownNegative(S) || isKnownPositive(S);
 }
 
-std::pair<const SCEV *, const SCEV *>
-ScalarEvolution::SplitIntoInitAndPostInc(const Loop *L, const SCEV *S) {
-  // Compute SCEV on entry of loop L.
-  const SCEV *Start = SCEVInitRewriter::rewrite(S, L, *this);
-  if (Start == getCouldNotCompute())
-    return { Start, Start };
-  // Compute post increment SCEV for loop L.
-  const SCEV *PostInc = SCEVPostIncRewriter::rewrite(S, L, *this);
-  assert(PostInc != getCouldNotCompute() && "Unexpected could not compute");
-  return { Start, PostInc };
-}
-
 bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred,
                                        const SCEV *LHS, const SCEV *RHS) {
   // Canonicalize the inputs first.
   (void)SimplifyICmpOperands(Pred, LHS, RHS);
 
-  // We'd like to check the predicate on every iteration of the most dominated
-  // loop between loops used in LHS and RHS.
-  // To do this we use the following list of steps:
-  // 1. Collect set S all loops on which either LHS or RHS depend.
-  // 2. If S is non-empty
-  // a. Let PD be the element of S which is dominated by all other elements of S
-  // b. Let E(LHS) be value of LHS on entry of PD.
-  //    To get E(LHS), we should just take LHS and replace all AddRecs that are
-  //    attached to PD on with their entry values.
-  //    Define E(RHS) in the same way.
-  // c. Let B(LHS) be value of L on backedge of PD.
-  //    To get B(LHS), we should just take LHS and replace all AddRecs that are
-  //    attached to PD on with their backedge values.
-  //    Define B(RHS) in the same way.
-  // d. Note that E(LHS) and E(RHS) are automatically available on entry of PD,
-  //    so we can assert on that.
-  // e. Return true if isLoopEntryGuardedByCond(Pred, E(LHS), E(RHS)) &&
-  //                   isLoopBackedgeGuardedByCond(Pred, B(LHS), B(RHS))
-
-  // First collect all loops.
-  SmallPtrSet<const Loop *, 8> LoopsUsed;
-  getUsedLoops(LHS, LoopsUsed);
-  getUsedLoops(RHS, LoopsUsed);
-
-  // Domination relationship must be a linear order on collected loops.
-#ifndef NDEBUG
-  for (auto *L1 : LoopsUsed)
-    for (auto *L2 : LoopsUsed)
-      assert((DT.dominates(L1->getHeader(), L2->getHeader()) ||
-              DT.dominates(L2->getHeader(), L1->getHeader())) &&
-             "Domination relationship is not a linear order");
-#endif
-  if (!LoopsUsed.empty()) {
-    const Loop *MDL = *std::max_element(LoopsUsed.begin(), LoopsUsed.end(),
-                                        [&](const Loop *L1, const Loop *L2) {
-                         return DT.dominates(L1->getHeader(), L2->getHeader());
-                       });
-
-    // Get init and post increment value for LHS.
-    auto SplitLHS = SplitIntoInitAndPostInc(MDL, LHS);
-    if (SplitLHS.first != getCouldNotCompute()) {
-      // if LHS does not contain unknown non-invariant SCEV then
-      // get init and post increment value for RHS.
-      auto SplitRHS = SplitIntoInitAndPostInc(MDL, RHS);
-      if (SplitRHS.first != getCouldNotCompute()) {
-        // if RHS does not contain unknown non-invariant SCEV then
-        // check whether implication is possible.
-        if (isLoopEntryGuardedByCond(MDL, Pred, SplitLHS.first,
-                                     SplitRHS.first) &&
-            isLoopBackedgeGuardedByCond(MDL, Pred, SplitLHS.second,
-                                        SplitRHS.second))
-          return true;
-      }
+  // If LHS or RHS is an addrec, check to see if the condition is true in
+  // every iteration of the loop.
+  // If LHS and RHS are both addrec, both conditions must be true in
+  // every iteration of the loop.
+  const SCEVAddRecExpr *LAR = dyn_cast<SCEVAddRecExpr>(LHS);
+  const SCEVAddRecExpr *RAR = dyn_cast<SCEVAddRecExpr>(RHS);
+  bool LeftGuarded = false;
+  bool RightGuarded = false;
+  if (LAR) {
+    const Loop *L = LAR->getLoop();
+    if (isAvailableAtLoopEntry(RHS, L) &&
+        isKnownOnEveryIteration(Pred, LAR, RHS)) {
+      if (!RAR) return true;
+      LeftGuarded = true;
+    }
+  }
+  if (RAR) {
+    const Loop *L = RAR->getLoop();
+    auto SwappedPred = ICmpInst::getSwappedPredicate(Pred);
+    if (isAvailableAtLoopEntry(LHS, L) &&
+        isKnownOnEveryIteration(SwappedPred, RAR, LHS)) {
+      if (!LAR) return true;
+      RightGuarded = true;
     }
   }
+  if (LeftGuarded && RightGuarded)
+    return true;
 
   if (isKnownPredicateViaSplitting(Pred, LHS, RHS))
     return true;

Removed: llvm/trunk/test/Transforms/IndVarSimplify/inner-loop-by-latch-cond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/inner-loop-by-latch-cond.ll?rev=327362&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/inner-loop-by-latch-cond.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/inner-loop-by-latch-cond.ll (removed)
@@ -1,33 +0,0 @@
-; RUN: opt < %s -indvars -S | FileCheck %s
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
-target triple = "x86_64-unknown-linux-gnu"
-
-declare void @foo(i64)
-
-define void @test(i64 %a) {
-entry:
-  br label %outer_header
-
-outer_header:
-  %i = phi i64 [20, %entry], [%i.next, %outer_latch]
-  %i.next = add nuw nsw i64 %i, 1
-  br label %inner_header
-
-inner_header:
-  %j = phi i64 [1, %outer_header], [%j.next, %inner_header]
-  %cmp = icmp ult i64 %j, %i.next
-; CHECK-NOT: select
-  %s = select i1 %cmp, i64 %j, i64 %i
-  call void @foo(i64 %s)
-  %j.next = add nuw nsw i64 %j, 1
-  %cond = icmp ult i64 %j, %i
-  br i1 %cond, label %inner_header, label %outer_latch
-
-outer_latch:
-  %cond2 = icmp ne i64 %i.next, 40
-  br i1 %cond2, label %outer_header, label %return
-
-return:
-  ret void
-}




More information about the llvm-commits mailing list