1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[LoopSimplifyCFG] Delete landing pads in dead exit blocks

In addition to removing phi nodes this patch removes any
landing pad that the dead exit block might have. Without
this fix Verifier complains about a new switch instruction
jumps to a block with a landing pad.

Differential Revision: https://reviews.llvm.org/D84320
This commit is contained in:
Yevgeny Rouban 2020-07-29 17:47:36 +07:00
parent 62153b67c4
commit a2a9ffd73d
2 changed files with 99 additions and 6 deletions

View File

@ -366,15 +366,20 @@ private:
unsigned DummyIdx = 1;
for (BasicBlock *BB : DeadExitBlocks) {
SmallVector<Instruction *, 4> DeadPhis;
// Eliminate all Phis and LandingPads from dead exits.
// TODO: Consider removing all instructions in this dead block.
SmallVector<Instruction *, 4> DeadInstructions;
for (auto &PN : BB->phis())
DeadPhis.push_back(&PN);
DeadInstructions.push_back(&PN);
// Eliminate all Phis from dead exits.
for (Instruction *PN : DeadPhis) {
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
PN->eraseFromParent();
if (auto *LandingPad = dyn_cast<LandingPadInst>(BB->getFirstNonPHI()))
DeadInstructions.emplace_back(LandingPad);
for (Instruction *I : DeadInstructions) {
I->replaceAllUsesWith(UndefValue::get(I->getType()));
I->eraseFromParent();
}
assert(DummyIdx != 0 && "Too many dead exits!");
DummySwitch->addCase(Builder.getInt32(DummyIdx++), BB);
DTUpdates.push_back({DominatorTree::Insert, Preheader, BB});

View File

@ -0,0 +1,88 @@
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg %s | FileCheck %s
; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' %s | FileCheck %s
declare i32* @fake_personality_function()
declare void @foo()
define i32 @test_remove_lpad(i1 %exitcond) personality i32* ()* @fake_personality_function {
; CHECK-LABEL: @test_remove_lpad(
entry:
br label %for.body
for.body:
br i1 0, label %never, label %next
next:
br label %latch
latch:
br i1 %exitcond, label %exit, label %for.body
exit:
ret i32 0
never:
invoke void @foo() to label %next unwind label %never-unwind
never-unwind:
; CHECK: never-unwind:
; CHECK-NEXT: unreachable
%res = landingpad token cleanup
unreachable
}
define i32 @test_remove_phi_lpad(i1 %exitcond) personality i32* ()* @fake_personality_function {
; CHECK-LABEL: @test_remove_phi_lpad(
entry:
br label %for.body
for.body:
br i1 0, label %never, label %next
next:
br label %latch
latch:
br i1 %exitcond, label %exit, label %for.body
exit:
ret i32 0
never:
invoke void @foo() to label %next unwind label %never-unwind
never-unwind:
; CHECK: never-unwind:
; CHECK-NEXT: ret i32 undef
%p = phi i32 [1, %never]
%res = landingpad token cleanup
ret i32 %p
}
define i32 @test_split_remove_phi_lpad_(i1 %exitcond) personality i32* ()* @fake_personality_function {
; CHECK-LABEL: @test_split_remove_phi_lpad_(
entry:
invoke void @foo() to label %for.body unwind label %unwind-bb
for.body:
br i1 0, label %never, label %next
next:
br label %latch
latch:
br i1 %exitcond, label %exit, label %for.body
exit:
ret i32 0
never:
invoke void @foo() to label %next unwind label %unwind-bb
unwind-bb:
; CHECK: unwind-bb.loopexit:
; CHECK-NEXT: br label %unwind-bb
%p = phi i32 [1, %never], [2, %entry]
%res = landingpad token cleanup
ret i32 %p
}