forked from OSchip/llvm-project
[SimplifyCFG] Do not blindly remove unreachable blocks
DeleteDeadBlock was called indiscriminately, leading to cleanuprets with undef cleanuppad references. Instead, try to drain the BB of most of it's instructions if it is unreachable. We can then remove the BB if it solely consists of a terminator (and maybe some phis). llvm-svn: 261731
This commit is contained in:
parent
e2ad73759d
commit
ec72e37220
|
@ -5278,9 +5278,17 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
|
||||||
if ((pred_empty(BB) &&
|
if ((pred_empty(BB) &&
|
||||||
BB != &BB->getParent()->getEntryBlock()) ||
|
BB != &BB->getParent()->getEntryBlock()) ||
|
||||||
BB->getSinglePredecessor() == BB) {
|
BB->getSinglePredecessor() == BB) {
|
||||||
DEBUG(dbgs() << "Removing BB: \n" << *BB);
|
// Get the block mostly empty.
|
||||||
DeleteDeadBlock(BB);
|
Changed |= removeAllNonTerminatorAndEHPadInstructions(BB) > 0;
|
||||||
return true;
|
// Now, verify that we succeeded getting the block empty.
|
||||||
|
// This will not be the case if this unreachable BB creates a token which is
|
||||||
|
// consumed by other unreachable blocks.
|
||||||
|
Instruction *FirstNonPHI = BB->getFirstNonPHI();
|
||||||
|
if (isa<TerminatorInst>(FirstNonPHI) && FirstNonPHI->use_empty()) {
|
||||||
|
DEBUG(dbgs() << "Removing BB: \n" << *BB);
|
||||||
|
DeleteDeadBlock(BB);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if we can constant propagate this terminator instruction
|
// Check to see if we can constant propagate this terminator instruction
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
; RUN: opt -simplifycfg -S < %s | FileCheck %s
|
||||||
|
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
|
||||||
|
target triple = "i686-pc-win32"
|
||||||
|
|
||||||
|
declare i32 @__CxxFrameHandler3(...)
|
||||||
|
|
||||||
|
declare void @fn_2()
|
||||||
|
|
||||||
|
define void @fn_1(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
|
||||||
|
entry:
|
||||||
|
br i1 %B, label %__Ea.exit, label %lor.lhs.false.i.i
|
||||||
|
|
||||||
|
lor.lhs.false.i.i:
|
||||||
|
br i1 %B, label %if.end.i.i, label %__Ea.exit
|
||||||
|
|
||||||
|
if.end.i.i:
|
||||||
|
invoke void @fn_2()
|
||||||
|
to label %__Ea.exit unwind label %ehcleanup.i
|
||||||
|
|
||||||
|
ehcleanup.i:
|
||||||
|
%t4 = cleanuppad within none []
|
||||||
|
br label %arraydestroy.body.i
|
||||||
|
|
||||||
|
arraydestroy.body.i:
|
||||||
|
%gep = getelementptr i8, i8* null, i32 -1
|
||||||
|
br label %dtor.exit.i
|
||||||
|
|
||||||
|
dtor.exit.i:
|
||||||
|
br i1 %B, label %arraydestroy.done3.i, label %arraydestroy.body.i
|
||||||
|
|
||||||
|
arraydestroy.done3.i:
|
||||||
|
cleanupret from %t4 unwind to caller
|
||||||
|
|
||||||
|
__Ea.exit:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: define void @fn_1(
|
||||||
|
; CHECK-NEXT: entry:
|
||||||
|
; CHECK-NEXT: ret void
|
Loading…
Reference in New Issue