[llvm] [FixIrreducible][UnifyLoopExits] Support switch statements (PR #206567)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 30 12:46:45 PDT 2026
================
@@ -309,20 +309,23 @@ static bool fixIrreducible(Cycle &C, CycleInfo &CI, DominatorTree &DT,
<< " -> " << printBasicBlock(Succ0)
<< (Succ0 && Succ1 ? " " : "") << printBasicBlock(Succ1)
<< '\n');
- } else if (CallBrInst *CallBr = dyn_cast<CallBrInst>(P->getTerminator())) {
- for (unsigned I = 0; I < CallBr->getNumSuccessors(); ++I) {
- BasicBlock *Succ = CallBr->getSuccessor(I);
+ } else if (isa<CallBrInst>(P->getTerminator()) ||
+ isa<SwitchInst>(P->getTerminator())) {
+ Instruction *Term = P->getTerminator();
+ for (unsigned I = 0; I < Term->getNumSuccessors(); ++I) {
+ BasicBlock *Succ = Term->getSuccessor(I);
if (Succ != Header)
continue;
- BasicBlock *NewSucc = SplitCallBrEdge(P, Succ, I, &DTU, &CI, LI);
+ BasicBlock *NewSucc = SplitMultiBrEdge(P, Succ, I, &DTU, &CI, LI);
CHub.addBranch(NewSucc, Succ);
----------------
hertelukas wrote:
Maybe I'm overlooking something, but isn't that a different issue? For the conditional branch, the pass assumed that only one branch is incident on the header, which has led to the bug. We aren't doing that - we check for each successor if it's the header and introduce a split (for each edge, which might lead to redundant splits).
```llvm
define void @foo_switch(i32 %c) {
entry:
br i1 false, label %a, label %b
a:
switch i32 %c, label %b [ i32 0, label %b ]
b:
br i1 false, label %exit, label %a
exit:
ret void
}
; Resulting in:
define void @foo_switch(i32 %c) {
entry:
br label %irr.guard
a: ; preds = %irr.guard, %b
switch i32 %c, label %a.target.b [
i32 0, label %a.target.b1
]
b: ; preds = %irr.guard
br i1 false, label %exit, label %a
exit: ; preds = %b
ret void
a.target.b: ; preds = %a
br label %irr.guard
a.target.b1: ; preds = %a
br label %irr.guard
irr.guard: ; preds = %entry, %a.target.b1, %a.target.b
%Guard.b = phi i1 [ true, %a.target.b ], [ true, %a.target.b1 ], [ true, %entry ]
br i1 %Guard.b, label %b, label %a
}
```
Playing around with the example a bit (trying to figure out if we can avoid some splits), phi nodes don't seem to get handled correctly then (also with `callbr`).
https://godbolt.org/z/PvTvchqx1
Since this seems like a separate issue, should I address it in this PR or file a new bug? I'll look into it anyway.
https://github.com/llvm/llvm-project/pull/206567
More information about the llvm-commits
mailing list