[llvm] [RegisterCoalescer] Update undef flags inside bundles (PR #227615)
Jay Foad via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 2 00:53:23 PDT 2026
https://github.com/jayfoad updated https://github.com/llvm/llvm-project/pull/227615
>From ba4ce1103846f3e5f33aa400bf67eff948a38481 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.foad at amd.com>
Date: Tue, 29 Sep 2026 17:44:39 +0100
Subject: [PATCH] [RegisterCoalescer] Update undef flags inside bundles
When joining makes an earlier subregister def a partial redefinition,
JoinVals::pruneValues removes its undef flag. It only looked at the
instruction returned by getInstructionFromIndex, which for a bundle is
the BUNDLE header, so the def inside the bundle kept a stale undef flag
that disagreed with the header. Update all operands in the bundle.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply at anthropic.com>
---
llvm/lib/CodeGen/RegisterCoalescer.cpp | 4 +--
.../coalescer-subreg-undef-in-bundle.mir | 31 +++++++++++++++++++
2 files changed, 33 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/coalescer-subreg-undef-in-bundle.mir
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 23b151ed7b981..c78ebf43abfa3 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -3326,8 +3326,8 @@ void JoinVals::pruneValues(JoinVals &Other,
// Also remove dead flags since the joined live range will
// continue past this instruction.
for (MachineOperand &MO :
- Indexes->getInstructionFromIndex(Def)->all_defs()) {
- if (MO.getReg() == Reg) {
+ mi_bundle_ops(*Indexes->getInstructionFromIndex(Def))) {
+ if (MO.isReg() && MO.isDef() && MO.getReg() == Reg) {
if (MO.getSubReg() != 0 && MO.isUndef() && !EraseImpDef)
MO.setIsUndef(false);
MO.setIsDead(false);
diff --git a/llvm/test/CodeGen/AMDGPU/coalescer-subreg-undef-in-bundle.mir b/llvm/test/CodeGen/AMDGPU/coalescer-subreg-undef-in-bundle.mir
new file mode 100644
index 0000000000000..42f47af0f22e6
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/coalescer-subreg-undef-in-bundle.mir
@@ -0,0 +1,31 @@
+# RUN: llc -mtriple=amdgpu11.00 -run-pass=register-coalescer -o - %s | FileCheck %s
+
+# Joining the copies makes both bundled V_MOVs define subregisters of %2. %1 is
+# joined first, so its def is marked undef; joining %0 then makes it a partial
+# redefinition, so the undef flag must be removed again. That has to happen
+# inside the bundle as well as on the BUNDLE header.
+
+---
+name: subreg_defs_in_bundles
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $vgpr0, $vgpr1, $sgpr0_sgpr1
+ ; CHECK-LABEL: name: subreg_defs_in_bundles
+ ; CHECK: BUNDLE implicit-def undef [[REG:%[0-9]+]].sub1, implicit $vgpr0, implicit $exec {
+ ; CHECK-NEXT: {{^ *}}undef [[REG]].sub1:vreg_64 = V_MOV_B32_e32 $vgpr0, implicit $exec
+ ; CHECK-NEXT: }
+ ; CHECK-NEXT: BUNDLE implicit-def [[REG]].sub0, implicit $vgpr1, implicit $exec {
+ ; CHECK-NEXT: {{^ *}}[[REG]].sub0:vreg_64 = V_MOV_B32_e32 $vgpr1, implicit $exec
+ ; CHECK-NEXT: }
+ BUNDLE implicit-def %0, implicit $vgpr0, implicit $exec {
+ %0:vgpr_32 = V_MOV_B32_e32 $vgpr0, implicit $exec
+ }
+ BUNDLE implicit-def %1, implicit $vgpr1, implicit $exec {
+ %1:vgpr_32 = V_MOV_B32_e32 $vgpr1, implicit $exec
+ }
+ undef %2.sub0:vreg_64 = COPY %1
+ %2.sub1:vreg_64 = COPY %0
+ GLOBAL_STORE_DWORDX2_SADDR undef %3:vgpr_32, %2, $sgpr0_sgpr1, 0, 0, implicit $exec
+ S_ENDPGM 0
+...
More information about the llvm-commits
mailing list