Skip to content

Commit a80b6c1

Browse files
committed
[Local] Handle terminators with users in removeUnreachableBlocks.
Terminators like invoke can have users outside the current basic block. We have to replace those users with undef, before replacing the terminator. This fixes a crash exposed by rL373430. Reviewers: brzycki, asbirlea, davide, spatel Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D68327 llvm-svn: 373513
1 parent c78c0e0 commit a80b6c1

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,9 +2246,13 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
22462246
}
22472247
BB->dropAllReferences();
22482248
if (DTU) {
2249-
// Remove the terminator of BB to clear the successor list of BB.
2250-
if (BB->getTerminator())
2251-
BB->getInstList().pop_back();
2249+
Instruction *TI = BB->getTerminator();
2250+
assert(TI && "Basic block should have a terminator");
2251+
// Terminators like invoke can have users. We have to replace their users,
2252+
// before removing them.
2253+
if (!TI->use_empty())
2254+
TI->replaceAllUsesWith(UndefValue::get(TI->getType()));
2255+
TI->eraseFromParent();
22522256
new UnreachableInst(BB->getContext(), BB);
22532257
assert(succ_empty(BB) && "The successor list of BB isn't empty before "
22542258
"applying corresponding DTU updates.");

llvm/unittests/Transforms/Utils/LocalTest.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,36 @@ TEST(Local, RemoveUnreachableBlocks) {
867867
bb2:
868868
br label %bb1
869869
}
870+
871+
declare i32 @__gxx_personality_v0(...)
872+
873+
define void @invoke_terminator() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
874+
entry:
875+
br i1 undef, label %invoke.block, label %exit
876+
877+
invoke.block:
878+
%cond = invoke zeroext i1 @invokable()
879+
to label %continue.block unwind label %lpad.block
880+
881+
continue.block:
882+
br i1 %cond, label %if.then, label %if.end
883+
884+
if.then:
885+
unreachable
886+
887+
if.end:
888+
unreachable
889+
890+
lpad.block:
891+
%lp = landingpad { i8*, i32 }
892+
catch i8* null
893+
br label %exit
894+
895+
exit:
896+
ret void
897+
}
898+
899+
declare i1 @invokable()
870900
)");
871901

872902
auto runEager = [&](Function &F, DominatorTree *DT) {
@@ -890,12 +920,14 @@ TEST(Local, RemoveUnreachableBlocks) {
890920
runWithDomTree(*M, "br_self_loop", runEager);
891921
runWithDomTree(*M, "br_constant", runEager);
892922
runWithDomTree(*M, "br_loop", runEager);
923+
runWithDomTree(*M, "invoke_terminator", runEager);
893924

894925
// Test removeUnreachableBlocks under Lazy UpdateStrategy.
895926
runWithDomTree(*M, "br_simple", runLazy);
896927
runWithDomTree(*M, "br_self_loop", runLazy);
897928
runWithDomTree(*M, "br_constant", runLazy);
898929
runWithDomTree(*M, "br_loop", runLazy);
930+
runWithDomTree(*M, "invoke_terminator", runLazy);
899931

900932
M = parseIR(C,
901933
R"(

0 commit comments

Comments
 (0)