[llvm] r223974 - 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.
Mark Heffernan
meheff at google.com
Wed Dec 10 14:53:53 PST 2014
Author: meheff
Date: Wed Dec 10 16:53:52 2014
New Revision: 223974
URL: http://llvm.org/viewvc/llvm-project?rev=223974&view=rev
Log:
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.
Modified:
llvm/trunk/lib/Analysis/ScalarEvolution.cpp
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=223974&r1=223973&r2=223974&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Dec 10 16:53:52 2014
@@ -6161,16 +6161,14 @@ ScalarEvolution::HowFarToZero(const SCEV
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
More information about the llvm-commits
mailing list