[Sink] Don't move landingpads
authorKeno Fischer <kfischer@college.harvard.edu>
Mon, 16 Nov 2015 04:47:58 +0000 (04:47 +0000)
committerKeno Fischer <kfischer@college.harvard.edu>
Mon, 16 Nov 2015 04:47:58 +0000 (04:47 +0000)
Summary: Moving landingpads into successor basic blocks makes the
verifier sad. Teach Sink that much like PHI nodes and terminator
instructions, landingpads (and cleanuppads, etc.) may not be moved
between basic blocks.

Reviewers: majnemer

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D14475

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

lib/Transforms/Scalar/Sink.cpp
test/Transforms/Sink/landingpad.ll [new file with mode: 0644]

index f6ccd999ea008273d625e2f81738f6d4a3ee82ea..7c0ac7aa6faec4225547e3d1c8b56b0510ad9e5e 100644 (file)
@@ -169,7 +169,7 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA,
         return false;
   }
 
-  if (isa<TerminatorInst>(Inst) || isa<PHINode>(Inst))
+  if (isa<TerminatorInst>(Inst) || isa<PHINode>(Inst) || Inst->isEHPad())
     return false;
 
   // Convergent operations cannot be made control-dependent on additional
diff --git a/test/Transforms/Sink/landingpad.ll b/test/Transforms/Sink/landingpad.ll
new file mode 100644 (file)
index 0000000..10548fd
--- /dev/null
@@ -0,0 +1,33 @@
+; Test that we don't sink landingpads
+; RUN: opt -sink -S < %s | FileCheck %s
+
+declare hidden void @g()
+declare void @h()
+declare i32 @__gxx_personality_v0(...)
+
+define void @f() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+entry:
+  invoke void @g()
+          to label %invoke.cont.15 unwind label %lpad
+
+invoke.cont.15:
+  unreachable
+
+; CHECK: lpad:
+; CHECK: %0 = landingpad { i8*, i32 }
+lpad:
+  %0 = landingpad { i8*, i32 }
+          catch i8* null
+  invoke void @h()
+          to label %invoke.cont unwind label %lpad.1
+
+; CHECK: invoke.cont
+; CHECK-NOT: %0 = landingpad { i8*, i32 }
+invoke.cont:
+  ret void
+
+lpad.1:
+  %1 = landingpad { i8*, i32 }
+          cleanup
+  resume { i8*, i32 } %1
+}