[llvm] [AMDGPU] Prevent GFX11 VALU Hazard Wait merging into terminators (PR #214935)
Carl Ritson via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 23:29:56 PDT 2026
https://github.com/perlfu created https://github.com/llvm/llvm-project/pull/214935
Fix an issue where a pending wait would be moved into the block terminators causing a validation error.
Flush all pending waits and exit optimization loop when reaching first terminator within a block.
>From f6ea6e98129baa449bd73efc53cd6517f9104d60 Mon Sep 17 00:00:00 2001
From: Carl Ritson <carl.ritson at amd.com>
Date: Sat, 8 Aug 2026 14:07:09 +0900
Subject: [PATCH] [AMDGPU] Prevent GFX11 VALU Hazard Wait merging into
terminators
Fix an issue where a pending wait would be moved into the block
terminators causing a validation error.
Flush all pending waits and exit optimization loop when reaching
first terminator within a block.
---
.../Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp | 15 ++++--
.../CodeGen/AMDGPU/valu-mask-write-hazard.mir | 51 +++++++++++++++++++
2 files changed, 61 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp b/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
index 51860f195cce7..279725e9388be 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUWaitSGPRHazards.cpp
@@ -478,9 +478,6 @@ class AMDGPUWaitSGPRHazards {
};
for (MachineInstr &MI : MBB) {
- if (MI.isMetaInstruction())
- continue;
-
if (MI.getOpcode() == AMDGPU::S_WAITCNT_DEPCTR &&
(MI.getOperand(0).getImm() & ConstantMaskBits) ==
ConstantMaskBits) {
@@ -500,12 +497,20 @@ class AMDGPUWaitSGPRHazards {
continue;
}
- // Do not optimize over branches
- if (PrevWait && (MI.isCall() || MI.isReturn() || MI.isBranch())) {
+ // Do not optimize over branches or terminators
+ if (PrevWait && (MI.isCall() || MI.isReturn() || MI.isBranch() ||
+ MI.isTerminator())) {
PrevWait->moveBefore(&MI);
PrevWait = nullptr;
Changed = true;
}
+ if (MI.isTerminator())
+ break;
+
+ // Note: test for meta instructions after terminators.
+ // Required to handle terminator meta instruction.
+ if (MI.isMetaInstruction())
+ continue;
const bool IsVALU = SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/false);
const bool IsSALU = SIInstrInfo::isSALU(MI);
diff --git a/llvm/test/CodeGen/AMDGPU/valu-mask-write-hazard.mir b/llvm/test/CodeGen/AMDGPU/valu-mask-write-hazard.mir
index d7034abfde61a..0b9754108463d 100644
--- a/llvm/test/CodeGen/AMDGPU/valu-mask-write-hazard.mir
+++ b/llvm/test/CodeGen/AMDGPU/valu-mask-write-hazard.mir
@@ -60,6 +60,7 @@
define amdgpu_gs void @mask_hazard_optimize1() { ret void }
define amdgpu_gs void @mask_hazard_optimize2() { ret void }
define amdgpu_gs void @mask_hazard_optimize3() { ret void }
+ define amdgpu_gs void @mask_hazard_optimize_terminators() { ret void }
...
---
@@ -1268,3 +1269,53 @@ body: |
$vgpr14 = V_CNDMASK_B32_e32 $sgpr49, killed $vgpr14, implicit killed $vcc, implicit $exec
$vgpr20 = V_ADD_U32_e32 $sgpr54, $vgpr16, implicit $exec
...
+
+---
+name: mask_hazard_optimize_terminators
+body: |
+ ; GFX11-LABEL: name: mask_hazard_optimize_terminators
+ ; GFX11: bb.0:
+ ; GFX11-NEXT: successors: %bb.1(0x80000000)
+ ; GFX11-NEXT: {{ $}}
+ ; GFX11-NEXT: $vgpr3 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
+ ; GFX11-NEXT: V_CMP_NE_U32_e32 0, $vgpr5, implicit-def $vcc, implicit $exec
+ ; GFX11-NEXT: $sgpr4 = S_MOV_B32 $sgpr1
+ ; GFX11-NEXT: $sgpr5 = S_MOV_B32 $sgpr2
+ ; GFX11-NEXT: S_WAITCNT_DEPCTR .VaVcc_0
+ ; GFX11-NEXT: $sgpr6 = S_MOV_B32_term $sgpr4
+ ; GFX11-NEXT: $sgpr7 = S_MOV_B32_term $sgpr5
+ ; GFX11-NEXT: S_BRANCH %bb.1
+ ; GFX11-NEXT: {{ $}}
+ ; GFX11-NEXT: bb.1:
+ ; GFX11-NEXT: $vgpr4 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
+ ; GFX11-NEXT: S_ENDPGM 0
+ ;
+ ; GFX12-LABEL: name: mask_hazard_optimize_terminators
+ ; GFX12: bb.0:
+ ; GFX12-NEXT: successors: %bb.1(0x80000000)
+ ; GFX12-NEXT: {{ $}}
+ ; GFX12-NEXT: $vgpr3 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
+ ; GFX12-NEXT: V_CMP_NE_U32_e32 0, $vgpr5, implicit-def $vcc, implicit $exec
+ ; GFX12-NEXT: $sgpr4 = S_MOV_B32 $sgpr1
+ ; GFX12-NEXT: $sgpr5 = S_MOV_B32 $sgpr2
+ ; GFX12-NEXT: $sgpr6 = S_MOV_B32_term $sgpr4
+ ; GFX12-NEXT: $sgpr7 = S_MOV_B32_term $sgpr5
+ ; GFX12-NEXT: S_BRANCH %bb.1
+ ; GFX12-NEXT: {{ $}}
+ ; GFX12-NEXT: bb.1:
+ ; GFX12-NEXT: S_WAITCNT_DEPCTR .VaVcc_0
+ ; GFX12-NEXT: $vgpr4 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
+ ; GFX12-NEXT: S_ENDPGM 0
+ bb.0:
+ $vgpr3 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
+ V_CMP_NE_U32_e32 0, $vgpr5, implicit-def $vcc, implicit $exec
+ $sgpr4 = S_MOV_B32 $sgpr1
+ $sgpr5 = S_MOV_B32 $sgpr2
+ $sgpr6 = S_MOV_B32_term $sgpr4
+ $sgpr7 = S_MOV_B32_term $sgpr5
+ S_BRANCH %bb.1
+
+ bb.1:
+ $vgpr4 = V_CNDMASK_B32_e32 $vgpr1, $vgpr2, implicit $vcc, implicit $exec
+ S_ENDPGM 0
+...
More information about the llvm-commits
mailing list