[llvm] r272181 - [SCEV] Track no-abnormal-exits instead of no-throw calls

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 8 10:48:43 PDT 2016


Author: sanjoy
Date: Wed Jun  8 12:48:42 2016
New Revision: 272181

URL: http://llvm.org/viewvc/llvm-project?rev=272181&view=rev
Log:
[SCEV] Track no-abnormal-exits instead of no-throw calls

Absence of may-unwind calls is not enough to guarantee that a
UB-generating use of an add-rec poison in the loop latch will actually
cause UB.  We also need to guard against calls that terminate the thread
or infinite loop themselves.

This partially addresses PR28012.

Modified:
    llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp
    llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=272181&r1=272180&r2=272181&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Wed Jun  8 12:48:42 2016
@@ -782,8 +782,12 @@ namespace llvm {
         LoopDispositions;
 
     /// A cache of the predicate "does the given loop contain an instruction
-    /// that can throw?"
-    DenseMap<const Loop *, bool> LoopMayThrow;
+    /// that can abnormally exit the loop (i.e. via throwing an exception, by
+    /// terminating the thread cleanly or by infinite looping in a called
+    /// function)?"  The last one is strictly not leaving the loop, but is
+    /// identical to leaving the loop from the viewpoint of reasoning about
+    /// undefined behavior.
+    DenseMap<const Loop *, bool> LoopHasAbnormalExit;
 
     /// Compute a LoopDisposition value.
     LoopDisposition computeLoopDisposition(const SCEV *S, const Loop *L);

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=272181&r1=272180&r2=272181&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Jun  8 12:48:42 2016
@@ -4909,19 +4909,19 @@ bool ScalarEvolution::isAddRecNeverPoiso
   if (!LatchControlDependentOnPoison)
     return false;
 
-  // Now check if loop is no-throw, and cache the information.  In the future,
-  // we can consider commoning this logic with LICMSafetyInfo into a separate
-  // analysis pass.
-
-  auto Itr = LoopMayThrow.find(L);
-  if (Itr == LoopMayThrow.end()) {
-    bool MayThrow = false;
+  // Now check if loop has abonormal exits (or not), and cache the information.
+
+  auto Itr = LoopHasAbnormalExit.find(L);
+  if (Itr == LoopHasAbnormalExit.end()) {
+    bool HasAbnormalExit = false;
     for (auto *BB : L->getBlocks()) {
-      MayThrow = any_of(*BB, [](Instruction &I) { return I.mayThrow(); });
-      if (MayThrow)
+      HasAbnormalExit = any_of(*BB, [](Instruction &I) {
+        return !isGuaranteedToTransferExecutionToSuccessor(&I);
+      });
+      if (HasAbnormalExit)
         break;
     }
-    auto InsertPair = LoopMayThrow.insert({L, MayThrow});
+    auto InsertPair = LoopHasAbnormalExit.insert({L, HasAbnormalExit});
     assert(InsertPair.second && "We just checked!");
     Itr = InsertPair.first;
   }
@@ -5490,7 +5490,7 @@ void ScalarEvolution::forgetLoop(const L
   for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
     forgetLoop(*I);
 
-  LoopMayThrow.erase(L);
+  LoopHasAbnormalExit.erase(L);
 }
 
 void ScalarEvolution::forgetValue(Value *V) {

Modified: llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll?rev=272181&r1=272180&r2=272181&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/nsw.ll Wed Jun  8 12:48:42 2016
@@ -240,3 +240,23 @@ loop:
 leave:
   ret void
 }
+
+declare void @may_exit() nounwind
+
+define void @pr28012(i32 %n) {
+; CHECK-LABEL: Classifying expressions for: @pr28012
+entry:
+  br label %loop
+
+loop:
+  %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
+  %iv.inc = add nsw i32 %iv, 7
+; CHECK:    %iv.inc = add nsw i32 %iv, 7
+; CHECK-NEXT:  -->  {7,+,7}<nuw><%loop>
+  %becond = icmp ult i32 %iv.inc, %n
+  call void @may_exit()
+  br i1 %becond, label %loop, label %leave
+
+leave:
+  ret void
+}




More information about the llvm-commits mailing list