[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