[llvm] [AMDGPU] Do not treat LDSDMA as VALU in several passes (PR #212866)
Akash Dutta via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 06:57:13 PDT 2026
https://github.com/akadutta updated https://github.com/llvm/llvm-project/pull/212866
>From a8fc519116a5261103accc360de1a8feef67feba Mon Sep 17 00:00:00 2001
From: akadutta_amdeng <Akash.Dutta at amd.com>
Date: Wed, 29 Jul 2026 15:10:42 -0500
Subject: [PATCH 1/5] Do not treat LDSDMA as VALU in several passes
---
.../AMDGPU/AMDGPUCoExecSchedStrategy.cpp | 2 +-
.../lib/Target/AMDGPU/AMDGPUHazardLatency.cpp | 4 ++--
llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp | 4 ++--
.../Target/AMDGPU/AMDGPUInsertDelayAlu.cpp | 20 +++++++++++--------
.../Target/AMDGPU/AMDGPUSetWavePriority.cpp | 4 ++--
.../Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp | 2 +-
.../lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 10 ++++------
llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 2 +-
llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 10 +++++-----
llvm/lib/Target/AMDGPU/SIInstrInfo.h | 4 ++--
llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp | 2 +-
11 files changed, 33 insertions(+), 31 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCoExecSchedStrategy.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCoExecSchedStrategy.cpp
index 504c3aae6ca57..ed122c1a55b4c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCoExecSchedStrategy.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCoExecSchedStrategy.cpp
@@ -65,7 +65,7 @@ InstructionFlavor llvm::AMDGPU::classifyFlavor(const MachineInstr &MI,
if (SII.isTRANS(MI))
return InstructionFlavor::TRANS;
- if (SII.isVALU(MI, /*AllowLDSDMA=*/true))
+ if (SII.isVALU(MI, /*AllowLDSDMA=*/false))
return InstructionFlavor::SingleCycleVALU;
if (SII.isDS(MI))
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUHazardLatency.cpp b/llvm/lib/Target/AMDGPU/AMDGPUHazardLatency.cpp
index 8825b3b8cb938..02416a4ef4cbc 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUHazardLatency.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUHazardLatency.cpp
@@ -48,7 +48,7 @@ void HazardLatency::apply(ScheduleDAGInstrs *DAG) {
for (SUnit &SU : DAG->SUnits) {
const MachineInstr *MI = SU.getInstr();
- if (!SIInstrInfo::isVALU(*MI, /*AllowLDSDMA=*/true))
+ if (!SIInstrInfo::isVALU(*MI, /*AllowLDSDMA=*/false))
continue;
if (MI->getOpcode() == AMDGPU::V_READLANE_B32 ||
MI->getOpcode() == AMDGPU::V_READFIRSTLANE_B32)
@@ -59,7 +59,7 @@ void HazardLatency::apply(ScheduleDAGInstrs *DAG) {
// Boost latency on VALU writes to SGPRs used by VALUs.
// Reduce risk of premature VALU pipeline stall on associated reads.
MachineInstr *DestMI = SuccDep.getSUnit()->getInstr();
- if (!SIInstrInfo::isVALU(*DestMI, /*AllowLDSDMA=*/true))
+ if (!SIInstrInfo::isVALU(*DestMI, /*AllowLDSDMA=*/false))
continue;
Register Reg = SuccDep.getReg();
if (!TRI.isSGPRReg(MRI, Reg))
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
index df7e80d62e065..4e40cac072414 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUIGroupLP.cpp
@@ -2593,8 +2593,8 @@ bool SchedGroup::canAddMI(const MachineInstr &MI) const {
Result = !MI.mayLoadOrStore();
else if (((SGMask & SchedGroupMask::VALU) != SchedGroupMask::NONE) &&
- TII->isVALU(MI, /*AllowLDSDMA=*/true) && !TII->isMFMAorWMMA(MI) &&
- !TII->isTRANS(MI) && !TII->isLDSDMA(MI)) {
+ TII->isVALU(MI, /*AllowLDSDMA=*/false) && !TII->isMFMAorWMMA(MI) &&
+ !TII->isTRANS(MI)) {
// Some memory instructions may be marked as VALU (e.g. BUFFER_LOAD_*_LDS).
// For our purposes, these shall not be classified as VALU as this results
// in unexpected behavior.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp
index 21de56463eae2..21c6a35b52e08 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInsertDelayAlu.cpp
@@ -66,7 +66,7 @@ class AMDGPUInsertDelayAlu {
enum DelayType { VALU, TRANS, SALU, OTHER };
// Get the delay type for a MachineInstr.
- DelayType getDelayType(const MachineInstr &MI) {
+ DelayType getDelayType(const MachineInstr &MI, bool AllowLDSDMA) {
// Non-F64 TRANS instructions use a separate delay type.
if (SIInstrInfo::isTRANS(MI) &&
!AMDGPU::isDPMACCInstruction(MI.getOpcode()))
@@ -74,7 +74,7 @@ class AMDGPUInsertDelayAlu {
// WMMA XDL ops are treated the same as TRANS.
if (ST->hasGFX1250Insts() && SII->isXDLWMMA(MI))
return TRANS;
- if (SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true))
+ if (SIInstrInfo::isVALU(MI, AllowLDSDMA))
return VALU;
if (SIInstrInfo::isSALU(MI))
return SALU;
@@ -372,7 +372,11 @@ class AMDGPUInsertDelayAlu {
continue;
}
- DelayType Type = getDelayType(MI);
+ // LDSDMA is VALU-tagged but only behaves like VALU for operand-use delay
+ // checks (e.g. v_readfirstlane -> tensor_load_to_lds). It must not
+ // publish or advance VALU delay state on its defs.
+ DelayType ProducerType = getDelayType(MI, /*AllowLDSDMA=*/false);
+ DelayType ConsumerType = getDelayType(MI, /*AllowLDSDMA=*/true);
if (instructionWaitsForSGPRWrites(MI)) {
auto It = State.find(LastSGPRFromVALU);
@@ -388,7 +392,7 @@ class AMDGPUInsertDelayAlu {
// Forget about all outstanding VALU delays.
// TODO: This is overkill since it also forgets about SALU delays.
State = DelayState();
- } else if (Type != OTHER) {
+ } else if (ConsumerType != OTHER) {
DelayInfo Delay;
// TODO: Scan implicit uses too?
for (const auto &Op : MI.explicit_uses()) {
@@ -408,7 +412,7 @@ class AMDGPUInsertDelayAlu {
}
}
- if (SII->isVALU(MI.getOpcode(), /*AllowLDSDMA=*/true)) {
+ if (ProducerType == VALU) {
for (const auto &Op : MI.defs()) {
Register Reg = Op.getReg();
if (AMDGPU::isSGPR(Reg, TRI)) {
@@ -425,13 +429,13 @@ class AMDGPUInsertDelayAlu {
}
}
- if (Type != OTHER) {
+ if (ProducerType != OTHER) {
// TODO: Scan implicit defs too?
for (const auto &Op : MI.defs()) {
unsigned Latency = SchedModel->computeOperandLatency(
&MI, Op.getOperandNo(), nullptr, 0);
for (MCRegUnit Unit : TRI->regunits(Op.getReg()))
- State[Unit] = DelayInfo(Type, Latency);
+ State[Unit] = DelayInfo(ProducerType, Latency);
}
}
@@ -442,7 +446,7 @@ class AMDGPUInsertDelayAlu {
// TODO: In wave64 mode, double the number of cycles for VALU and VMEM
// instructions on the assumption that they will usually have to be issued
// twice?
- State.advance(Type, Cycles);
+ State.advance(ProducerType, Cycles);
LLVM_DEBUG(dbgs() << " State after " << MI; State.dump(TRI););
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUSetWavePriority.cpp b/llvm/lib/Target/AMDGPU/AMDGPUSetWavePriority.cpp
index e3448be9f44f5..7d8297ed8d67c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUSetWavePriority.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUSetWavePriority.cpp
@@ -156,7 +156,7 @@ bool AMDGPUSetWavePriority::run(MachineFunction &MF) {
MaxNumVALUInstsInMiddle =
std::max(MaxNumVALUInstsInMiddle, NumVALUInstsAtEnd);
NumVALUInstsAtEnd = 0;
- } else if (SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true)) {
+ } else if (SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/false)) {
if (AtStart)
++MBBInfos[MBB].NumVALUInstsAtStart;
++NumVALUInstsAtEnd;
@@ -189,7 +189,7 @@ bool AMDGPUSetWavePriority::run(MachineFunction &MF) {
// Raise the priority at the beginning of the shader.
MachineBasicBlock::iterator I = Entry.begin(), E = Entry.end();
- while (I != E && !SIInstrInfo::isVALU(*I, /*AllowLDSDMA=*/true) &&
+ while (I != E && !SIInstrInfo::isVALU(*I, /*AllowLDSDMA=*/false) &&
!I->isTerminator())
++I;
BuildSetprioMI(Entry, I, HighPriority);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp b/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
index 51860f195cce7..c5e89dae32f7c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
@@ -275,7 +275,7 @@ class AMDGPUWaitSGPRHazards {
}
// Process only VALUs and SALUs
- bool IsVALU = SIInstrInfo::isVALU(*MI, /*AllowLDSDMA=*/true);
+ bool IsVALU = SIInstrInfo::isVALU(*MI, /*AllowLDSDMA=*/false);
bool IsSALU = SIInstrInfo::isSALU(*MI);
if (!IsVALU && !IsSALU)
continue;
diff --git a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
index af326d60aacb4..35e468ffd7931 100644
--- a/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNHazardRecognizer.cpp
@@ -179,8 +179,7 @@ static bool isPermlane(const MachineInstr &MI) {
}
static bool isLdsDma(const MachineInstr &MI) {
- return SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true) &&
- (SIInstrInfo::isMUBUF(MI) || SIInstrInfo::isFLAT(MI));
+ return SIInstrInfo::isLDSDMA(MI);
}
static unsigned getHWReg(const SIInstrInfo *TII, const MachineInstr &RegInstr) {
@@ -1067,7 +1066,7 @@ int GCNHazardRecognizer::checkVALUHazardsHelper(
/// none exists.
static const MachineOperand *
getDstSelForwardingOperand(const MachineInstr &MI, const GCNSubtarget &ST) {
- if (!SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true))
+ if (!SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/false))
return nullptr;
const SIInstrInfo *TII = ST.getInstrInfo();
@@ -2136,9 +2135,8 @@ bool GCNHazardRecognizer::fixWMMAHazards(MachineInstr *MI) {
}
static bool isCoexecutableVALUInst(const MachineInstr &MI) {
- return SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true) &&
- !SIInstrInfo::isWMMA(MI) && !SIInstrInfo::isSWMMAC(MI) &&
- !SIInstrInfo::isLDSDMA(MI);
+ return SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/false) &&
+ !SIInstrInfo::isWMMA(MI) && !SIInstrInfo::isSWMMAC(MI);
}
// Classify XDL WMMA instructions into co-execution hazard categories
diff --git a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
index 22247238d5542..13bd27cfc4926 100644
--- a/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp
@@ -1447,7 +1447,7 @@ MCPhysReg WaitcntBrackets::determineVGPR16Dependency(const MachineInstr &MI,
if (!Wait.hasWait())
return Reg;
- if (Context->TII.isVALU(MI, /*AllowLDSDMA=*/true))
+ if (Context->TII.isVALU(MI, /*AllowLDSDMA=*/false))
return Reg32;
// If hi/lo16 mixed events
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 28914d598a72d..013752326d4d0 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -2793,7 +2793,7 @@ bool SIInstrInfo::isLegalToSwap(const MachineInstr &MI, unsigned OpIdx0,
// It may move literal to position other than src0, this is not allowed
// pre-gfx10 However, most test cases need literals in Src0 for VOP
// FIXME: After gfx9, literal can be in place other than Src0
- if (isVALU(MI, /*AllowLDSDMA=*/true)) {
+ if (isVALU(MI, /*AllowLDSDMA=*/false)) {
if ((int)OpIdx0 == Src0Idx && !MO0.isReg() &&
!isInlineConstant(MO0, OpInfo1))
return false;
@@ -5497,7 +5497,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
}
// Verify VOP*. Ignore multiple sgpr operands on writelane.
- if (isVALU(MI, /*AllowLDSDMA=*/true) &&
+ if (isVALU(MI, /*AllowLDSDMA=*/false) &&
Desc.getOpcode() != AMDGPU::V_WRITELANE_B32) {
unsigned ConstantBusCount = 0;
bool UsesLiteral = false;
@@ -6522,7 +6522,7 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
const bool IsInlineConst = !MO->isReg() && isInlineConstant(*MO, OpInfo);
- if (isVALU(MI, /*AllowLDSDMA=*/true) && !IsInlineConst &&
+ if (isVALU(MI, /*AllowLDSDMA=*/false) && !IsInlineConst &&
usesConstantBus(MRI, *MO, OpInfo)) {
const MachineOperand *UsedLiteral = nullptr;
@@ -6641,7 +6641,7 @@ bool SIInstrInfo::isNeverCoissue(MachineInstr &MI) const {
if (!IsGFX950Only && !IsGFX940Only)
return false;
- if (!isVALU(MI, /*AllowLDSDMA=*/true))
+ if (!isVALU(MI, /*AllowLDSDMA=*/false))
return false;
// V_COS, V_EXP, V_RCP, etc.
@@ -10048,7 +10048,7 @@ unsigned SIInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
// Instructions may have a 32-bit literal encoded after them. Check
// operands that could ever be literals.
- if (isVALU(MI, /*AllowLDSDMA=*/true) || isSALU(MI)) {
+ if (isVALU(MI, /*AllowLDSDMA=*/false) || isSALU(MI)) {
if (isDPP(MI))
return DescSize;
bool HasLiteral = false;
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index 8e15b7b45b609..54cbd188b3a23 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -874,13 +874,13 @@ class SIInstrInfo final : public AMDGPUGenInstrInfo {
static bool isVGPRSpill(const MachineInstr &MI) {
return MI.getOpcode() != AMDGPU::SI_SPILL_S32_TO_VGPR &&
MI.getOpcode() != AMDGPU::SI_RESTORE_S32_FROM_VGPR &&
- (isSpill(MI) && isVALU(MI, /*AllowLDSDMA=*/true));
+ (isSpill(MI) && isVALU(MI, /*AllowLDSDMA=*/false));
}
bool isVGPRSpill(uint32_t Opcode) const {
return Opcode != AMDGPU::SI_SPILL_S32_TO_VGPR &&
Opcode != AMDGPU::SI_RESTORE_S32_FROM_VGPR &&
- (isSpill(Opcode) && isVALU(Opcode, /*AllowLDSDMA=*/true));
+ (isSpill(Opcode) && isVALU(Opcode, /*AllowLDSDMA=*/false));
}
static bool isSGPRSpill(const MachineInstr &MI) {
diff --git a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp
index 15c28ac8ff948..43bd825ec180f 100644
--- a/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerControlFlow.cpp
@@ -381,7 +381,7 @@ void SILowerControlFlow::emitIfBreak(MachineInstr &MI) {
if (MI.getOperand(1).isReg()) {
if (MachineInstr *Def = MRI->getUniqueVRegDef(MI.getOperand(1).getReg())) {
SkipAnding = Def->getParent() == MI.getParent() &&
- SIInstrInfo::isVALU(*Def, /*AllowLDSDMA=*/true);
+ SIInstrInfo::isVALU(*Def, /*AllowLDSDMA=*/false);
}
}
>From 60851ada6ac9b429bb96585b7da348ff7bdf473f Mon Sep 17 00:00:00 2001
From: akadutta_amdeng <Akash.Dutta at amd.com>
Date: Thu, 30 Jul 2026 12:51:46 -0500
Subject: [PATCH 2/5] add new tests
---
.../AMDGPU/insert-delay-alu-ldsdma.mir | 33 +++++++++++++++++++
.../CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir | 20 +++++++++++
.../AMDGPU/ldsdma-not-valu-wait-sgpr.mir | 28 ++++++++++++++++
3 files changed, 81 insertions(+)
create mode 100644 llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
create mode 100644 llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
create mode 100644 llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
diff --git a/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir b/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
new file mode 100644
index 0000000000000..42f1d019ab516
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
@@ -0,0 +1,33 @@
+# Verify LDSDMA delay-alu handling: LDSDMA consumes VALU delay state on its
+# SGPR operands but must not publish VALU delay state from its defs.
+# RUN: llc -mtriple=amdgpu12.50 -start-before=amdgpu-insert-delay-alu %s -o - | FileCheck %s
+
+---
+name: ldsdma_consumer_needs_delay
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: {{^}}ldsdma_consumer_needs_delay:
+ ; CHECK: v_readfirstlane_b32
+ ; CHECK: s_delay_alu instid0(VALU_DEP_1)
+ ; CHECK: tensor_load_to_lds
+ liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ $sgpr0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ S_ENDPGM 0
+
+---
+name: ldsdma_not_valu_producer
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: {{^}}ldsdma_not_valu_producer:
+ ; CHECK: v_add_nc_u32_e32 v0, v0, v0
+ ; CHECK-NEXT: tensor_load_to_lds
+ ; CHECK-NEXT: s_delay_alu instid0(VALU_DEP_1)
+ ; CHECK-NEXT: v_add_nc_u32_e32 v0, v0, v0
+ liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, $exec
+ $vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
+ TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ $vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
+ S_ENDPGM 0
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
new file mode 100644
index 0000000000000..be3fc5cf1f51b
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
@@ -0,0 +1,20 @@
+# LDSDMA must not count as a co-executable VALU when filling WMMA hazard gaps.
+# RUN: llc -mtriple=amdgpu12.50 -run-pass=post-RA-hazard-rec %s -o - | FileCheck %s
+
+---
+name: ldsdma_not_coexec_valu_gap
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: ldsdma_not_coexec_valu_gap
+ ; CHECK: V_WMMA_F32_16X16X32_BF16
+ ; CHECK: TENSOR_LOAD_TO_LDS
+ ; CHECK: V_NOP_e32
+ ; CHECK: V_NOP_e32
+ ; CHECK: V_NOP_e32
+ ; CHECK: V_ADD_F32_e32
+ liveins: $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, $vgpr24, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23 = V_WMMA_F32_16X16X32_BF16_w32_twoaddr $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, 8, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, 0, 0, 0, 0, implicit $exec
+ TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ $vgpr24 = V_ADD_F32_e32 $vgpr24, $vgpr16, implicit $mode, implicit $exec
+ S_ENDPGM 0
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
new file mode 100644
index 0000000000000..e4419353efd28
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
@@ -0,0 +1,28 @@
+# LDSDMA must not be treated as VALU by amdgpu-wait-sgpr-hazards. A tensor/async
+# load between a VALU SGPR write and its consumer must not clear the hazard.
+# RUN: llc -mtriple=amdgpu11.00 -mattr=+wavefrontsize64 -verify-machineinstrs -run-pass post-RA-hazard-rec,amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
+
+--- |
+ define amdgpu_gs void @ldsdma_not_valu_for_sgpr_hazard() { ret void }
+
+---
+name: ldsdma_not_valu_for_sgpr_hazard
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: ldsdma_not_valu_for_sgpr_hazard
+ ; CHECK: V_CNDMASK_B32
+ ; CHECK: V_READFIRSTLANE_B32
+ ; CHECK: TENSOR_LOAD_TO_LDS
+ ; CHECK: S_WAITCNT_DEPCTR .VaSdst_0
+ ; CHECK: S_ENDPGM
+ $vgpr1 = IMPLICIT_DEF
+ $vgpr2 = IMPLICIT_DEF
+ $vgpr3 = IMPLICIT_DEF
+ $sgpr2_sgpr3 = IMPLICIT_DEF
+ $vgpr1 = V_CNDMASK_B32_e64 0, $vgpr1, 0, $vgpr2, $sgpr2_sgpr3, implicit $exec
+ $sgpr2 = V_READFIRSTLANE_B32 $vgpr3, implicit $exec
+ %0:sgpr_128 = IMPLICIT_DEF
+ %1:sgpr_256 = IMPLICIT_DEF
+ TENSOR_LOAD_TO_LDS_d2_gfx1250 %0, %1, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ S_ENDPGM 0
>From cdf08340ecab011c6b576e88b0e1a54f07542f02 Mon Sep 17 00:00:00 2001
From: akadutta_amdeng <Akash.Dutta at amd.com>
Date: Thu, 13 Aug 2026 07:48:31 -0500
Subject: [PATCH 3/5] fix tests
---
llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir | 2 ++
llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir | 1 +
llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir | 4 +++-
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir b/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
index 42f1d019ab516..9c692581dce45 100644
--- a/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
+++ b/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
@@ -15,6 +15,7 @@ body: |
$sgpr0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
S_ENDPGM 0
+...
---
name: ldsdma_not_valu_producer
@@ -31,3 +32,4 @@ body: |
TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
$vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
S_ENDPGM 0
+...
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
index be3fc5cf1f51b..a4b28d6a101ab 100644
--- a/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
@@ -18,3 +18,4 @@ body: |
TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
$vgpr24 = V_ADD_F32_e32 $vgpr24, $vgpr16, implicit $mode, implicit $exec
S_ENDPGM 0
+...
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
index e4419353efd28..4322004805109 100644
--- a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
@@ -1,9 +1,10 @@
# LDSDMA must not be treated as VALU by amdgpu-wait-sgpr-hazards. A tensor/async
# load between a VALU SGPR write and its consumer must not clear the hazard.
-# RUN: llc -mtriple=amdgpu11.00 -mattr=+wavefrontsize64 -verify-machineinstrs -run-pass post-RA-hazard-rec,amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
+# RUN: llc -mtriple=amdgpu11.00 -mattr=+wavefrontsize64 -run-pass post-RA-hazard-rec,amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
--- |
define amdgpu_gs void @ldsdma_not_valu_for_sgpr_hazard() { ret void }
+...
---
name: ldsdma_not_valu_for_sgpr_hazard
@@ -26,3 +27,4 @@ body: |
%1:sgpr_256 = IMPLICIT_DEF
TENSOR_LOAD_TO_LDS_d2_gfx1250 %0, %1, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
S_ENDPGM 0
+...
>From 59a8e650bacfc222968c1f20b69fdbdf4f7119bd Mon Sep 17 00:00:00 2001
From: akadutta_amdeng <Akash.Dutta at amd.com>
Date: Thu, 13 Aug 2026 16:18:32 -0500
Subject: [PATCH 4/5] update tests
---
.../AMDGPU/insert-delay-alu-ldsdma.mir | 33 +++++++++-----
.../CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir | 32 ++++++++------
.../AMDGPU/ldsdma-not-valu-wait-sgpr.mir | 43 +++++++++++--------
3 files changed, 66 insertions(+), 42 deletions(-)
diff --git a/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir b/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
index 9c692581dce45..5263f41d4d792 100644
--- a/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
+++ b/llvm/test/CodeGen/AMDGPU/insert-delay-alu-ldsdma.mir
@@ -1,17 +1,23 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
# Verify LDSDMA delay-alu handling: LDSDMA consumes VALU delay state on its
# SGPR operands but must not publish VALU delay state from its defs.
-# RUN: llc -mtriple=amdgpu12.50 -start-before=amdgpu-insert-delay-alu %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu12.50 -run-pass=amdgpu-insert-delay-alu %s -o - | FileCheck %s
---
name: ldsdma_consumer_needs_delay
tracksRegLiveness: true
body: |
bb.0:
- ; CHECK-LABEL: {{^}}ldsdma_consumer_needs_delay:
- ; CHECK: v_readfirstlane_b32
- ; CHECK: s_delay_alu instid0(VALU_DEP_1)
- ; CHECK: tensor_load_to_lds
liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ ; CHECK-LABEL: name: ldsdma_consumer_needs_delay
+ ; CHECK: liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $exec = IMPLICIT_DEF
+ ; CHECK-NEXT: $sgpr0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
+ ; CHECK-NEXT: S_DELAY_ALU .id0_VALU_DEP_1
+ ; CHECK-NEXT: TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ ; CHECK-NEXT: S_ENDPGM 0
+ $exec = IMPLICIT_DEF
$sgpr0 = V_READFIRSTLANE_B32 $vgpr0, implicit $exec
TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
S_ENDPGM 0
@@ -22,12 +28,17 @@ name: ldsdma_not_valu_producer
tracksRegLiveness: true
body: |
bb.0:
- ; CHECK-LABEL: {{^}}ldsdma_not_valu_producer:
- ; CHECK: v_add_nc_u32_e32 v0, v0, v0
- ; CHECK-NEXT: tensor_load_to_lds
- ; CHECK-NEXT: s_delay_alu instid0(VALU_DEP_1)
- ; CHECK-NEXT: v_add_nc_u32_e32 v0, v0, v0
- liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, $exec
+ liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ ; CHECK-LABEL: name: ldsdma_not_valu_producer
+ ; CHECK: liveins: $vgpr0, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $exec = IMPLICIT_DEF
+ ; CHECK-NEXT: $vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
+ ; CHECK-NEXT: TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ ; CHECK-NEXT: S_DELAY_ALU .id0_VALU_DEP_1
+ ; CHECK-NEXT: $vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ $exec = IMPLICIT_DEF
$vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
$vgpr0 = V_ADD_U32_e32 $vgpr0, $vgpr0, implicit $exec
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
index a4b28d6a101ab..4182c7380072f 100644
--- a/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-coexec-valu.mir
@@ -1,21 +1,27 @@
-# LDSDMA must not count as a co-executable VALU when filling WMMA hazard gaps.
-# RUN: llc -mtriple=amdgpu12.50 -run-pass=post-RA-hazard-rec %s -o - | FileCheck %s
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# LDSDMA must not be treated as a co-executable VALU by the WMMA co-execution
+# hazard handling. Here the LDSDMA reads $vgpr16 (its vaddr), which overlaps the
+# WMMA result in $vgpr16_..._vgpr23. If LDSDMA were a co-executable VALU it would
+# be a hazard victim and require V_NOP padding after the WMMA; it must not be.
+# RUN: llc -mtriple=amdgpu12.50 -run-pass=post-RA-hazard-rec -o - %s | FileCheck %s
---
-name: ldsdma_not_coexec_valu_gap
+name: ldsdma_not_coexec_valu_victim
tracksRegLiveness: true
body: |
bb.0:
- ; CHECK-LABEL: name: ldsdma_not_coexec_valu_gap
- ; CHECK: V_WMMA_F32_16X16X32_BF16
- ; CHECK: TENSOR_LOAD_TO_LDS
- ; CHECK: V_NOP_e32
- ; CHECK: V_NOP_e32
- ; CHECK: V_NOP_e32
- ; CHECK: V_ADD_F32_e32
- liveins: $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, $vgpr24, $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11
+ liveins: $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, $sgpr0_sgpr1
+ ; CHECK-LABEL: name: ldsdma_not_coexec_valu_victim
+ ; CHECK: liveins: $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, $sgpr0_sgpr1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: $exec = IMPLICIT_DEF
+ ; CHECK-NEXT: $m0 = IMPLICIT_DEF
+ ; CHECK-NEXT: early-clobber $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23 = V_WMMA_F32_16X16X32_BF16_w32_twoaddr $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, 8, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, 0, 0, 0, 0, implicit $exec
+ ; CHECK-NEXT: GLOBAL_LOAD_LDS_DWORD_SADDR $sgpr0_sgpr1, $vgpr16, 0, 0, 0, implicit $m0, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ $exec = IMPLICIT_DEF
+ $m0 = IMPLICIT_DEF
$vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23 = V_WMMA_F32_16X16X32_BF16_w32_twoaddr $vgpr0_vgpr1_vgpr2_vgpr3_vgpr4_vgpr5_vgpr6_vgpr7, $vgpr8_vgpr9_vgpr10_vgpr11_vgpr12_vgpr13_vgpr14_vgpr15, 8, $vgpr16_vgpr17_vgpr18_vgpr19_vgpr20_vgpr21_vgpr22_vgpr23, 0, 0, 0, 0, implicit $exec
- TENSOR_LOAD_TO_LDS_d2_gfx1250 $sgpr0_sgpr1_sgpr2_sgpr3, $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
- $vgpr24 = V_ADD_F32_e32 $vgpr24, $vgpr16, implicit $mode, implicit $exec
+ GLOBAL_LOAD_LDS_DWORD_SADDR $sgpr0_sgpr1, $vgpr16, 0, 0, 0, implicit $m0, implicit $exec
S_ENDPGM 0
...
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
index 4322004805109..75564698e9d43 100644
--- a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
@@ -1,10 +1,10 @@
-# LDSDMA must not be treated as VALU by amdgpu-wait-sgpr-hazards. A tensor/async
-# load between a VALU SGPR write and its consumer must not clear the hazard.
-# RUN: llc -mtriple=amdgpu11.00 -mattr=+wavefrontsize64 -run-pass post-RA-hazard-rec,amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
-
---- |
- define amdgpu_gs void @ldsdma_not_valu_for_sgpr_hazard() { ret void }
-...
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# LDSDMA must not be treated as VALU by amdgpu-wait-sgpr-hazards. A VALU writes
+# an SGPR that the LDSDMA then reads (its saddr). If the LDSDMA counted as a VALU
+# reader, the pass would insert an S_WAITCNT_DEPCTR .VaSdst_0 before it; it must
+# not. This hazard pass only performs a full scan on gfx12 (not gfx11/gfx1250),
+# so the test targets gfx1200 and runs the pass on its own.
+# RUN: llc -mtriple=amdgpu12.00 -run-pass amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
---
name: ldsdma_not_valu_for_sgpr_hazard
@@ -12,19 +12,26 @@ tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: ldsdma_not_valu_for_sgpr_hazard
- ; CHECK: V_CNDMASK_B32
- ; CHECK: V_READFIRSTLANE_B32
- ; CHECK: TENSOR_LOAD_TO_LDS
- ; CHECK: S_WAITCNT_DEPCTR .VaSdst_0
- ; CHECK: S_ENDPGM
+ ; CHECK: $exec_lo = IMPLICIT_DEF
+ ; CHECK-NEXT: $vgpr0 = IMPLICIT_DEF
+ ; CHECK-NEXT: $vgpr1 = IMPLICIT_DEF
+ ; CHECK-NEXT: $vgpr2 = IMPLICIT_DEF
+ ; CHECK-NEXT: $vgpr3 = IMPLICIT_DEF
+ ; CHECK-NEXT: $sgpr4_sgpr5 = IMPLICIT_DEF
+ ; CHECK-NEXT: $m0 = IMPLICIT_DEF
+ ; CHECK-NEXT: $vgpr1 = V_CNDMASK_B32_e64 0, $vgpr1, 0, $vgpr2, $sgpr4, implicit $exec
+ ; CHECK-NEXT: $sgpr5 = V_READFIRSTLANE_B32 $vgpr3, implicit $exec
+ ; CHECK-NEXT: GLOBAL_LOAD_LDS_DWORD_SADDR $sgpr4_sgpr5, $vgpr0, 0, 0, 0, implicit $m0, implicit $exec
+ ; CHECK-NEXT: S_ENDPGM 0
+ $exec_lo = IMPLICIT_DEF
+ $vgpr0 = IMPLICIT_DEF
$vgpr1 = IMPLICIT_DEF
$vgpr2 = IMPLICIT_DEF
$vgpr3 = IMPLICIT_DEF
- $sgpr2_sgpr3 = IMPLICIT_DEF
- $vgpr1 = V_CNDMASK_B32_e64 0, $vgpr1, 0, $vgpr2, $sgpr2_sgpr3, implicit $exec
- $sgpr2 = V_READFIRSTLANE_B32 $vgpr3, implicit $exec
- %0:sgpr_128 = IMPLICIT_DEF
- %1:sgpr_256 = IMPLICIT_DEF
- TENSOR_LOAD_TO_LDS_d2_gfx1250 %0, %1, 0, 0, implicit-def dead $tensorcnt, implicit $exec, implicit $tensorcnt
+ $sgpr4_sgpr5 = IMPLICIT_DEF
+ $m0 = IMPLICIT_DEF
+ $vgpr1 = V_CNDMASK_B32_e64 0, $vgpr1, 0, $vgpr2, $sgpr4, implicit $exec
+ $sgpr5 = V_READFIRSTLANE_B32 $vgpr3, implicit $exec
+ GLOBAL_LOAD_LDS_DWORD_SADDR $sgpr4_sgpr5, $vgpr0, 0, 0, 0, implicit $m0, implicit $exec
S_ENDPGM 0
...
>From af55eb4e48591be796b6e6eb075153ba620a037f Mon Sep 17 00:00:00 2001
From: Akash Dutta <137309513+akadutta at users.noreply.github.com>
Date: Tue, 8 Sep 2026 08:57:02 -0500
Subject: [PATCH 5/5] Update
llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
Co-authored-by: Matt Arsenault <arsenm2 at gmail.com>
---
llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
index 75564698e9d43..279e0748f65ed 100644
--- a/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
+++ b/llvm/test/CodeGen/AMDGPU/ldsdma-not-valu-wait-sgpr.mir
@@ -4,7 +4,7 @@
# reader, the pass would insert an S_WAITCNT_DEPCTR .VaSdst_0 before it; it must
# not. This hazard pass only performs a full scan on gfx12 (not gfx11/gfx1250),
# so the test targets gfx1200 and runs the pass on its own.
-# RUN: llc -mtriple=amdgpu12.00 -run-pass amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
+# RUN: llc -mtriple=amdgpu12.00 -run-pass=amdgpu-wait-sgpr-hazards -o - %s | FileCheck %s
---
name: ldsdma_not_valu_for_sgpr_hazard
More information about the llvm-commits
mailing list