1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Fix lifetime call in landingpad blocking Simplifycfg pass

Fix lifetime call in landingpad blocks simplifycfg from removing the
landingpad.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D77188
This commit is contained in:
Zequan Wu 2020-04-09 11:06:19 -07:00 committed by Reid Kleckner
parent b7ab26aa94
commit 1f84a491a4
2 changed files with 59 additions and 21 deletions

View 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.

View File

@ -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(...)