summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2014-03-25 16:25:12 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2014-03-25 16:25:12 +0000
commite75eaca32f058d9633438ac7ceebde13d25b8a18 (patch)
tree2311b32c57e512a8e66b428c859ac5169e4962b9 /llvm/lib/Analysis
parentb22426c510cbec2c64e7f1d97f2a63c9a185f812 (diff)
downloadbcm5719-llvm-e75eaca32f058d9633438ac7ceebde13d25b8a18.tar.gz
bcm5719-llvm-e75eaca32f058d9633438ac7ceebde13d25b8a18.zip
ScalarEvolution: Compute exit counts for loops with a power-of-2 step.
If we have a loop of the form for (unsigned n = 0; n != (k & -32); n += 32) {} then we know that n is always divisible by 32 and the loop must terminate. Even if we have a condition where the loop counter will overflow it'll always hold this invariant. PR19183. Our loop vectorizer creates this pattern and it's also occasionally formed by loop counters derived from pointers. llvm-svn: 204728
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 39bf95b92d9..08de6213e22 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5744,6 +5744,16 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L, bool IsSubExpr) {
getUDivExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
return ExitLimit(Exact, Exact, /*MustExit=*/false);
}
+
+ // If Step is a power of two that evenly divides Start we know that the loop
+ // will always terminate. Start may not be a constant so we just have the
+ // number of trailing zeros available. This is safe even in presence of
+ // overflow as the recurrence will overflow to exactly 0.
+ const APInt &StepV = StepC->getValue()->getValue();
+ if (StepV.isPowerOf2() &&
+ GetMinTrailingZeros(getNegativeSCEV(Start)) >= StepV.countTrailingZeros())
+ return getUDivExactExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
+
// Then, try to solve the above equation provided that Start is constant.
if (const SCEVConstant *StartC = dyn_cast<SCEVConstant>(Start))
return SolveLinEquationWithOverflow(StepC->getValue()->getValue(),
OpenPOWER on IntegriCloud