[PATCH] D106197: [ScalarEvolution] Refine computeMaxBECountForLT to be accurate in more cases.
Eli Friedman via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 16 16:26:23 PDT 2021
efriedma created this revision.
efriedma added reviewers: reames, mkazantsev, nikic, fhahn.
Herald added a subscriber: hiraditya.
efriedma requested review of this revision.
Herald added a project: LLVM.
Allow arbitrary strides, and make sure we return the correct result when the backedge-taken count is zero.
Inspired by D104140 <https://reviews.llvm.org/D104140>.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D106197
Files:
llvm/lib/Analysis/ScalarEvolution.cpp
llvm/test/Analysis/ScalarEvolution/max-trip-count.ll
Index: llvm/test/Analysis/ScalarEvolution/max-trip-count.ll
===================================================================
--- llvm/test/Analysis/ScalarEvolution/max-trip-count.ll
+++ llvm/test/Analysis/ScalarEvolution/max-trip-count.ll
@@ -455,3 +455,20 @@
loop.exit:
ret void
}
+
+define void @max_overflow(i8 %n) mustprogress {
+; CHECK-LABEL: Determining loop execution counts for: @max_overflow
+; CHECK: Loop %loop: backedge-taken count is (-126 + (126 smax %n))<nsw>
+; CHECK: Loop %loop: max backedge-taken count is 0
+entry:
+ br label %loop
+
+loop:
+ %i = phi i8 [ 63, %entry ], [ %i.next, %loop ]
+ %i.next = add nsw i8 %i, 63
+ %t = icmp slt i8 %i.next, %n
+ br i1 %t, label %loop, label %exit
+
+exit:
+ ret void
+}
Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -11533,9 +11533,11 @@
const SCEV *End,
unsigned BitWidth,
bool IsSigned) {
+ // The logic in this function assumes we can represent a positive stride.
+ // If we can't, the backedge-taken count must be zero.
+ if (IsSigned && BitWidth == 1)
+ return getZero(Stride->getType());
- assert(!isKnownNonPositive(Stride) &&
- "Stride is expected strictly positive!");
// Calculate the maximum backedge count based on the range of values
// permitted by Start, End, and Stride.
const SCEV *MaxBECount;
@@ -11545,13 +11547,11 @@
APInt StrideForMaxBECount =
IsSigned ? getSignedRangeMin(Stride) : getUnsignedRangeMin(Stride);
- // We already know that the stride is positive, so we paper over conservatism
- // in our range computation by forcing StrideForMaxBECount to be at least one.
- // In theory this is unnecessary, but we expect MaxBECount to be a
- // SCEVConstant, and (udiv <constant> 0) is not constant folded by SCEV (there
- // is nothing to constant fold it to).
- APInt One(BitWidth, 1, IsSigned);
- StrideForMaxBECount = APIntOps::smax(One, StrideForMaxBECount);
+ // We assume either the stride is positive, or the backedge-taken count
+ // is zero. So force StrideForMaxBECount to be at least one.
+ APInt One(BitWidth, 1);
+ StrideForMaxBECount = IsSigned ? APIntOps::smax(One, StrideForMaxBECount)
+ : APIntOps::umax(One, StrideForMaxBECount);
APInt MaxValue = IsSigned ? APInt::getSignedMaxValue(BitWidth)
: APInt::getMaxValue(BitWidth);
@@ -11564,6 +11564,10 @@
APInt MaxEnd = IsSigned ? APIntOps::smin(getSignedRangeMax(End), Limit)
: APIntOps::umin(getUnsignedRangeMax(End), Limit);
+ // MaxBECount = ceil((max(MaxEnd, MinStart) - MinStart) / Stride)
+ MaxEnd = IsSigned ? APIntOps::smax(MaxEnd, MinStart)
+ : APIntOps::umax(MaxEnd, MinStart);
+
MaxBECount = getUDivCeilSCEV(getConstant(MaxEnd - MinStart) /* Delta */,
getConstant(StrideForMaxBECount) /* Step */);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106197.359477.patch
Type: text/x-patch
Size: 3191 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210716/582b851c/attachment.bin>
More information about the llvm-commits
mailing list