[llvm] 6227f02 - [SimpleLoopUnswitch] Update DefaultExit condition to check unreachable is not empty.
Alina Sbirlea via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 13:49:29 PDT 2020
Author: Alina Sbirlea
Date: 2020-05-07T13:48:30-07:00
New Revision: 6227f021ad400cc604ca2d15d3639eabfd66a2d9
URL: https://github.com/llvm/llvm-project/commit/6227f021ad400cc604ca2d15d3639eabfd66a2d9
DIFF: https://github.com/llvm/llvm-project/commit/6227f021ad400cc604ca2d15d3639eabfd66a2d9.diff
LOG: [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
Added:
Modified:
llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index 1085a2922d46..6d63277e85b7 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -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;
diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
index 4f01fd517444..713743db6500 100644
--- a/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
+++ b/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
@@ -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
+}
More information about the llvm-commits
mailing list