From: Mark Heffernan Date: Wed, 10 Dec 2014 22:53:52 +0000 (+0000) Subject: Fix PR21694. r219517 added a use of SCEV divide in HowFarToZero computation. This... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=1e9d355499a77370b1eb1ee02e0c916ff46ab4f2;p=oota-llvm.git 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 --- diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 177bd23030a..a06cfc101b3 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/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(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