Index: include/llvm/Analysis/ScalarEvolution.h =================================================================== --- include/llvm/Analysis/ScalarEvolution.h +++ include/llvm/Analysis/ScalarEvolution.h @@ -1838,7 +1838,7 @@ /// assert these preconditions so please be careful. const SCEV *computeMaxBECountForLT(const SCEV *Start, const SCEV *Stride, const SCEV *End, unsigned BitWidth, - bool IsSigned); + bool IsSigned, const Loop *L); /// Verify if an linear IV with positive stride can overflow when in a /// less-than comparison, knowing the invariant term of the comparison, Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -10434,8 +10434,8 @@ const SCEV *Stride, const SCEV *End, unsigned BitWidth, - bool IsSigned) { - + bool IsSigned, + const Loop *L) { assert(!isKnownNonPositive(Stride) && "Stride is expected strictly positive!"); // Calculate the maximum backedge count based on the range of values @@ -10444,6 +10444,14 @@ APInt MinStart = IsSigned ? getSignedRangeMin(Start) : getUnsignedRangeMin(Start); + // If loop entry is guarded by an ULT, with a constant Stride, we know + // (Start-Stride) is in [0, End). + auto *S = getMinusSCEV(Start, Stride); + if (!IsSigned && isa(Stride) && isLoopInvariant(End, L) && + isLoopEntryGuardedByCond(L, ICmpInst::ICMP_ULT, S, End)) + MinStart = getUnsignedRangeMin(S) + + dyn_cast(Stride)->getAPInt(); + APInt StrideForMaxBECount = IsSigned ? getSignedRangeMin(Stride) : getUnsignedRangeMin(Stride); @@ -10567,7 +10575,7 @@ // checked above). if (!isLoopInvariant(RHS, L)) { const SCEV *MaxBECount = computeMaxBECountForLT( - Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned); + Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned, L); return ExitLimit(getCouldNotCompute() /* ExactNotTaken */, MaxBECount, false /*MaxOrZero*/, Predicates); } @@ -10604,7 +10612,7 @@ MaxOrZero = true; } else { MaxBECount = computeMaxBECountForLT( - Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned); + Start, Stride, RHS, getTypeSizeInBits(LHS->getType()), IsSigned, L); } if (isa(MaxBECount) && Index: test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll =================================================================== --- test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll +++ test/Analysis/ScalarEvolution/2008-11-18-Stride2.ll @@ -1,7 +1,7 @@ ; RUN: opt < %s -analyze -scalar-evolution 2>&1 | FileCheck %s ; CHECK: Loop %bb: backedge-taken count is ((999 + (-1 * %x)) /u 3) -; CHECK: Loop %bb: max backedge-taken count is 334 +; CHECK: Loop %bb: max backedge-taken count is 333 ; This is a tricky testcase for unsigned wrap detection which ScalarEvolution