[SimpleLoopUnswitch] Update DefaultExit condition to check unreachable is not empty.

Summary:
Update the check for the default exit block to not only check that the
terminator is not unreachable, but also check that unreachable block has
*only* the unreachable instruction.

Reviewers: chandlerc

Subscribers: hiraditya, uabelho, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D78277
This commit is contained in:
Alina Sbirlea 2020-04-15 21:49:00 -07:00
parent c9e6519d15
commit 6227f021ad
2 changed files with 67 additions and 3 deletions

View File

@ -598,6 +598,23 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT,
auto *ParentBB = SI.getParent();
auto IsTriviallyUnswitchableExitBlock = [&](BasicBlock &BBToCheck) {
// BBToCheck is not an exit block if it is inside loop L.
if (L.contains(&BBToCheck))
return false;
// BBToCheck is not trivial to unswitch if its phis aren't loop invariant.
if (!areLoopExitPHIsLoopInvariant(L, *ParentBB, BBToCheck))
return false;
// We do not unswitch a block that only has an unreachable statement, as
// it's possible this is a previously unswitched block. Only unswitch if
// either the terminator is not unreachable, or, if it is, it's not the only
// instruction in the block.
auto *TI = BBToCheck.getTerminator();
bool isUnreachable = isa<UnreachableInst>(TI);
return !isUnreachable ||
(isUnreachable && (BBToCheck.getFirstNonPHIOrDbg() != TI));
};
SmallVector<int, 4> ExitCaseIndices;
for (auto Case : SI.cases()) {
auto *SuccBB = Case.getCaseSuccessor();
@ -608,9 +625,7 @@ static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT,
BasicBlock *DefaultExitBB = nullptr;
SwitchInstProfUpdateWrapper::CaseWeightOpt DefaultCaseWeight =
SwitchInstProfUpdateWrapper::getSuccessorWeight(SI, 0);
if (!L.contains(SI.getDefaultDest()) &&
areLoopExitPHIsLoopInvariant(L, *ParentBB, *SI.getDefaultDest()) &&
!isa<UnreachableInst>(SI.getDefaultDest()->getTerminator())) {
if (IsTriviallyUnswitchableExitBlock(*SI.getDefaultDest())) {
DefaultExitBB = SI.getDefaultDest();
} else if (ExitCaseIndices.empty())
return false;

View File

@ -1243,3 +1243,52 @@ loopexit:
; CHECK: loopexit:
; CHECK-NEXT: ret
}
declare void @f()
declare void @g()
define void @test_unswitch_switch_with_nonempty_unreachable() {
; CHECK-LABEL: @test_unswitch_switch_with_nonempty_unreachable()
entry:
br label %loop
loop:
%cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
br label %for.cond
for.cond:
switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [
i32 0, label %for.cond
i32 1, label %NonEmptyUnreachableBlock
i32 2, label %loop.loopexit
]
loop.loopexit:
unreachable
NonEmptyUnreachableBlock:
call void @f()
call void @g()
unreachable
; CHECK:loop:
; CHECK-NEXT: %cleanup.dest.slot.0 = select i1 undef, i32 5, i32 undef
; CHECK-NEXT: switch i32 %cleanup.dest.slot.0, label %NonEmptyUnreachableBlock [
; CHECK-NEXT: i32 1, label %NonEmptyUnreachableBlock
; CHECK-NEXT: i32 2, label %loop.loopexit
; CHECK-NEXT: i32 0, label %loop.split
; CHECK-NEXT: ]
; CHECK:loop.split:
; CHECK-NEXT: br label %for.cond
; CHECK:for.cond:
; CHECK-NEXT: br label %for.cond
; CHECK:loop.loopexit:
; CHECK-NEXT: unreachable
; CHECK:NonEmptyUnreachableBlock:
; CHECK-NEXT: call void @f()
; CHECK-NEXT: call void @g()
; CHECK-NEXT: unreachable
}