[PATCH] D106331: [ScalarEvolution] Try harder to prove overflow in howManyLessThans.
Eli Friedman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 19 18:24:10 PDT 2021
efriedma created this revision.
efriedma added reviewers: reames, mkazantsev.
Herald added subscribers: javed.absar, hiraditya.
efriedma requested review of this revision.
Herald added a project: LLVM.
If we have an instruction "add nsw (IV - Stride), Stride" feeding into the icmp, we know Start - Stride doesn't overflow.
It's unfortunate we can't deduce this more directly, but we don't really have any SCEV infrastructure to support this sort of check.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D106331
Files:
llvm/include/llvm/Analysis/ScalarEvolution.h
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll
Index: llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll
===================================================================
--- llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll
+++ llvm/test/Analysis/ScalarEvolution/trip-count-unknown-stride.ll
@@ -5,7 +5,7 @@
; that this is not an infinite loop with side effects.
; CHECK-LABEL: Determining loop execution counts for: @foo1
-; CHECK: backedge-taken count is ((-1 + (%n smax %s)) /u %s)
+; CHECK: backedge-taken count is ((-1 + %n) /u %s)
; We should have a conservative estimate for the max backedge taken count for
; loops with unknown stride.
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8108,7 +8108,7 @@
case ICmpInst::ICMP_ULT: { // while (X < Y)
bool IsSigned = Pred == ICmpInst::ICMP_SLT;
ExitLimit EL = howManyLessThans(LHS, RHS, L, IsSigned, ControlsExit,
- AllowPredicates);
+ AllowPredicates, ExitCond);
if (EL.hasAnyInfo()) return EL;
break;
}
@@ -11573,7 +11573,8 @@
ScalarEvolution::ExitLimit
ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
const Loop *L, bool IsSigned,
- bool ControlsExit, bool AllowPredicates) {
+ bool ControlsExit, bool AllowPredicates,
+ ICmpInst *OrigCond) {
SmallPtrSet<const SCEVPredicate *, 4> Predicates;
const SCEVAddRecExpr *IV = dyn_cast<SCEVAddRecExpr>(LHS);
@@ -11765,8 +11766,23 @@
const SCEV *BECount = nullptr;
auto *StartMinusStride = getMinusSCEV(OrigStart, Stride);
// Can we prove (max(RHS,Start) > Start - Stride?
- if (isLoopEntryGuardedByCond(L, Cond, StartMinusStride, Start) &&
- isLoopEntryGuardedByCond(L, Cond, StartMinusStride, RHS)) {
+ if (isLoopEntryGuardedByCond(L, Cond, StartMinusStride, RHS)) {
+ auto MaySubOverflow = [&]() {
+ // Start - Stride < Start implies no overflow.
+ if (isLoopEntryGuardedByCond(L, Cond, StartMinusStride, Start))
+ return false;
+ // Check if we have an IR instruction feeding into the branch
+ // "add nsw IVMinusStride, Stride"
+ if (getSCEV(OrigCond->getOperand(0)) == IV) {
+ if (auto *Add = dyn_cast<AddOperator>(OrigCond->getOperand(0))) {
+ if (IsSigned ? Add->hasNoSignedWrap() : Add->hasNoUnsignedWrap()) {
+ if (getSCEV(Add->getOperand(1)) == Stride)
+ return false;
+ }
+ }
+ }
+ return true;
+ };
// In this case, we can use a refined formula for computing backedge taken
// count. The general formula remains:
// "End-Start /uceiling Stride" where "End = max(RHS,Start)"
@@ -11785,11 +11801,13 @@
// "((RHS - 1) - (Start - Stride)) /u Stride" reassociates to
// "((RHS - (Start - Stride) - 1) /u Stride".
// Our preconditions trivially imply no overflow in that form.
- const SCEV *MinusOne = getMinusOne(Stride->getType());
- const SCEV *Numerator =
- getMinusSCEV(getAddExpr(RHS, MinusOne), StartMinusStride);
- if (!isa<SCEVCouldNotCompute>(Numerator)) {
- BECount = getUDivExpr(Numerator, Stride);
+ if (!MaySubOverflow()) {
+ const SCEV *MinusOne = getMinusOne(Stride->getType());
+ const SCEV *Numerator =
+ getMinusSCEV(getAddExpr(RHS, MinusOne), StartMinusStride);
+ if (!isa<SCEVCouldNotCompute>(Numerator)) {
+ BECount = getUDivExpr(Numerator, Stride);
+ }
}
}
Index: llvm/include/llvm/Analysis/ScalarEvolution.h
===================================================================
--- llvm/include/llvm/Analysis/ScalarEvolution.h
+++ llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1811,7 +1811,7 @@
/// 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);
+ bool AllowPredicates, ICmpInst *OrigCond);
ExitLimit howManyGreaterThans(const SCEV *LHS, const SCEV *RHS, const Loop *L,
bool isSigned, bool IsSubExpr,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106331.359977.patch
Type: text/x-patch
Size: 4461 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210720/6594e30b/attachment.bin>
More information about the llvm-commits
mailing list