Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -7206,17 +7206,8 @@ // 1*N = -Start; -1*N = Start (mod 2^BW), so: // N = Distance (as unsigned) if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) { - ConstantRange CR = getUnsignedRange(Start); - const SCEV *MaxBECount; - if (!CountDown && CR.getUnsignedMin().isMinValue()) - // When counting up, the worst starting value is 1, not 0. - MaxBECount = CR.getUnsignedMax().isMinValue() - ? getConstant(APInt::getMinValue(CR.getBitWidth())) - : getConstant(APInt::getMaxValue(CR.getBitWidth())); - else - MaxBECount = getConstant(CountDown ? CR.getUnsignedMax() - : -CR.getUnsignedMin()); - return ExitLimit(Distance, MaxBECount, false, Predicates); + APInt MaxBECount = getUnsignedRange(Distance).getUnsignedMax(); + return ExitLimit(Distance, getConstant(MaxBECount), false, Predicates); } // As a special case, handle the instance where Step is a positive power of Index: test/Analysis/ScalarEvolution/max-trip-count.ll =================================================================== --- test/Analysis/ScalarEvolution/max-trip-count.ll +++ test/Analysis/ScalarEvolution/max-trip-count.ll @@ -207,3 +207,86 @@ bar.exit: ; preds = %for.cond.i, %for.body.i ret i32 0 } + +; CHECK-LABEL: @ne_max_trip_count_1 +; CHECK: Loop %for.body: max backedge-taken count is 7 +define i32 @ne_max_trip_count_1(i32 %n) { +entry: + %masked = and i32 %n, 7 + br label %for.body + +for.body: + %i = phi i32 [ 0, %entry ], [ %add, %for.body ] + %add = add nsw i32 %i, 1 + %cmp = icmp ne i32 %i, %masked + br i1 %cmp, label %for.body, label %bar.exit + +bar.exit: + ret i32 0 +} + +; CHECK-LABEL: @ne_max_trip_count_2 +; CHECK: Loop %for.body: max backedge-taken count is -1 +define i32 @ne_max_trip_count_2(i32 %n) { +entry: + %masked = and i32 %n, 7 + br label %for.body + +for.body: + %i = phi i32 [ 0, %entry ], [ %add, %for.body ] + %add = add nsw i32 %i, 1 + %cmp = icmp ne i32 %add, %masked + br i1 %cmp, label %for.body, label %bar.exit + +bar.exit: + ret i32 0 +} + +; TODO: Improve count based on guard. +; CHECK-LABEL: @ne_max_trip_count_3 +; CHECK: Loop %for.body: max backedge-taken count is -1 +define i32 @ne_max_trip_count_3(i32 %n) { +entry: + %masked = and i32 %n, 7 + %guard = icmp eq i32 %masked, 0 + br i1 %guard, label %exit, label %for.preheader + +for.preheader: + br label %for.body + +for.body: + %i = phi i32 [ 0, %for.preheader ], [ %add, %for.body ] + %add = add nsw i32 %i, 1 + %cmp = icmp ne i32 %add, %masked + br i1 %cmp, label %for.body, label %loop.exit + +loop.exit: + br label %exit + +exit: + ret i32 0 +} + +; TODO: Improve count based on guard. +; CHECK-LABEL: @ne_max_trip_count_4 +; CHECK: Loop %for.body: max backedge-taken count is -1 +define i32 @ne_max_trip_count_4(i32 %n) { +entry: + %guard = icmp eq i32 %n, 0 + br i1 %guard, label %exit, label %for.preheader + +for.preheader: + br label %for.body + +for.body: + %i = phi i32 [ 0, %for.preheader ], [ %add, %for.body ] + %add = add nsw i32 %i, 1 + %cmp = icmp ne i32 %add, %n + br i1 %cmp, label %for.body, label %loop.exit + +loop.exit: + br label %exit + +exit: + ret i32 0 +}