[PATCH] D78277: [SimpleLoopUnswitch] Update DefaultExit condition to check unreachable is not empty.
Alina Sbirlea via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue May 5 15:40:42 PDT 2020
asbirlea updated this revision to Diff 262238.
asbirlea marked 2 inline comments as done.
asbirlea added a comment.
Address comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D78277/new/
https://reviews.llvm.org/D78277
Files:
llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
Index: llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
===================================================================
--- llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
+++ llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch.ll
@@ -1243,3 +1243,52 @@
; 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
+}
Index: llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -598,6 +598,22 @@
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.begin() != TI));
+ };
+
SmallVector<int, 4> ExitCaseIndices;
for (auto Case : SI.cases()) {
auto *SuccBB = Case.getCaseSuccessor();
@@ -608,9 +624,7 @@
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78277.262238.patch
Type: text/x-patch
Size: 3329 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200505/445d22ff/attachment.bin>
More information about the llvm-commits
mailing list