[llvm] r267175 - Have isKnownNotFullPoison be smarter around control flow
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 22 10:41:06 PDT 2016
Author: sanjoy
Date: Fri Apr 22 12:41:06 2016
New Revision: 267175
URL: http://llvm.org/viewvc/llvm-project?rev=267175&view=rev
Log:
Have isKnownNotFullPoison be smarter around control flow
Summary:
(... while still not using a PostDomTree)
The way we use isKnownNotFullPoison from SCEV today, the new CFG walking
logic will not trigger for any realistic cases -- it will kick in only
for situations where we could have merged the contiguous basic blocks
anyway[0], since the poison generating instruction dominates all of its
non-PHI uses (which are the only uses we consider right now).
However, having this change in place will allow a later bugfix to break
fewer llvm-lit tests.
[0]: i.e. cases where block A branches to block B and B is A's only
successor and A is B's only predecessor.
Reviewers: broune, bjarke.roune
Subscribers: mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D19212
Modified:
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/test/Analysis/ScalarEvolution/flags-from-poison.ll
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=267175&r1=267174&r2=267175&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Fri Apr 22 12:41:06 2016
@@ -3543,26 +3543,44 @@ bool llvm::isKnownNotFullPoison(const In
// Set of instructions that we have proved will yield poison if PoisonI
// does.
SmallSet<const Value *, 16> YieldsPoison;
+ SmallSet<const BasicBlock *, 4> Visited;
YieldsPoison.insert(PoisonI);
+ Visited.insert(PoisonI->getParent());
- for (BasicBlock::const_iterator I = PoisonI->getIterator(), E = BB->end();
- I != E; ++I) {
- if (&*I != PoisonI) {
- const Value *NotPoison = getGuaranteedNonFullPoisonOp(&*I);
- if (NotPoison != nullptr && YieldsPoison.count(NotPoison)) return true;
- if (!isGuaranteedToTransferExecutionToSuccessor(&*I))
- return false;
+ BasicBlock::const_iterator Begin = PoisonI->getIterator(), End = BB->end();
+
+ unsigned Iter = 0;
+ while (Iter++ < MaxDepth) {
+ for (auto &I : make_range(Begin, End)) {
+ if (&I != PoisonI) {
+ const Value *NotPoison = getGuaranteedNonFullPoisonOp(&I);
+ if (NotPoison != nullptr && YieldsPoison.count(NotPoison))
+ return true;
+ if (!isGuaranteedToTransferExecutionToSuccessor(&I))
+ return false;
+ }
+
+ // Mark poison that propagates from I through uses of I.
+ if (YieldsPoison.count(&I)) {
+ for (const User *User : I.users()) {
+ const Instruction *UserI = cast<Instruction>(User);
+ if (propagatesFullPoison(UserI))
+ YieldsPoison.insert(User);
+ }
+ }
}
- // Mark poison that propagates from I through uses of I.
- if (YieldsPoison.count(&*I)) {
- for (const User *User : I->users()) {
- const Instruction *UserI = cast<Instruction>(User);
- if (UserI->getParent() == BB && propagatesFullPoison(UserI))
- YieldsPoison.insert(User);
+ if (auto *NextBB = BB->getSingleSuccessor()) {
+ if (Visited.insert(NextBB).second) {
+ BB = NextBB;
+ Begin = BB->getFirstNonPHI()->getIterator();
+ End = BB->end();
+ continue;
}
}
- }
+
+ break;
+ };
return false;
}
Modified: llvm/trunk/test/Analysis/ScalarEvolution/flags-from-poison.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/flags-from-poison.ll?rev=267175&r1=267174&r2=267175&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/flags-from-poison.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/flags-from-poison.ll Fri Apr 22 12:41:06 2016
@@ -113,11 +113,65 @@ loop:
%i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nsw>
+ %index32 = add nsw i32 %i, %offset
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %index32
+ %nexti = add nsw i32 %i, 1
+ br label %loop2
+loop2:
+ %f = load float, float* %ptr, align 4
+ %exitcond = icmp eq i32 %nexti, %numIterations
+ br i1 %exitcond, label %exit, label %loop
+exit:
+ ret void
+}
+
+; Similar to test-add-not-header, but in this case the load
+; instruction may not be executed.
+define void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations,
+ i1* %cond_buf) {
+; CHECK-LABEL: @test-add-not-header3
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
+
+; CHECK: %index32 =
; CHECK: --> {%offset,+,1}<nw>
%index32 = add nsw i32 %i, %offset
%ptr = getelementptr inbounds float, float* %input, i32 %index32
%nexti = add nsw i32 %i, 1
+ %cond = load volatile i1, i1* %cond_buf
+ br i1 %cond, label %loop2, label %exit
+loop2:
+ %f = load float, float* %ptr, align 4
+ %exitcond = icmp eq i32 %nexti, %numIterations
+ br i1 %exitcond, label %exit, label %loop
+exit:
+ ret void
+}
+
+; Same thing as test-add-not-header2, except we have a few extra
+; blocks.
+define void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) {
+; CHECK-LABEL: @test-add-not-header4
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]
+
+; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nsw>
+ %index32 = add nsw i32 %i, %offset
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %index32
+ %nexti = add nsw i32 %i, 1
+ br label %loop3
+loop3:
+ br label %loop4
+loop4:
br label %loop2
loop2:
%f = load float, float* %ptr, align 4
@@ -126,6 +180,26 @@ loop2:
exit:
ret void
}
+
+; Demonstrate why we need a Visited set in llvm::isKnownNotFullPoison.
+define void @test-add-not-header5(float* %input, i32 %offset) {
+; CHECK-LABEL: @test-add-not-header5
+entry:
+ br label %loop
+loop:
+ %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
+
+; CHECK: %index32 =
+; CHECK: --> {%offset,+,1}<nw>
+ %index32 = add nsw i32 %i, %offset
+
+ %ptr = getelementptr inbounds float, float* %input, i32 %index32
+ %nexti = add nsw i32 %i, 1
+ br label %loop
+
+exit:
+ ret void
+}
; The call instruction makes it not guaranteed that the add will be
; executed, since it could run forever or throw an exception, so we
More information about the llvm-commits
mailing list