[llvm] [AMDGPU] Pre-commit test for redundant s_wait_xcnt after implicit XCN… (PR #198772)
Dark Steve via llvm-commits
llvm-commits at lists.llvm.org
Wed May 20 05:59:27 PDT 2026
https://github.com/PrasoonMishra created https://github.com/llvm/llvm-project/pull/198772
…T drain
Demonstrates that `SIInsertWaitcnts` currently emits `s_wait_xcnt 0x0` after instructions that already drain XCNT in hardware on gfx1250: `s_barrier_wait`, `s_barrier_signal`, `s_barrier_signal_isfirst`, `s_sendmsg`, PC-changing terminators etc.
>From 0dc88c2b74bbffd099c8ac55ab7303c4f46c9459 Mon Sep 17 00:00:00 2001
From: Dark Steve <Prasoon.Mishra at amd.com>
Date: Wed, 20 May 2026 09:59:07 +0000
Subject: [PATCH] [AMDGPU] Pre-commit test for redundant s_wait_xcnt after
implicit XCNT drain
Demonstrates that SIInsertWaitcnts currently emits an s_wait_xcnt 0x0
right after instructions that already drain XCNT in hardware on gfx1250:
s_barrier_wait, s_barrier_signal, s_barrier_signal_isfirst, s_sendmsg,
PC-changing terminators etc.
---
llvm/test/CodeGen/AMDGPU/wait-xcnt-drain.ll | 137 ++++++++++++++++++++
1 file changed, 137 insertions(+)
create mode 100644 llvm/test/CodeGen/AMDGPU/wait-xcnt-drain.ll
diff --git a/llvm/test/CodeGen/AMDGPU/wait-xcnt-drain.ll b/llvm/test/CodeGen/AMDGPU/wait-xcnt-drain.ll
new file mode 100644
index 0000000000000..d21cba6e27d70
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/wait-xcnt-drain.ll
@@ -0,0 +1,137 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 < %s | FileCheck %s
+
+define amdgpu_kernel void @drain_barrier_wait(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %a, i32 %b) {
+; CHECK-LABEL: drain_barrier_wait:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_clause 0x1
+; CHECK-NEXT: s_load_b64 s[6:7], s[4:5], 0x10 nv
+; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s6
+; CHECK-NEXT: v_mov_b32_e32 v2, s7
+; CHECK-NEXT: global_store_b32 v0, v1, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_barrier_wait 1
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b32 v0, v2, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_endpgm
+ store volatile i32 %a, ptr addrspace(1) %p
+ call void @llvm.amdgcn.s.barrier.wait(i16 1)
+ store volatile i32 %b, ptr addrspace(1) %q
+ ret void
+}
+
+define amdgpu_kernel void @drain_barrier_signal(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %a, i32 %b) {
+; CHECK-LABEL: drain_barrier_signal:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_clause 0x1
+; CHECK-NEXT: s_load_b64 s[6:7], s[4:5], 0x10 nv
+; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s6
+; CHECK-NEXT: v_mov_b32_e32 v2, s7
+; CHECK-NEXT: global_store_b32 v0, v1, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_barrier_signal 1
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b32 v0, v2, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_endpgm
+ store volatile i32 %a, ptr addrspace(1) %p
+ call void @llvm.amdgcn.s.barrier.signal(i32 1)
+ store volatile i32 %b, ptr addrspace(1) %q
+ ret void
+}
+
+define amdgpu_kernel void @drain_barrier_signal_isfirst(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %a, i32 %b) {
+; CHECK-LABEL: drain_barrier_signal_isfirst:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_clause 0x1
+; CHECK-NEXT: s_load_b64 s[6:7], s[4:5], 0x10 nv
+; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
+; CHECK-NEXT: v_mov_b32_e32 v0, 0
+; CHECK-NEXT: s_cmp_eq_u32 0, 0
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v1, s6 :: v_dual_mov_b32 v2, s7
+; CHECK-NEXT: global_store_b32 v0, v1, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_barrier_signal_isfirst 1
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b32 v0, v2, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_endpgm
+ store volatile i32 %a, ptr addrspace(1) %p
+ %r = call i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 1)
+ store volatile i32 %b, ptr addrspace(1) %q
+ ret void
+}
+
+define amdgpu_kernel void @drain_sendmsg(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %a, i32 %b) {
+; CHECK-LABEL: drain_sendmsg:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_clause 0x1
+; CHECK-NEXT: s_load_b64 s[6:7], s[4:5], 0x10 nv
+; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
+; CHECK-NEXT: v_mov_b32_e32 v0, 0
+; CHECK-NEXT: s_mov_b32 m0, 0
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v1, s6 :: v_dual_mov_b32 v2, s7
+; CHECK-NEXT: global_store_b32 v0, v1, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_sendmsg sendmsg(MSG_INTERRUPT)
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b32 v0, v2, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_endpgm
+ store volatile i32 %a, ptr addrspace(1) %p
+ call void @llvm.amdgcn.s.sendmsg(i32 1, i32 0)
+ store volatile i32 %b, ptr addrspace(1) %q
+ ret void
+}
+
+define amdgpu_kernel void @drain_cbranch(ptr addrspace(1) %p, ptr addrspace(1) %q, i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: drain_cbranch:
+; CHECK: ; %bb.0: ; %entry
+; CHECK-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0
+; CHECK-NEXT: s_clause 0x1
+; CHECK-NEXT: s_load_b96 s[8:10], s[4:5], 0x10 nv
+; CHECK-NEXT: s_load_b128 s[0:3], s[4:5], 0x0 nv
+; CHECK-NEXT: s_wait_kmcnt 0x0
+; CHECK-NEXT: v_dual_mov_b32 v0, 0 :: v_dual_mov_b32 v1, s8
+; CHECK-NEXT: s_cmp_lt_i32 s10, 1
+; CHECK-NEXT: global_store_b32 v0, v1, s[0:1] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_cbranch_scc1 .LBB4_2
+; CHECK-NEXT: ; %bb.1: ; %then
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: v_mov_b32_e32 v1, s9
+; CHECK-NEXT: global_store_b32 v0, v1, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_endpgm
+; CHECK-NEXT: .LBB4_2: ; %else
+; CHECK-NEXT: s_wait_xcnt 0x0
+; CHECK-NEXT: global_store_b32 v0, v0, s[2:3] scope:SCOPE_SYS
+; CHECK-NEXT: s_wait_storecnt 0x0
+; CHECK-NEXT: s_endpgm
+entry:
+ store volatile i32 %a, ptr addrspace(1) %p
+ %cond = icmp sgt i32 %c, 0
+ br i1 %cond, label %then, label %else
+then:
+ store volatile i32 %b, ptr addrspace(1) %q
+ ret void
+else:
+ store volatile i32 0, ptr addrspace(1) %q
+ ret void
+}
+
+declare void @llvm.amdgcn.s.barrier.wait(i16 immarg)
+declare void @llvm.amdgcn.s.barrier.signal(i32 immarg)
+declare i1 @llvm.amdgcn.s.barrier.signal.isfirst(i32 immarg)
+declare void @llvm.amdgcn.s.sendmsg(i32 immarg, i32)
More information about the llvm-commits
mailing list