[llvm-branch-commits] [llvm] CodeGen: Fix stale live range for undef PHI sources on split edges (PR #228057)

Matt Arsenault via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Oct 1 05:15:20 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/228057

SplitCriticalEdge collects the PHI sources coming from the new block so
the trimming loop below does not undo the segment just added for them.
An undef operand gets no segment, but was still added to the set, so a
register that is only an undef PHI operand on the split edge kept the
stale extension of its live range through the new block.

Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>

>From 0dabfe3ba3d01cbabb5892a8f04de9779dc7365c Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 1 Oct 2026 13:59:33 +0200
Subject: [PATCH] CodeGen: Fix stale live range for undef PHI sources on split
 edges

SplitCriticalEdge collects the PHI sources coming from the new block so
the trimming loop below does not undo the segment just added for them.
An undef operand gets no segment, but was still added to the set, so a
register that is only an undef PHI operand on the split edge kept the
stale extension of its live range through the new block.

Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>
---
 llvm/lib/CodeGen/MachineBasicBlock.cpp        |  2 +-
 ...n-split-critical-edge-undef-phi-source.mir | 36 +++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-undef-phi-source.mir

diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 4cd6afed26405..108d5fe842ca2 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -1345,9 +1345,9 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
         if (I->getOperand(ni+1).getMBB() == NMBB) {
           MachineOperand &MO = I->getOperand(ni);
           Register Reg = MO.getReg();
-          PHISrcRegs.insert(Reg);
           if (MO.isUndef())
             continue;
+          PHISrcRegs.insert(Reg);
 
           LiveInterval &LI = LIS->getInterval(Reg);
           VNInfo *VNI = LI.getVNInfoAt(PrevIndex);
diff --git a/llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-undef-phi-source.mir b/llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-undef-phi-source.mir
new file mode 100644
index 0000000000000..c9c29eb7b875c
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-undef-phi-source.mir
@@ -0,0 +1,36 @@
+# RUN: llc -mtriple=amdgpu9.00 -passes='require<live-intervals>,phi-node-elimination,print<live-intervals>' -filetype=null %s 2>&1 | FileCheck %s
+
+# %0 is only an undef PHI operand on the critical edge from %bb.1 to
+# %bb.2, so splitting the edge must not leave %0 live through the new
+# block.
+
+# CHECK: ********** INTERVALS **********
+# CHECK-NEXT: %0 [16r,[[SPLIT:[0-9]+]]B:0)
+# CHECK: [[SPLIT]]B{{[[:space:]]+}}bb.5:
+
+---
+name: split_critical_edge_undef_phi_source
+tracksRegLiveness: true
+body: |
+  bb.0:
+    %0:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
+    %1:vgpr_32 = V_MOV_B32_e32 1, implicit $exec
+    $scc = IMPLICIT_DEF
+    S_CBRANCH_SCC1 %bb.1, implicit $scc
+    S_BRANCH %bb.4
+
+  bb.1:
+    $scc = IMPLICIT_DEF
+    S_CBRANCH_SCC1 %bb.3, implicit $scc
+    S_BRANCH %bb.2
+
+  bb.2:
+    %2:vgpr_32 = PHI undef %0, %bb.1, %1, %bb.4
+    S_ENDPGM 0, implicit %2
+
+  bb.3:
+    S_ENDPGM 0, implicit %0
+
+  bb.4:
+    S_BRANCH %bb.2
+...



More information about the llvm-branch-commits mailing list