summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-04-21 05:09:12 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-04-21 05:09:12 +0000
commit54a3a006cab5a108322ed61ce4fbe2939177274c (patch)
treec4333b4bb38c01709d4f43209437ffb66df22abd /llvm/lib/Transforms
parentafd1b06d8eaaaf15b38a5ad79dcab20f437b1bc0 (diff)
downloadbcm5719-llvm-54a3a006cab5a108322ed61ce4fbe2939177274c.tar.gz
bcm5719-llvm-54a3a006cab5a108322ed61ce4fbe2939177274c.zip
[SimplifyCFG] Fold `llvm.guard(false)` to unreachable
Summary: `llvm.guard(false)` always bails out of the current compilation unit, so we can prune any control flow following it. Reviewers: hfinkel, pcc, reames Subscribers: majnemer, reames, mcrosier, llvm-commits Differential Revision: http://reviews.llvm.org/D19245 llvm-svn: 266955
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index bd8b7c45d1a..75eda97d0a3 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1310,7 +1310,7 @@ static bool markAliveBlocks(Function &F,
// Assumptions that are known to be false are equivalent to unreachable.
// Also, if the condition is undefined, then we make the choice most
// beneficial to the optimizer, and choose that to also be unreachable.
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(BBI))
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(BBI)) {
if (II->getIntrinsicID() == Intrinsic::assume) {
bool MakeUnreachable = false;
if (isa<UndefValue>(II->getArgOperand(0)))
@@ -1327,6 +1327,24 @@ static bool markAliveBlocks(Function &F,
}
}
+ if (II->getIntrinsicID() == Intrinsic::experimental_guard) {
+ // A call to the guard intrinsic bails out of the current compilation
+ // unit if the predicate passed to it is false. If the predicate is a
+ // constant false, then we know the guard will bail out of the current
+ // compile unconditionally, so all code following it is dead.
+ //
+ // Note: unlike in llvm.assume, it is not "obviously profitable" for
+ // guards to treat `undef` as `false` since a guard on `undef` can
+ // still be useful for widening.
+ if (auto *CI = dyn_cast<ConstantInt>(II->getArgOperand(0)))
+ if (CI->isZero() && !isa<UnreachableInst>(II->getNextNode())) {
+ changeToUnreachable(II->getNextNode(), /*UseLLVMTrap=*/ false);
+ Changed = true;
+ break;
+ }
+ }
+ }
+
if (CallInst *CI = dyn_cast<CallInst>(BBI)) {
if (CI->doesNotReturn()) {
// If we found a call to a no-return function, insert an unreachable
OpenPOWER on IntegriCloud