mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223974 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b1fac191b2
commit
1e9d355499
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user