[PATCH] D91126: [SCEV] Generalize no-self-wrap check in isLoopInvariantExitCondDuringFirstIterations
Max Kazantsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 9 23:15:44 PST 2020
mkazantsev created this revision.
mkazantsev added reviewers: apilipenko, ebrevnov, fhahn.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
mkazantsev requested review of this revision.
Lift limitation on step being `+/- 1`. In fact, the only thing it is needed for
is proving no-self-wrap. We can instead check this flag directly.
Theoretically it can increase the scope of the transform, but I could not
construct such test easily.
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
@@ -9585,17 +9585,20 @@
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 IsStepNonNegative = isKnownNonNegative(Step);
+ bool IsStepNonPositive = isKnownNonPositive(Step);
+ if (!IsStepNonNegative && !IsStepNonPositive)
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.
@@ -9603,14 +9606,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.304057.patch
Type: text/x-patch
Size: 2455 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201110/d351bc18/attachment.bin>
More information about the llvm-commits
mailing list