forked from OSchip/llvm-project
[NFC][ScalarEvolution] Cleanup howManyLessThans.
In preparation for D104075. Some NFC cleanup, and some test coverage for planned changes.
This commit is contained in:
parent
70eb3bfff0
commit
009436e9c1
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue