Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -11534,6 +11534,12 @@ if (IsSigned && BitWidth == 1) return getZero(Stride->getType()); + // This code has only been closely audited for negative strides in the + // unsigned comparison case, it may be correct for signed comparison, but + // that needs to be established. + assert((!IsSigned || !isKnownNonPositive(Stride)) && + "Stride is expected strictly positive for signed case!"); + // Calculate the maximum backedge count based on the range of values // permitted by Start, End, and Stride. APInt MinStart = @@ -11640,20 +11646,15 @@ // The positive stride case is the same as isKnownPositive(Stride) returning // true (original behavior of the function). // - // We want to make sure that the stride is truly unknown as there are edge - // cases where ScalarEvolution propagates no wrap flags to the - // post-increment/decrement IV even though the increment/decrement operation - // itself is wrapping. The computed backedge taken count may be wrong in - // such cases. This is prevented by checking that the stride is not known to - // be either positive or non-positive. For example, no wrap flags are - // propagated to the post-increment IV of this loop with a trip count of 2 - - // - // unsigned char i; - // for(i=127; i<128; i+=129) - // A[i] = i; - // - if (PredicatedIV || !NoWrap || isKnownNonPositive(Stride) || - !loopIsFiniteByAssumption(L) || !loopHasNoAbnormalExits(L)) + if (PredicatedIV || !NoWrap || !loopIsFiniteByAssumption(L) || + !loopHasNoAbnormalExits(L)) + return getCouldNotCompute(); + + // This bailout is protecting the logic in computeMaxBECountForLT which + // has not yet been sufficiently auditted or tested with negative strides. + // We used to filter out all known-non-positive cases here, we're in the + // process of being less restrictive bit by bit. + if (IsSigned && isKnownNonPositive(Stride)) return getCouldNotCompute(); if (!isKnownNonZero(Stride)) { Index: llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll =================================================================== --- llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll +++ llvm/test/Analysis/ScalarEvolution/trip-count-negative-stride.ll @@ -85,8 +85,8 @@ } ; CHECK-LABEL: Determining loop execution counts for: @ult_129_unknown_start -; CHECK: Loop %for.body: Unpredictable backedge-taken count -; CHECK: Loop %for.body: Unpredictable max backedge-taken count +; CHECK: Loop %for.body: backedge-taken count is (((127 + (-1 * (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) + (-1 * %start) + (-128 umax (-127 + %start))) /u -127) + (1 umin (127 + (-1 * %start) + (-128 umax (-127 + %start))))) +; CHECK: Loop %for.body: max backedge-taken count is 1 define void @ult_129_unknown_start(i8 %start) mustprogress { entry: