[PATCH] D91126: [SCEV] Generalize no-self-wrap check in isLoopInvariantExitCondDuringFirstIterations

Max Kazantsev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 10 20:38:07 PST 2020


This revision was automatically updated to reflect the committed changes.
Closed by commit rG7dcc8899174f: [SCEV] Generalize no-self-wrap check in isLoopInvariantExitCondDuringFirstItera… (authored by mkazantsev).

Changed prior to commit:
  https://reviews.llvm.org/D91126?vs=304057&id=304386#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91126/new/

https://reviews.llvm.org/D91126

Files:
  llvm/lib/Analysis/ScalarEvolution.cpp


Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -9589,17 +9589,19 @@
   if (!ICmpInst::isRelational(Pred))
     return false;
 
-  // TODO: Support steps other than +/- 1.
   const SCEV *Step = AR->getStepRecurrence(*this);
-  auto *One = getOne(Step->getType());
-  auto *MinusOne = getNegativeSCEV(One);
-  if (Step != One && Step != MinusOne)
+  bool IsStepNonPositive = isKnownNonPositive(Step);
+  if (!IsStepNonPositive && !isKnownNonNegative(Step))
     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())
+  bool HasNoSelfWrap = AR->hasNoSelfWrap();
+  if (!HasNoSelfWrap)
+    // If num iter has same type as the AddRec, and step is +/- 1, even max
+    // possible number of iterations is not enough to self-wrap.
+    if (MaxIter->getType() == AR->getType())
+      if (Step == getOne(AR->getType()) || Step == getMinusOne(AR->getType()))
+        HasNoSelfWrap = true;
+  // Only proceed with non-self-wrapping ARs.
+  if (!HasNoSelfWrap)
     return false;
 
   // Value of IV on suggested last iteration.
@@ -9607,14 +9609,13 @@
   // 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.
+  // We know that the addrec does not have a self-wrap. To prove that there is
+  // no signed/unsigned wrap, we need to check that
+  // Start <= Last for positive step or Start >= Last for negative step. Either
+  // works for zero step.
   ICmpInst::Predicate NoOverflowPred =
       CmpInst::isSigned(Pred) ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
-  if (Step == MinusOne)
+  if (IsStepNonPositive)
     NoOverflowPred = CmpInst::getSwappedPredicate(NoOverflowPred);
   const SCEV *Start = AR->getStart();
   if (!isKnownPredicateAt(NoOverflowPred, Start, Last, Context))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91126.304386.patch
Type: text/x-patch
Size: 2408 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201111/8cfaebab/attachment.bin>


More information about the llvm-commits mailing list