[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