/// 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
/// 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
}
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;
}
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;
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);
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
// 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
// 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);
; 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:
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
+}
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
+}
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
+}