forked from OSchip/llvm-project
[SCEV] Make howFarToZero max backedge-taken count check for precondition.
Refines max backedge-taken count if a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated. Differential Revision: https://reviews.llvm.org/D28536 llvm-svn: 291704
This commit is contained in:
parent
de0f50886f
commit
bd6dedaa7f
|
@ -7207,6 +7207,23 @@ ScalarEvolution::howFarToZero(const SCEV *V, const Loop *L, bool ControlsExit,
|
||||||
// N = Distance (as unsigned)
|
// N = Distance (as unsigned)
|
||||||
if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) {
|
if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) {
|
||||||
APInt MaxBECount = getUnsignedRange(Distance).getUnsignedMax();
|
APInt MaxBECount = getUnsignedRange(Distance).getUnsignedMax();
|
||||||
|
|
||||||
|
// When a loop like "for (int i = 0; i != n; ++i) { /* body */ }" is rotated,
|
||||||
|
// we end up with a loop whose backedge-taken count is n - 1. Detect this
|
||||||
|
// case, and see if we can improve the bound.
|
||||||
|
//
|
||||||
|
// Explicitly handling this here is necessary because getUnsignedRange
|
||||||
|
// isn't context-sensitive; it doesn't know that we only care about the
|
||||||
|
// range inside the loop.
|
||||||
|
const SCEV *Zero = getZero(Distance->getType());
|
||||||
|
const SCEV *One = getOne(Distance->getType());
|
||||||
|
const SCEV *DistancePlusOne = getAddExpr(Distance, One);
|
||||||
|
if (isLoopEntryGuardedByCond(L, ICmpInst::ICMP_NE, DistancePlusOne, Zero)) {
|
||||||
|
// If Distance + 1 doesn't overflow, we can compute the maximum distance
|
||||||
|
// as "unsigned_max(Distance + 1) - 1".
|
||||||
|
ConstantRange CR = getUnsignedRange(DistancePlusOne);
|
||||||
|
MaxBECount = APIntOps::umin(MaxBECount, CR.getUnsignedMax() - 1);
|
||||||
|
}
|
||||||
return ExitLimit(Distance, getConstant(MaxBECount), false, Predicates);
|
return ExitLimit(Distance, getConstant(MaxBECount), false, Predicates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -242,9 +242,8 @@ bar.exit:
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
; TODO: Improve count based on guard.
|
|
||||||
; CHECK-LABEL: @ne_max_trip_count_3
|
; CHECK-LABEL: @ne_max_trip_count_3
|
||||||
; CHECK: Loop %for.body: max backedge-taken count is -1
|
; CHECK: Loop %for.body: max backedge-taken count is 6
|
||||||
define i32 @ne_max_trip_count_3(i32 %n) {
|
define i32 @ne_max_trip_count_3(i32 %n) {
|
||||||
entry:
|
entry:
|
||||||
%masked = and i32 %n, 7
|
%masked = and i32 %n, 7
|
||||||
|
@ -267,9 +266,8 @@ exit:
|
||||||
ret i32 0
|
ret i32 0
|
||||||
}
|
}
|
||||||
|
|
||||||
; TODO: Improve count based on guard.
|
|
||||||
; CHECK-LABEL: @ne_max_trip_count_4
|
; CHECK-LABEL: @ne_max_trip_count_4
|
||||||
; CHECK: Loop %for.body: max backedge-taken count is -1
|
; CHECK: Loop %for.body: max backedge-taken count is -2
|
||||||
define i32 @ne_max_trip_count_4(i32 %n) {
|
define i32 @ne_max_trip_count_4(i32 %n) {
|
||||||
entry:
|
entry:
|
||||||
%guard = icmp eq i32 %n, 0
|
%guard = icmp eq i32 %n, 0
|
||||||
|
|
Loading…
Reference in New Issue