[llvm] [CodeGen] Fix SplitCriticalEdge using parent valno for subrange segments (PR #208480)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 15:54:30 PDT 2026
https://github.com/alex-t updated https://github.com/llvm/llvm-project/pull/208480
>From e79ad448987a377e4bd99784a1547a027c996d89 Mon Sep 17 00:00:00 2001
From: alex-t <alexander.timofeev at amd.com>
Date: Sun, 5 Jul 2026 13:13:05 +0000
Subject: [PATCH 1/3] [CodeGen] Fix SplitCriticalEdge using parent valno for
subrange segments
When SplitCriticalEdge extends the live intervals of PHI source registers
into the newly created split block, it added a segment to each subrange
using the *parent* LiveInterval's VNInfo:
for (auto &SR : LI.subranges())
SR.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
Subranges have their own value numbers, distinct from the parent range.
If a PHI source is also live through the split block, the subrange already
has a segment (under its own valno) covering the renumbered indices of the
new block. Overlaying the foreign parent valno on top of it triggers the
addSegment assert Cannot overlap two segments with differing ValIDs.
Use the subrange's own value number at PrevIndex instead, mirroring the
existing live-through update loop a few lines below which already does this
correctly. Subranges without a value live at PrevIndex are skipped.
Add a regression test that reproduces the assert via stock
phi-node-elimination with LiveIntervals (subrange-tracked) live: a 64-bit
PHI source whose sub0/sub1 lanes are live through the split block.
---
llvm/lib/CodeGen/MachineBasicBlock.cpp | 10 ++++-
...imination-split-critical-edge-subrange.mir | 42 +++++++++++++++++++
2 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-subrange.mir
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 2870bf404644c..597a85ad97cdb 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -1348,8 +1348,14 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
assert(VNI &&
"PHI sources should be live out of their predecessors.");
LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
- for (auto &SR : LI.subranges())
- SR.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
+ for (auto &SR : LI.subranges()) {
+ // Use the subrange's own value number; reusing the parent range's
+ // VNInfo overlaps the subrange's existing value with a foreign valno
+ // when the register is live through the split block. Mirrors the
+ // live-through update loop below.
+ if (VNInfo *SubVNI = SR.getVNInfoAt(PrevIndex))
+ SR.addSegment(LiveInterval::Segment(StartIndex, EndIndex, SubVNI));
+ }
}
}
}
diff --git a/llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-subrange.mir b/llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-subrange.mir
new file mode 100644
index 0000000000000..a9ea8cb7f5b28
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/phi-elimination-split-critical-edge-subrange.mir
@@ -0,0 +1,42 @@
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -run-pass liveintervals,phi-node-elimination -o - %s | FileCheck %s
+# RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -verify-machineinstrs -passes='require<live-intervals>,phi-node-elimination' -o - %s | FileCheck %s
+
+# PHIElimination splits the critical edge bb.0 -> bb.2 while LiveIntervals with
+# subranges are live. The PHI sources are subregisters (%r.sub0/%r.sub1) of a
+# 64-bit vreg that is live *through* the newly inserted split block (used in
+# bb.1). MachineBasicBlock::SplitCriticalEdge used to extend each subrange with
+# the parent range's VNInfo, overlapping the subrange's own value and asserting
+# in LiveRange::addSegment ("Cannot overlap two segments with differing
+# ValID's"). It must use the subrange's own VNInfo instead.
+
+---
+name: real_split_subrange
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: real_split_subrange
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.3({{[^)]+}}), %bb.1
+ ; CHECK: bb.3:
+ ; CHECK: successors: %bb.2
+ ; CHECK: bb.2:
+ ; CHECK: S_ENDPGM
+ bb.0:
+ %r:vreg_64 = IMPLICIT_DEF
+ %c0:sreg_32 = IMPLICIT_DEF
+ %c1:sreg_32 = IMPLICIT_DEF
+ %const:vgpr_32 = IMPLICIT_DEF
+ S_CMP_EQ_U32 killed %c0:sreg_32, killed %c1:sreg_32, implicit-def $scc
+ S_CBRANCH_SCC1 %bb.2, implicit $scc
+ S_BRANCH %bb.1
+
+ bb.1:
+ ; Use %r so it is live-out of bb.0 past the PHI (forces edge split).
+ %u0:vgpr_32 = V_ADD_F32_e64 0, %r.sub0:vreg_64, 0, %const:vgpr_32, 0, 0, implicit $mode, implicit $exec
+ %u1:vgpr_32 = V_ADD_F32_e64 0, %r.sub1:vreg_64, 0, %const:vgpr_32, 0, 0, implicit $mode, implicit $exec
+ S_BRANCH %bb.2
+
+ bb.2:
+ %p0:vgpr_32 = PHI %r.sub0:vreg_64, %bb.0, %u0:vgpr_32, %bb.1
+ %p1:vgpr_32 = PHI %r.sub1:vreg_64, %bb.0, %u1:vgpr_32, %bb.1
+ S_ENDPGM 0, implicit %p0:vgpr_32, implicit %p1:vgpr_32
+...
>From b7ee24c6b104bd571ab1a8791477c9812b8490b4 Mon Sep 17 00:00:00 2001
From: alex-t <alexander.timofeev at amd.com>
Date: Mon, 13 Jul 2026 21:11:19 +0000
Subject: [PATCH 2/3] Comments changed
---
llvm/lib/CodeGen/MachineBasicBlock.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 597a85ad97cdb..9cd60f5dd21ab 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -1349,10 +1349,7 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
"PHI sources should be live out of their predecessors.");
LI.addSegment(LiveInterval::Segment(StartIndex, EndIndex, VNI));
for (auto &SR : LI.subranges()) {
- // Use the subrange's own value number; reusing the parent range's
- // VNInfo overlaps the subrange's existing value with a foreign valno
- // when the register is live through the split block. Mirrors the
- // live-through update loop below.
+ // New segment VNI must be from the subrange.
if (VNInfo *SubVNI = SR.getVNInfoAt(PrevIndex))
SR.addSegment(LiveInterval::Segment(StartIndex, EndIndex, SubVNI));
}
>From d788903732fcdb4f98afd1816f5580826505b316 Mon Sep 17 00:00:00 2001
From: alex-t <alexander.timofeev at amd.com>
Date: Mon, 13 Jul 2026 22:50:36 +0000
Subject: [PATCH 3/3] Formatting fix.
---
llvm/lib/CodeGen/MachineBasicBlock.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 9cd60f5dd21ab..f88dde0fee45a 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -1351,7 +1351,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
for (auto &SR : LI.subranges()) {
// New segment VNI must be from the subrange.
if (VNInfo *SubVNI = SR.getVNInfoAt(PrevIndex))
- SR.addSegment(LiveInterval::Segment(StartIndex, EndIndex, SubVNI));
+ SR.addSegment(
+ LiveInterval::Segment(StartIndex, EndIndex, SubVNI));
}
}
}
More information about the llvm-commits
mailing list