[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