]> granicus.if.org Git - llvm/commitdiff
[PruneEH] Don't split musttail call from ret
authorJoseph Tremoulet <jotrem@microsoft.com>
Tue, 2 Apr 2019 15:47:11 +0000 (15:47 +0000)
committerJoseph Tremoulet <jotrem@microsoft.com>
Tue, 2 Apr 2019 15:47:11 +0000 (15:47 +0000)
Summary:
When inserting an `unreachable` after a noreturn call, we must ensure
that it's not a musttail call to avoid breaking the IR invariants for
musttail calls.

Reviewers: fedor.sergeev, majnemer

Reviewed By: majnemer

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60079

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357483 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/PruneEH.cpp
test/Transforms/PruneEH/musttail.ll [new file with mode: 0644]

index 46d42764fd245dba72181c03f9458cf10996a960..ef7b43e8b5572f7a34b3a83381395cdd8f4b37f1 100644 (file)
@@ -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/test/Transforms/PruneEH/musttail.ll b/test/Transforms/PruneEH/musttail.ll
new file mode 100644 (file)
index 0000000..1ad6077
--- /dev/null
@@ -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 }