[llvm] CodeGen: Record tied virtual register operands in finalizeBundle (PR #166209)
Nicolai Hähnle via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 4 10:59:17 PST 2025
https://github.com/nhaehnle updated https://github.com/llvm/llvm-project/pull/166209
>From f13a14b93c308732c71438788f2d8b0e60ea8687 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicolai=20H=C3=A4hnle?= <nicolai.haehnle at amd.com>
Date: Thu, 18 Sep 2025 16:38:50 -0700
Subject: [PATCH] CodeGen: Record tied virtual register operands in
finalizeBundle
This is in preparation of a future AMDGPU change where we are going to
create bundles before register allocation and want to rely on the
TwoAddressInstructionPass handling those bundles correctly.
v2:
- simplify the virtual register check and the test
commit-id:64872792
---
llvm/lib/CodeGen/MachineInstrBundle.cpp | 22 ++++++++++++++++++++-
llvm/test/CodeGen/AMDGPU/finalizebundle.mir | 2 +-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/MachineInstrBundle.cpp b/llvm/lib/CodeGen/MachineInstrBundle.cpp
index da29ffc9d2fed..88d81993fbe55 100644
--- a/llvm/lib/CodeGen/MachineInstrBundle.cpp
+++ b/llvm/lib/CodeGen/MachineInstrBundle.cpp
@@ -136,6 +136,7 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB,
SmallSetVector<Register, 8> ExternUses;
SmallSet<Register, 8> KilledUseSet;
SmallSet<Register, 8> UndefUseSet;
+ SmallVector<std::pair<Register, Register>> TiedOperands;
for (auto MII = FirstMI; MII != LastMI; ++MII) {
// Debug instructions have no effects to track.
if (MII->isDebugInstr())
@@ -161,6 +162,15 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB,
// External def is now killed.
KilledUseSet.insert(Reg);
}
+ if (MO.isTied() && Reg.isVirtual()) {
+ // Record tied operand constraints that involve virtual registers so
+ // that bundles that are formed pre-register allocation reflect the
+ // relevant constraints.
+ unsigned TiedIdx = MII->findTiedOperandIdx(MO.getOperandNo());
+ MachineOperand &TiedMO = MII->getOperand(TiedIdx);
+ Register DefReg = TiedMO.getReg();
+ TiedOperands.emplace_back(DefReg, Reg);
+ }
}
}
@@ -203,7 +213,17 @@ void llvm::finalizeBundle(MachineBasicBlock &MBB,
bool isKill = KilledUseSet.contains(Reg);
bool isUndef = UndefUseSet.contains(Reg);
MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
- getImplRegState(true));
+ getImplRegState(true));
+ }
+
+ for (auto [DefReg, UseReg] : TiedOperands) {
+ unsigned DefIdx =
+ std::distance(LocalDefs.begin(), llvm::find(LocalDefs, DefReg));
+ unsigned UseIdx =
+ std::distance(ExternUses.begin(), llvm::find(ExternUses, UseReg));
+ assert(DefIdx < LocalDefs.size());
+ assert(UseIdx < ExternUses.size());
+ MIB->tieOperands(DefIdx, LocalDefs.size() + UseIdx);
}
}
diff --git a/llvm/test/CodeGen/AMDGPU/finalizebundle.mir b/llvm/test/CodeGen/AMDGPU/finalizebundle.mir
index d2ec1fcbac84f..279f4298e6418 100644
--- a/llvm/test/CodeGen/AMDGPU/finalizebundle.mir
+++ b/llvm/test/CodeGen/AMDGPU/finalizebundle.mir
@@ -40,7 +40,7 @@ name: test_tied
body: |
bb.0:
; CHECK-LABEL: name: test_tied
- ; CHECK: BUNDLE implicit-def %0, implicit-def %2, implicit %1:vgpr_32, implicit $mode, implicit $exec {
+ ; CHECK: BUNDLE implicit-def %0, implicit-def %2, implicit %1:vgpr_32(tied-def 1), implicit $mode, implicit $exec {
; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr_32 = COPY %1:vgpr_32
; CHECK-NEXT: [[V_FMAC_F16_e32_:%[0-9]+]]:vgpr_32 = V_FMAC_F16_e32 internal [[COPY]], internal [[COPY]], %1:vgpr_32, implicit $mode, implicit $exec
; CHECK-NEXT: }
More information about the llvm-commits
mailing list