Fix lifetime call in landingpad blocking Simplifycfg pass
authorZequan Wu <zequanwu@google.com>
Thu, 9 Apr 2020 18:06:19 +0000 (11:06 -0700)
committerReid Kleckner <rnk@google.com>
Thu, 9 Apr 2020 20:07:32 +0000 (13:07 -0700)
Fix lifetime call in landingpad blocks simplifycfg from removing the
landingpad.

Reviewed By: rnk

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

llvm/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll [new file with mode: 0644]

index 9a39df4..263a055 100644 (file)
@@ -3962,6 +3962,28 @@ bool SimplifyCFGOpt::simplifyCommonResume(ResumeInst *RI) {
   return !TrivialUnwindBlocks.empty();
 }
 
+// Check if cleanup block is empty
+static bool isCleanupBlockEmpty(Instruction *Inst, Instruction *RI) {
+  BasicBlock::iterator I = Inst->getIterator(), E = RI->getIterator();
+  while (++I != E) {
+    auto *II = dyn_cast<IntrinsicInst>(I);
+    if (!II)
+      return false;
+
+    Intrinsic::ID IntrinsicID = II->getIntrinsicID();
+    switch (IntrinsicID) {
+    case Intrinsic::dbg_declare:
+    case Intrinsic::dbg_value:
+    case Intrinsic::dbg_label:
+    case Intrinsic::lifetime_end:
+      break;
+    default:
+      return false;
+    }
+  }
+  return true;
+}
+
 // Simplify resume that is only used by a single (non-phi) landing pad.
 bool SimplifyCFGOpt::simplifySingleResume(ResumeInst *RI) {
   BasicBlock *BB = RI->getParent();
@@ -3970,10 +3992,8 @@ bool SimplifyCFGOpt::simplifySingleResume(ResumeInst *RI) {
          "Resume must unwind the exception that caused control to here");
 
   // Check that there are no other instructions except for debug intrinsics.
-  BasicBlock::iterator I = LPInst->getIterator(), E = RI->getIterator();
-  while (++I != E)
-    if (!isa<DbgInfoIntrinsic>(I))
-      return false;
+  if (!isCleanupBlockEmpty(LPInst, RI))
+    return false;
 
   // Turn all invokes that unwind here into calls and delete the basic block.
   for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;) {
@@ -4009,23 +4029,8 @@ static bool removeEmptyCleanup(CleanupReturnInst *RI) {
     return false;
 
   // Check that there are no other instructions except for benign intrinsics.
-  BasicBlock::iterator I = CPInst->getIterator(), E = RI->getIterator();
-  while (++I != E) {
-    auto *II = dyn_cast<IntrinsicInst>(I);
-    if (!II)
-      return false;
-
-    Intrinsic::ID IntrinsicID = II->getIntrinsicID();
-    switch (IntrinsicID) {
-    case Intrinsic::dbg_declare:
-    case Intrinsic::dbg_value:
-    case Intrinsic::dbg_label:
-    case Intrinsic::lifetime_end:
-      break;
-    default:
-      return false;
-    }
-  }
+  if (!isCleanupBlockEmpty(CPInst, RI))
+    return false;
 
   // If the cleanup return we are simplifying unwinds to the caller, this will
   // set UnwindDest to nullptr.
diff --git a/llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll b/llvm/test/Transforms/SimplifyCFG/lifetime-landingpad.ll
new file mode 100644 (file)
index 0000000..2042438
--- /dev/null
@@ -0,0 +1,33 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+; CHECK-LABEL: define void @foo
+define void @foo() personality i32 (...)* @__gxx_personality_v0 {
+entry:
+; CHECK: alloca i8
+; CHECK: call void @llvm.lifetime.start.p0i8
+; CHECK: call void @bar()
+; CHECK: call void @llvm.lifetime.end.p0i8
+; CHECK: ret void
+  %a = alloca i8
+  call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %a) nounwind
+  invoke void @bar() to label %invoke.cont unwind label %lpad
+
+invoke.cont:
+  call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %a) nounwind
+  ret void
+
+lpad:
+; CHECK-NOT: landingpad
+  %b = landingpad { i8*, i32 }
+          cleanup
+  call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %a) nounwind
+  resume { i8*, i32 } %b
+}
+
+declare void @bar()
+
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) nounwind
+
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) nounwind
+
+declare i32 @__gxx_personality_v0(...)