[llvm] [MIRVRegNamerUtils] Handle instructions with multiple definitions (PR #172982)

Frederik Harwath via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 19 06:10:29 PST 2025


https://github.com/frederik-h updated https://github.com/llvm/llvm-project/pull/172982

>From a85250c1703829c1737fb8f4d5a47eaacabac9f5 Mon Sep 17 00:00:00 2001
From: Frederik Harwath <fharwath at amd.com>
Date: Tue, 16 Dec 2025 10:51:56 -0500
Subject: [PATCH 1/3] [MIRVRegNamerUtils] Handle instructions with multiple
 definitions

The VRegRenamer considers only the first definition for renaming.

Make VRegRenamer rename the virtual registers of all definitions,
add test demonstrating the renaming of two definitions for AMDGPU.
---
 llvm/lib/CodeGen/MIRVRegNamerUtils.cpp        | 15 ++++----
 .../MIR/AMDGPU/mir-canon-multi-def.mir        | 37 +++++++++++++++++++
 2 files changed, 45 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir

diff --git a/llvm/lib/CodeGen/MIRVRegNamerUtils.cpp b/llvm/lib/CodeGen/MIRVRegNamerUtils.cpp
index 884c625f94cc7..cb140e1900722 100644
--- a/llvm/lib/CodeGen/MIRVRegNamerUtils.cpp
+++ b/llvm/lib/CodeGen/MIRVRegNamerUtils.cpp
@@ -152,13 +152,14 @@ bool VRegRenamer::renameInstsInMBB(MachineBasicBlock *MBB) {
       continue;
     if (!Candidate.getNumOperands())
       continue;
-    // Look for instructions that define VRegs in operand 0.
-    MachineOperand &MO = Candidate.getOperand(0);
-    // Avoid non regs, instructions defining physical regs.
-    if (!MO.isReg() || !MO.getReg().isVirtual())
-      continue;
-    VRegs.push_back(
-        NamedVReg(MO.getReg(), Prefix + getInstructionOpcodeHash(Candidate)));
+    // Look for instructions that define VRegs.
+    for (MachineOperand &MO : Candidate.defs()) {
+      // Avoid non regs, instructions defining physical regs.
+      if (!MO.isReg() || !MO.getReg().isVirtual())
+        continue;
+      VRegs.push_back(
+          NamedVReg(MO.getReg(), Prefix + getInstructionOpcodeHash(Candidate)));
+    }
   }
 
   return !VRegs.empty() ? doVRegRenaming(getVRegRenameMap(VRegs)) : false;
diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir b/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
new file mode 100644
index 0000000000000..977bb55c9a17e
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
@@ -0,0 +1,37 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=amdgcn -run-pass mir-canonicalizer -mir-vreg-namer-use-stable-hash -verify-machineinstrs %s -o - | FileCheck %s
+
+---
+name: multi_def_renaming
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $sgpr0_sgpr1, $vgpr3
+    ; CHECK-LABEL: name: multi_def_renaming
+    ; CHECK: liveins: $sgpr0_sgpr1, $vgpr3
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: %bb0_1062d9001ab55240__1:vgpr_32 = COPY $vgpr3
+    ; CHECK-NEXT: %bb0_d404709a296ee532__1:sreg_32 = COPY $sgpr1
+    ; CHECK-NEXT: %bb0_bbc0cd19274e6c7b__1:sreg_32 = COPY $sgpr0
+    ; CHECK-NEXT: %bb0_0a0c5272a7d346ac__1:vgpr_32 = V_ADD_U32_e64 %bb0_1062d9001ab55240__1, %bb0_1062d9001ab55240__1, 0, implicit $exec
+    ; CHECK-NEXT: %bb0_079c949829e5b8ca__1:vgpr_32 = V_SUB_U32_e64 %bb0_0a0c5272a7d346ac__1, 2, 0, implicit $exec
+    ; CHECK-NEXT: %bb0_2480fd234d71ac02__1:sreg_64 = REG_SEQUENCE %bb0_bbc0cd19274e6c7b__1, %subreg.sub0, %bb0_d404709a296ee532__1, %subreg.sub1
+    ; CHECK-NEXT: %bb0_3e89a8fc566e3506__1:vreg_64 = REG_SEQUENCE %bb0_0a0c5272a7d346ac__1, %subreg.sub0, %bb0_0a0c5272a7d346ac__1, %subreg.sub1
+    ; CHECK-NEXT: %bb0_af82b3d077ca950c__1:vreg_64, %bb0_af82b3d077ca950c__2:sreg_64 = V_MAD_U64_U32_e64 %bb0_0a0c5272a7d346ac__1, %bb0_0a0c5272a7d346ac__1, %bb0_3e89a8fc566e3506__1, 0, implicit $exec
+    ; CHECK-NEXT: %bb0_640fe5cc4c57ace5__1:vgpr_32 = COPY %bb0_af82b3d077ca950c__2.sub0
+    ; CHECK-NEXT: S_ENDPGM 0
+    %0:sreg_32 = COPY $sgpr0
+    %1:sreg_32 = COPY $sgpr1
+    %2:vgpr_32 = COPY $vgpr3
+    %3:vgpr_32 = V_ADD_U32_e64 %2, %2, 0, implicit $exec
+    %4:vgpr_32 = V_SUB_U32_e64 %3, 2, 0, implicit $exec
+    %5:vreg_64 = REG_SEQUENCE %3, %subreg.sub0, %3, %subreg.sub1
+    %6:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
+    %7:vreg_64, %8:sreg_64 = V_MAD_U64_U32_e64 %3,  %3, %5, 0, implicit $exec
+    %9:vgpr_32 = COPY %8.sub0
+
+    S_ENDPGM 0
+...
+
+## NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+# CHECK: {{.*}}

>From 80c68b94662b26443464edc9283a0a00479d7a6e Mon Sep 17 00:00:00 2001
From: Frederik Harwath <fharwath at amd.com>
Date: Fri, 19 Dec 2025 09:00:16 -0500
Subject: [PATCH 2/3] review changes

---
 .../MIR/AMDGPU/mir-canon-multi-def.mir        | 29 +++++--------------
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir b/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
index 977bb55c9a17e..d4072126c7b4e 100644
--- a/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
+++ b/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
@@ -7,31 +7,16 @@ tracksRegLiveness: true
 body:             |
   bb.0:
     liveins: $sgpr0_sgpr1, $vgpr3
+    liveins: $vgpr3, $vgpr4_vgpr5
+
     ; CHECK-LABEL: name: multi_def_renaming
-    ; CHECK: liveins: $sgpr0_sgpr1, $vgpr3
+    ; CHECK: liveins: $sgpr0_sgpr1, $vgpr3, $vgpr3, $vgpr4_vgpr5
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: %bb0_1062d9001ab55240__1:vgpr_32 = COPY $vgpr3
-    ; CHECK-NEXT: %bb0_d404709a296ee532__1:sreg_32 = COPY $sgpr1
-    ; CHECK-NEXT: %bb0_bbc0cd19274e6c7b__1:sreg_32 = COPY $sgpr0
-    ; CHECK-NEXT: %bb0_0a0c5272a7d346ac__1:vgpr_32 = V_ADD_U32_e64 %bb0_1062d9001ab55240__1, %bb0_1062d9001ab55240__1, 0, implicit $exec
-    ; CHECK-NEXT: %bb0_079c949829e5b8ca__1:vgpr_32 = V_SUB_U32_e64 %bb0_0a0c5272a7d346ac__1, 2, 0, implicit $exec
-    ; CHECK-NEXT: %bb0_2480fd234d71ac02__1:sreg_64 = REG_SEQUENCE %bb0_bbc0cd19274e6c7b__1, %subreg.sub0, %bb0_d404709a296ee532__1, %subreg.sub1
-    ; CHECK-NEXT: %bb0_3e89a8fc566e3506__1:vreg_64 = REG_SEQUENCE %bb0_0a0c5272a7d346ac__1, %subreg.sub0, %bb0_0a0c5272a7d346ac__1, %subreg.sub1
-    ; CHECK-NEXT: %bb0_af82b3d077ca950c__1:vreg_64, %bb0_af82b3d077ca950c__2:sreg_64 = V_MAD_U64_U32_e64 %bb0_0a0c5272a7d346ac__1, %bb0_0a0c5272a7d346ac__1, %bb0_3e89a8fc566e3506__1, 0, implicit $exec
-    ; CHECK-NEXT: %bb0_640fe5cc4c57ace5__1:vgpr_32 = COPY %bb0_af82b3d077ca950c__2.sub0
+    ; CHECK-NEXT: %bb0_cb7ce318324a7ba8__1:vreg_64, %bb0_cb7ce318324a7ba8__2:sreg_64 = V_MAD_U64_U32_e64 $vgpr3, $vgpr3, $vgpr4_vgpr5, 0, implicit $exec
+    ; CHECK-NEXT: %bb0_640fe5cc4c57ace5__1:vgpr_32 = COPY %bb0_cb7ce318324a7ba8__2.sub0
     ; CHECK-NEXT: S_ENDPGM 0
-    %0:sreg_32 = COPY $sgpr0
-    %1:sreg_32 = COPY $sgpr1
-    %2:vgpr_32 = COPY $vgpr3
-    %3:vgpr_32 = V_ADD_U32_e64 %2, %2, 0, implicit $exec
-    %4:vgpr_32 = V_SUB_U32_e64 %3, 2, 0, implicit $exec
-    %5:vreg_64 = REG_SEQUENCE %3, %subreg.sub0, %3, %subreg.sub1
-    %6:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, %1, %subreg.sub1
-    %7:vreg_64, %8:sreg_64 = V_MAD_U64_U32_e64 %3,  %3, %5, 0, implicit $exec
-    %9:vgpr_32 = COPY %8.sub0
+    %0:vreg_64, %1:sreg_64 = V_MAD_U64_U32_e64 $vgpr3, $vgpr3, $vgpr4_vgpr5, 0, implicit $exec
+    %2:vgpr_32 = COPY %1.sub0
 
     S_ENDPGM 0
 ...
-
-## NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-# CHECK: {{.*}}

>From 271db4cc7f7536e733da6bc0ea4db513ca8aae72 Mon Sep 17 00:00:00 2001
From: Frederik Harwath <fharwath at amd.com>
Date: Fri, 19 Dec 2025 09:10:16 -0500
Subject: [PATCH 3/3] Remove duplicate liveins from test

---
 llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir b/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
index d4072126c7b4e..d4f4b2b8a1465 100644
--- a/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
+++ b/llvm/test/CodeGen/MIR/AMDGPU/mir-canon-multi-def.mir
@@ -6,11 +6,10 @@ name: multi_def_renaming
 tracksRegLiveness: true
 body:             |
   bb.0:
-    liveins: $sgpr0_sgpr1, $vgpr3
     liveins: $vgpr3, $vgpr4_vgpr5
 
     ; CHECK-LABEL: name: multi_def_renaming
-    ; CHECK: liveins: $sgpr0_sgpr1, $vgpr3, $vgpr3, $vgpr4_vgpr5
+    ; CHECK: liveins: $vgpr3, $vgpr4_vgpr5
     ; CHECK-NEXT: {{  $}}
     ; CHECK-NEXT: %bb0_cb7ce318324a7ba8__1:vreg_64, %bb0_cb7ce318324a7ba8__2:sreg_64 = V_MAD_U64_U32_e64 $vgpr3, $vgpr3, $vgpr4_vgpr5, 0, implicit $exec
     ; CHECK-NEXT: %bb0_640fe5cc4c57ace5__1:vgpr_32 = COPY %bb0_cb7ce318324a7ba8__2.sub0



More information about the llvm-commits mailing list