[llvm] [StructurizeCFG] Hoist and simplify zero-cost incoming else phi values (PR #139605)

Shilei Tian via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 23 21:23:00 PDT 2025


================
@@ -413,6 +455,42 @@ INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
 INITIALIZE_PASS_END(StructurizeCFGLegacyPass, "structurizecfg",
                     "Structurize the CFG", false, false)
 
+/// Because the SCC order of Then and Else blocks is arbitrary, structurization
+/// can introduce unnecessary VGPR copies due to register coalescing
+/// interference.
+/// For example, if the Else block has a zero-cost instruction and
+/// the Then block modifies the VGPR value, only one value is live at a time in
+/// merge block before structurization. After structurization, the coalescer may
+/// incorrectly treat the Then value as live in the Else block (via the path
+/// Then → Flow → Else), leading to unnecessary VGPR copies.
+///
+/// This function examines phi nodes whose incoming values are zero-cost
+/// instructions in the Else block. It identifies such values that can be safely
+/// hoisted and moves them to the nearest common dominator of Then and Else
+/// blocks. A follow-up function after setting PhiNodes assigns the hoisted
+/// value to poison phi nodes along the if→flow edge, aiding register coalescing
+/// and minimizing unnecessary live ranges.
+void StructurizeCFG::hoistZeroCostElseBlockPhiValues(BasicBlock *ElseBB,
+                                                     BasicBlock *ThenBB) {
+
+  BasicBlock *ElseSucc = ElseBB->getSingleSuccessor();
+  BasicBlock *CommonDominator = DT->findNearestCommonDominator(ElseBB, ThenBB);
+
+  if (!ElseSucc || !CommonDominator)
+    return;
+  Instruction *Term = CommonDominator->getTerminator();
+  for (PHINode &Phi : ElseSucc->phis()) {
+    Value *ElseVal = Phi.getIncomingValueForBlock(ElseBB);
+    if (auto *Inst = dyn_cast<Instruction>(ElseVal)) {
+      if (isHoistableInstruction(Inst, ElseBB, TTI)) {
+        Inst->removeFromParent();
+        Inst->insertInto(CommonDominator, Term->getIterator());
+        HoistedValues[Inst] = CommonDominator;
+      }
+    }
----------------
shiltian wrote:

```suggestion
    Value *ElseVal = Phi.getIncomingValueForBlock(ElseBB);
    auto *Inst = dyn_cast<Instruction>(ElseVal);
    if (!Inst || !isHoistableInstruction(Inst, ElseBB, TTI))
      continue;
    Inst->removeFromParent();
    Inst->insertInto(CommonDominator, Term->getIterator());
    HoistedValues[Inst] = CommonDominator;
    }
```

https://github.com/llvm/llvm-project/pull/139605


More information about the llvm-commits mailing list