[PATCH] D109029: [SCEV] Clarify requirements for zero-stride to be UB

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 31 15:23:03 PDT 2021


reames created this revision.
reames added reviewers: efriedma, nikic, lifted, fhahn.
Herald added subscribers: bollu, hiraditya, mcrosier.
reames requested review of this revision.
Herald added a project: LLVM.

There's a silent bug in our reasoning about zero strides.  We assume that having a single static exit implies that if that exit is not taken, then the loop must be infinite.  This ignores the potential for abnormal exits via exceptions.  Consider the following example:
for (uint_8 i = 0; i < 1; i += 0) {

  throw_on_thousandth_call();

}

Our reasoning is such that we'd conclude this loop can't take the backedge as that would lead to a (presumed) infinite loop.

In practice, this is a silent bug because the loopIsFiniteByAssumption returns false strictly more often than the loopHaNoAbnormalExits property.  We could reasonable want to change that in the future, so fixing the codeflow now is worthwhile.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D109029

Files:
  llvm/lib/Analysis/ScalarEvolution.cpp


Index: llvm/lib/Analysis/ScalarEvolution.cpp
===================================================================
--- llvm/lib/Analysis/ScalarEvolution.cpp
+++ llvm/lib/Analysis/ScalarEvolution.cpp
@@ -11627,13 +11627,15 @@
     // a) IV is either nuw or nsw depending upon signedness (indicated by the
     //    NoWrap flag).
     // b) loop is single exit with no side effects.
+    // c) loop has no abnormal exits
     //
     //
     // Precondition a) implies that if the stride is negative, this is a single
     // trip loop. The backedge taken count formula reduces to zero in this case.
     //
-    // Precondition b) implies that if rhs is invariant in L, then unknown
-    // stride being zero means the backedge can't be taken without UB.
+    // Precondition b) and c) combine to imply that if rhs is invariant in L,
+    // then a zero stride means the backedge can't be taken without executing
+    // undefined behavior.
     //
     // The positive stride case is the same as isKnownPositive(Stride) returning
     // true (original behavior of the function).
@@ -11651,7 +11653,7 @@
     //   A[i] = i;
     //
     if (PredicatedIV || !NoWrap || isKnownNonPositive(Stride) ||
-        !loopIsFiniteByAssumption(L))
+        !loopIsFiniteByAssumption(L) || !loopHasNoAbnormalExits(L))
       return getCouldNotCompute();
 
     if (!isKnownNonZero(Stride)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109029.369806.patch
Type: text/x-patch
Size: 1379 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210831/da291197/attachment.bin>


More information about the llvm-commits mailing list