Skip to content

Commit 5366de7

Browse files
committed
[SimpleLoopUnswitch] Don't non-trivially unswitch loops with catchswitch exits
SplitBlock() can't handle catchswitch. Fixes PR50973. Reviewed By: aheejin Differential Revision: https://reviews.llvm.org/D105672
1 parent 0e49c54 commit 5366de7

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,14 +2775,15 @@ static bool unswitchBestCondition(
27752775
SmallVector<BasicBlock *, 4> ExitBlocks;
27762776
L.getUniqueExitBlocks(ExitBlocks);
27772777

2778-
// We cannot unswitch if exit blocks contain a cleanuppad instruction as we
2779-
// don't know how to split those exit blocks.
2778+
// We cannot unswitch if exit blocks contain a cleanuppad/catchswitch
2779+
// instruction as we don't know how to split those exit blocks.
27802780
// FIXME: We should teach SplitBlock to handle this and remove this
27812781
// restriction.
27822782
for (auto *ExitBB : ExitBlocks) {
2783-
if (isa<CleanupPadInst>(ExitBB->getFirstNonPHI())) {
2784-
LLVM_DEBUG(
2785-
dbgs() << "Cannot unswitch because of cleanuppad in exit block\n");
2783+
auto *I = ExitBB->getFirstNonPHI();
2784+
if (isa<CleanupPadInst>(I) || isa<CatchSwitchInst>(I)) {
2785+
LLVM_DEBUG(dbgs() << "Cannot unswitch because of cleanuppad/catchswitch "
2786+
"in exit block\n");
27862787
return false;
27872788
}
27882789
}

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,8 +766,10 @@ static BasicBlock *SplitBlockImpl(BasicBlock *Old, Instruction *SplitPt,
766766
BBName);
767767
}
768768
BasicBlock::iterator SplitIt = SplitPt->getIterator();
769-
while (isa<PHINode>(SplitIt) || SplitIt->isEHPad())
769+
while (isa<PHINode>(SplitIt) || SplitIt->isEHPad()) {
770770
++SplitIt;
771+
assert(SplitIt != SplitPt->getParent()->end());
772+
}
771773
std::string Name = BBName.str();
772774
BasicBlock *New = Old->splitBasicBlock(
773775
SplitIt, Name.empty() ? Old->getName() + ".split" : Name);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: opt -passes=simple-loop-unswitch -enable-nontrivial-unswitch < %s -S | FileCheck %s
2+
3+
; CHECK: if.end{{.*}}:
4+
; CHECK-NOT: if.end{{.*}}:
5+
declare i32 @__gxx_wasm_personality_v0(...)
6+
7+
declare void @foo()
8+
9+
define void @test(i1 %arg) personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
10+
entry:
11+
br label %while.body
12+
13+
while.body: ; preds = %cleanup, %entry
14+
br i1 %arg, label %if.end, label %if.then
15+
16+
if.then: ; preds = %while.body
17+
br label %if.end
18+
19+
if.end: ; preds = %if.then, %while.body
20+
invoke void @foo()
21+
to label %cleanup unwind label %catch.dispatch
22+
23+
catch.dispatch: ; preds = %invoke.cont, %if.end
24+
%0 = catchswitch within none [label %catch] unwind to caller
25+
26+
catch: ; preds = %catch.dispatch
27+
%1 = catchpad within %0 [i8* null]
28+
unreachable
29+
30+
cleanup: ; preds = %invoke.cont
31+
br label %while.body
32+
}
33+

0 commit comments

Comments
 (0)