mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-19 02:03:11 +00:00
[SCEV] Make howFarToZero use a simpler formula for max backedge-taken count.
This is both easier to understand, and produces a tighter bound in certain cases. Differential Revision: https://reviews.llvm.org/D28393 llvm-svn: 291701
This commit is contained in:
parent
8069f39125
commit
9136368f80
@ -7206,17 +7206,8 @@ ScalarEvolution::howFarToZero(const SCEV *V, const Loop *L, bool ControlsExit,
|
||||
// 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
|
||||
|
@ -207,3 +207,86 @@ for.cond.i: ; preds = %for.body.i
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user