summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/IPO/PruneEH.cpp3
-rw-r--r--llvm/test/Transforms/PruneEH/musttail.ll15
2 files changed, 17 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/IPO/PruneEH.cpp b/llvm/lib/Transforms/IPO/PruneEH.cpp
index 46d42764fd2..ef7b43e8b55 100644
--- a/llvm/lib/Transforms/IPO/PruneEH.cpp
+++ b/llvm/lib/Transforms/IPO/PruneEH.cpp
@@ -203,7 +203,8 @@ static bool SimplifyFunction(Function *F, CallGraph &CG) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
if (CallInst *CI = dyn_cast<CallInst>(I++))
- if (CI->doesNotReturn() && !isa<UnreachableInst>(I)) {
+ if (CI->doesNotReturn() && !CI->isMustTailCall() &&
+ !isa<UnreachableInst>(I)) {
// This call calls a function that cannot return. Insert an
// unreachable instruction after it and simplify the code. Do this
// by splitting the BB, adding the unreachable, then deleting the
diff --git a/llvm/test/Transforms/PruneEH/musttail.ll b/llvm/test/Transforms/PruneEH/musttail.ll
new file mode 100644
index 00000000000..1ad607713c6
--- /dev/null
+++ b/llvm/test/Transforms/PruneEH/musttail.ll
@@ -0,0 +1,15 @@
+; RUN: opt -prune-eh -S < %s | FileCheck %s
+
+declare void @noreturn()
+
+define void @testfn() {
+ ; A musttail call must be followed by (optional bitcast then) ret,
+ ; so make sure we don't insert an unreachable
+ ; CHECK: musttail call void @noreturn
+ ; CHECK-NOT: unreachable
+ ; CHECK-NEXT: ret void
+ musttail call void @noreturn() #0
+ ret void
+}
+
+attributes #0 = { noreturn }
OpenPOWER on IntegriCloud