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 @@ -10465,8 +10465,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 @@ -10475,6 +10475,34 @@ APInt MinStart = IsSigned ? getSignedRangeMin(Start) : getUnsignedRangeMin(Start); + // For this loop: + // entry: + // %x = load i32, i32* @global, align 4 + // %0 = icmp ult i32 %x, 17 + // br i1 %0, label %loop, label %exit + // + // loop: + // %iv = phi i32 [ %x, %entry ], [ %iv.next, %loop ] + // %iv.next = add nuw i32 %iv, 8 + // %1 = icmp ult i32 %iv.next, 17 + // br i1 %1, label %loop, label %exit + // + // exit: + // ret void + // + // Start is (%x + 8), Stride is 8, End is 17. Given that loop entry is guarded + // by ult %x, 17, we know %x is in [0, 17) if loop is entered, and min start + // shall be 8. + auto *S = getMinusSCEV(Start, Stride); + if (!IsSigned && isa(Stride) && isLoopInvariant(End, L) && + // Prove that (Start - Stride) is in [0, End) + isLoopEntryGuardedByCond(L, ICmpInst::ICMP_ULT, S, End) && + // Prove that (Start - Stride) doesn't overflow. + isKnownNonNegative(Stride) && isKnownNonNegative(End)) + // Compute MinStart as getUnsignedRangeMin(Start-Stride) + Stride. + MinStart = getUnsignedRangeMin(S) + + dyn_cast(Stride)->getAPInt(); + APInt StrideForMaxBECount = IsSigned ? getSignedRangeMin(Stride) : getUnsignedRangeMin(Stride); @@ -10598,7 +10626,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); } @@ -10635,7 +10663,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