[llvm] [FixIrreducible][UnifyLoopExits] Fix callbr multiedge splitting (PR #207598)
Robert Imschweiler via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 6 06:34:00 PDT 2026
================
@@ -726,42 +726,62 @@ static bool updateCycleLoopInfo(TI *LCI, BasicBlock *CallBrBlock,
}
BasicBlock *llvm::SplitCallBrEdge(BasicBlock *CallBrBlock, BasicBlock *Succ,
- unsigned SuccIdx, DomTreeUpdater *DTU,
- CycleInfo *CI, LoopInfo *LI,
- bool *UpdatedLI) {
+ unsigned SuccIdx, BasicBlock *CallBrTarget,
+ DomTreeUpdater *DTU, CycleInfo *CI,
+ LoopInfo *LI, bool *UpdatedLI) {
CallBrInst *CallBr = dyn_cast<CallBrInst>(CallBrBlock->getTerminator());
assert(CallBr && "expected callbr terminator");
assert(SuccIdx < CallBr->getNumSuccessors() &&
Succ == CallBr->getSuccessor(SuccIdx) && "invalid successor index");
+ bool ReusesCallBrTarget = CallBrTarget;
// Create a new block between callbr and the specified successor.
// splitBlockBefore cannot be re-used here since it cannot split if the split
// point is a PHI node (because BasicBlock::splitBasicBlockBefore cannot
// handle that). But we don't need to rewire every part of a potential PHI
// node. We only care about the edge between CallBrBlock and the original
// successor.
- BasicBlock *CallBrTarget =
- BasicBlock::Create(CallBrBlock->getContext(),
- CallBrBlock->getName() + ".target." + Succ->getName(),
- CallBrBlock->getParent());
- // Rewire control flow from the new target block to the original successor.
- Succ->replacePhiUsesWith(CallBrBlock, CallBrTarget);
+ if (!ReusesCallBrTarget) {
+ CallBrTarget = BasicBlock::Create(CallBrBlock->getContext(),
+ CallBrBlock->getName() + ".target." +
+ Succ->getName(),
+ CallBrBlock->getParent());
+ // Jump from the new target block to the original successor.
+ UncondBrInst::Create(Succ, CallBrTarget);
+ // Replace a single incoming value with the callbr target block. We cannot
+ // use replacePhiUsesWith, as this would replace the value for every edge
+ // from the callbr block to succ.
+ for (PHINode &PN : Succ->phis()) {
+ int BBIdx = PN.getBasicBlockIndex(CallBrBlock);
+ assert(BBIdx != -1 && "expected incoming value form callbr block");
+ PN.setIncomingBlock(BBIdx, CallBrTarget);
+ }
+ } else {
+ for (PHINode &PN : Succ->phis()) {
----------------
ro-i wrote:
no braces needed
https://github.com/llvm/llvm-project/pull/207598
More information about the llvm-commits
mailing list