[NFC][ScalarEvolution] Cleanup howManyLessThans.

In preparation for D104075. Some NFC cleanup, and some test coverage for
planned changes.
This commit is contained in:
Eli Friedman 2021-07-08 17:49:02 -07:00
parent 70eb3bfff0
commit 009436e9c1
5 changed files with 72 additions and 14 deletions

View File

@ -1791,7 +1791,7 @@ private:
/// less-than comparison will execute. If not computable, return
/// CouldNotCompute.
///
/// \p isSigned specifies whether the less-than is signed.
/// \p Pred specifies the kind of less-than comparison.
///
/// \p ControlsExit is true when the LHS < RHS condition directly controls
/// the branch (loops exits only if condition is true). In this case, we can
@ -1800,12 +1800,12 @@ private:
/// If \p AllowPredicates is set, this call will try to use a minimal set of
/// SCEV predicates in order to return an exact answer.
ExitLimit howManyLessThans(const SCEV *LHS, const SCEV *RHS, const Loop *L,
bool isSigned, bool ControlsExit,
bool AllowPredicates = false);
ICmpInst::Predicate Pred, bool ControlsExit,
bool AllowPredicates);
ExitLimit howManyGreaterThans(const SCEV *LHS, const SCEV *RHS, const Loop *L,
bool isSigned, bool IsSubExpr,
bool AllowPredicates = false);
bool AllowPredicates);
/// Return a predecessor of BB (which may not be an immediate predecessor)
/// which has exactly one successor from which BB is reachable, or null if

View File

@ -8091,9 +8091,8 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
}
case ICmpInst::ICMP_SLT:
case ICmpInst::ICMP_ULT: { // while (X < Y)
bool IsSigned = Pred == ICmpInst::ICMP_SLT;
ExitLimit EL = howManyLessThans(LHS, RHS, L, IsSigned, ControlsExit,
AllowPredicates);
ExitLimit EL =
howManyLessThans(LHS, RHS, L, Pred, ControlsExit, AllowPredicates);
if (EL.hasAnyInfo()) return EL;
break;
}
@ -11645,10 +11644,13 @@ const SCEV *ScalarEvolution::computeMaxBECountForLT(const SCEV *Start,
ScalarEvolution::ExitLimit
ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool IsSigned,
const Loop *L, ICmpInst::Predicate Pred,
bool ControlsExit, bool AllowPredicates) {
SmallPtrSet<const SCEVPredicate *, 4> Predicates;
assert(ICmpInst::isLT(Pred) && "Unexpected pred");
bool IsSigned = ICmpInst::isSigned(Pred);
const SCEVAddRecExpr *IV = dyn_cast<SCEVAddRecExpr>(LHS);
bool PredicatedIV = false;
@ -11666,7 +11668,6 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
auto WrapType = IsSigned ? SCEV::FlagNSW : SCEV::FlagNUW;
bool NoWrap = ControlsExit && IV->getNoWrapFlags(WrapType);
ICmpInst::Predicate Cond = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
const SCEV *Stride = IV->getStepRecurrence(*this);
@ -11779,7 +11780,6 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
return RHS;
}
const SCEV *End = RHS;
// When the RHS is not invariant, we do not know the end bound of the loop and
// cannot calculate the ExactBECount needed by ExitLimit. However, we can
// calculate the MaxBECount, given the start, stride and max value for the end
@ -11796,7 +11796,7 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
// is the LHS value of the less-than comparison the first time it is evaluated
// and End is the RHS.
const SCEV *BECountIfBackedgeTaken =
computeBECount(IsSigned, Start, End, Stride);
computeBECount(IsSigned, Start, RHS, Stride);
// If the loop entry is guarded by the result of the backedge test of the
// first loop iteration, then we know the backedge will be taken at least
// once and so the backedge taken count is as above. If not then we use the
@ -11805,13 +11805,15 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
// result is as above, and if not max(End,Start) is Start so we get a backedge
// count of zero.
const SCEV *BECount;
if (isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(OrigStart, Stride), OrigRHS))
if (isLoopEntryGuardedByCond(L, Pred, getMinusSCEV(OrigStart, Stride),
OrigRHS))
BECount = BECountIfBackedgeTaken;
else {
const SCEV *End;
// If we know that RHS >= Start in the context of loop, then we know that
// max(RHS, Start) = RHS at this point.
if (isLoopEntryGuardedByCond(
L, IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, OrigRHS, OrigStart))
if (isLoopEntryGuardedByCond(L, ICmpInst::getInversePredicate(Pred),
OrigRHS, OrigStart))
End = RHS;
else
End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);

View File

@ -27,6 +27,8 @@ target triple = "x86_64-unknown-linux-gnu"
; CHECK: Loop %for.body: Unpredictable backedge-taken count.
; CHECK: Determining loop execution counts for: @test_other_exit
; CHECK: Loop %for.body: <multiple exits> Unpredictable backedge-taken count.
; CHECK: Determining loop execution counts for: @test_gt
; CHECK: Loop %for.body: Unpredictable backedge-taken count.
define void @test(i32 %N) mustprogress {
entry:
@ -184,4 +186,16 @@ for.cond.cleanup:
ret void
}
define void @test_gt(i32 %S, i32 %N) mustprogress {
entry:
br label %for.body
for.body:
%iv = phi i32 [ %iv.next, %for.body ], [ %S, %entry ]
%iv.next = add i32 %iv, -2
%cmp = icmp ugt i32 %iv.next, %N
br i1 %cmp, label %for.body, label %for.cond.cleanup
for.cond.cleanup:
ret void
}

View File

@ -432,3 +432,26 @@ loop:
loop.exit:
ret void
}
; sgt with negative stride
define void @changing_end_bound7(i32 %start, i32* %n_addr, i32* %addr) {
; CHECK-LABEL: Determining loop execution counts for: @changing_end_bound7
; CHECK: Loop %loop: Unpredictable backedge-taken count.
; CHECK: Loop %loop: Unpredictable max backedge-taken count.
entry:
br label %loop
loop:
%iv = phi i32 [ %start, %entry ], [ %iv.next, %loop ]
%acc = phi i32 [ 0, %entry ], [ %acc.next, %loop ]
%val = load atomic i32, i32* %addr unordered, align 4
fence acquire
%acc.next = add i32 %acc, %val
%iv.next = add i32 %iv, -1
%n = load atomic i32, i32* %n_addr unordered, align 4
%cmp = icmp sgt i32 %iv.next, %n
br i1 %cmp, label %loop, label %loop.exit
loop.exit:
ret void
}

View File

@ -80,3 +80,22 @@ loop:
leave:
ret void
}
define void @s_2(i8 %start) {
entry:
%rhs = add i8 %start, -100
br label %loop
loop:
%iv = phi i8 [ %start, %entry ], [ %iv.inc, %loop ]
%iv.inc = add nsw i8 %iv, -1
%iv.cmp = icmp sgt i8 %iv, %rhs
br i1 %iv.cmp, label %loop, label %leave
; CHECK-LABEL: Determining loop execution counts for: @s_2
; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * ((-100 + %start) smin %start)) + %start)
; CHECK-NEXT: Loop %loop: max backedge-taken count is -1
leave:
ret void
}