summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorMark Heffernan <meheff@google.com>2014-12-10 22:53:52 +0000
committerMark Heffernan <meheff@google.com>2014-12-10 22:53:52 +0000
commit41d7656d5a7a41b95af7a3c6a1e13f5a4571c2b9 (patch)
tree24f97d0a539dd0ce60f20a3d884752665c697102 /llvm/lib/Analysis
parent2325e38024d095b9780e709cc8ca134aab1941fb (diff)
downloadbcm5719-llvm-41d7656d5a7a41b95af7a3c6a1e13f5a4571c2b9.tar.gz
bcm5719-llvm-41d7656d5a7a41b95af7a3c6a1e13f5a4571c2b9.zip
Fix PR21694. r219517 added a use of SCEV divide in HowFarToZero computation. This divide can produce incorrect results as we are using an unsigned divide for what should be a modular divide. This change reverts back to a more conservative computation using trailing zeros.
llvm-svn: 223974
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp18
1 files changed, 8 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 177bd23030a..a06cfc101b3 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -6161,16 +6161,14 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L, bool ControlsExit) {
return ExitLimit(Distance, MaxBECount);
}
- // If the step exactly divides the distance then unsigned divide computes the
- // backedge count.
- const SCEV *Q, *R;
- ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this);
- SCEVUDivision::divide(SE, Distance, Step, &Q, &R);
- if (R->isZero()) {
- const SCEV *Exact =
- getUDivExactExpr(Distance, CountDown ? getNegativeSCEV(Step) : Step);
- return ExitLimit(Exact, Exact);
- }
+ // 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);
// If the condition controls loop exit (the loop exits only if the expression
// is true) and the addition is no-wrap we can use unsigned divide to
OpenPOWER on IntegriCloud