diff options
| author | Mark Heffernan <meheff@google.com> | 2014-12-10 22:53:52 +0000 |
|---|---|---|
| committer | Mark Heffernan <meheff@google.com> | 2014-12-10 22:53:52 +0000 |
| commit | 41d7656d5a7a41b95af7a3c6a1e13f5a4571c2b9 (patch) | |
| tree | 24f97d0a539dd0ce60f20a3d884752665c697102 /llvm/lib/Analysis | |
| parent | 2325e38024d095b9780e709cc8ca134aab1941fb (diff) | |
| download | bcm5719-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.cpp | 18 |
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 |

