// 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
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
+}