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
This commit is contained in:
Mark Heffernan 2014-12-10 22:53:52 +00:00
parent 2325e38024
commit 41d7656d5a
1 changed files with 8 additions and 10 deletions

View File

@ -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