[llvm] AMDGPU: Add codegen for atomicrmw operations usub_cond and usub_sat (PR #141068)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 30 07:18:54 PDT 2025


================
@@ -0,0 +1,1558 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GFX9-SDAG %s
+; RUN: llc -global-isel=0 -mtriple=amdgcn -mcpu=gfx1200 -verify-machineinstrs < %s | FileCheck -check-prefixes=GFX12-SDAG %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -check-prefixes=GFX9-GISEL %s
+; RUN: llc -global-isel=1 -mtriple=amdgcn -mcpu=gfx1200 -verify-machineinstrs < %s | FileCheck -check-prefixes=GFX12-GISEL %s
+
+define amdgpu_kernel void @flat_atomic_usub_cond_no_rtn_u32(ptr %addr, i32 %in) {
+; GFX9-SDAG-LABEL: flat_atomic_usub_cond_no_rtn_u32:
+; GFX9-SDAG:       ; %bb.0: ; %entry
+; GFX9-SDAG-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GFX9-SDAG-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; GFX9-SDAG-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX9-SDAG-NEXT:    v_mov_b32_e32 v1, s1
+; GFX9-SDAG-NEXT:    v_add_co_u32_e64 v0, vcc, -16, s0
+; GFX9-SDAG-NEXT:    v_addc_co_u32_e32 v1, vcc, -1, v1, vcc
+; GFX9-SDAG-NEXT:    flat_load_dword v1, v[0:1]
+; GFX9-SDAG-NEXT:    s_add_u32 s4, s0, -16
+; GFX9-SDAG-NEXT:    s_addc_u32 s5, s1, -1
+; GFX9-SDAG-NEXT:    v_mov_b32_e32 v2, s4
+; GFX9-SDAG-NEXT:    s_mov_b64 s[0:1], 0
+; GFX9-SDAG-NEXT:    v_mov_b32_e32 v3, s5
+; GFX9-SDAG-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX9-SDAG-NEXT:    ; =>This Inner Loop Header: Depth=1
+; GFX9-SDAG-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-SDAG-NEXT:    v_subrev_u32_e32 v0, s2, v1
+; GFX9-SDAG-NEXT:    v_cmp_le_u32_e32 vcc, s2, v1
+; GFX9-SDAG-NEXT:    v_cndmask_b32_e32 v0, v1, v0, vcc
+; GFX9-SDAG-NEXT:    flat_atomic_cmpswap v0, v[2:3], v[0:1] glc
+; GFX9-SDAG-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-SDAG-NEXT:    buffer_wbinvl1_vol
+; GFX9-SDAG-NEXT:    v_cmp_eq_u32_e32 vcc, v0, v1
+; GFX9-SDAG-NEXT:    s_or_b64 s[0:1], vcc, s[0:1]
+; GFX9-SDAG-NEXT:    v_mov_b32_e32 v1, v0
+; GFX9-SDAG-NEXT:    s_andn2_b64 exec, exec, s[0:1]
+; GFX9-SDAG-NEXT:    s_cbranch_execnz .LBB0_1
+; GFX9-SDAG-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-SDAG-NEXT:    s_endpgm
+;
+; GFX12-SDAG-LABEL: flat_atomic_usub_cond_no_rtn_u32:
+; GFX12-SDAG:       ; %bb.0: ; %entry
+; GFX12-SDAG-NEXT:    s_load_b96 s[0:2], s[4:5], 0x24
+; GFX12-SDAG-NEXT:    s_wait_kmcnt 0x0
+; GFX12-SDAG-NEXT:    v_dual_mov_b32 v0, s0 :: v_dual_mov_b32 v1, s1
+; GFX12-SDAG-NEXT:    v_mov_b32_e32 v2, s2
+; GFX12-SDAG-NEXT:    global_wb scope:SCOPE_SYS
+; GFX12-SDAG-NEXT:    s_wait_storecnt 0x0
+; GFX12-SDAG-NEXT:    flat_atomic_cond_sub_u32 v[0:1], v2 offset:-16 scope:SCOPE_SYS
+; GFX12-SDAG-NEXT:    s_wait_storecnt_dscnt 0x0
+; GFX12-SDAG-NEXT:    global_inv scope:SCOPE_SYS
+; GFX12-SDAG-NEXT:    s_endpgm
+;
+; GFX9-GISEL-LABEL: flat_atomic_usub_cond_no_rtn_u32:
+; GFX9-GISEL:       ; %bb.0: ; %entry
+; GFX9-GISEL-NEXT:    s_load_dwordx2 s[0:1], s[4:5], 0x24
+; GFX9-GISEL-NEXT:    s_load_dword s2, s[4:5], 0x2c
+; GFX9-GISEL-NEXT:    s_waitcnt lgkmcnt(0)
+; GFX9-GISEL-NEXT:    s_add_u32 s0, s0, -16
+; GFX9-GISEL-NEXT:    s_addc_u32 s1, s1, -1
+; GFX9-GISEL-NEXT:    v_mov_b32_e32 v0, s0
+; GFX9-GISEL-NEXT:    v_mov_b32_e32 v1, s1
+; GFX9-GISEL-NEXT:    flat_load_dword v3, v[0:1]
+; GFX9-GISEL-NEXT:    s_mov_b64 s[0:1], 0
+; GFX9-GISEL-NEXT:  .LBB0_1: ; %atomicrmw.start
+; GFX9-GISEL-NEXT:    ; =>This Inner Loop Header: Depth=1
+; GFX9-GISEL-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-GISEL-NEXT:    v_subrev_u32_e32 v2, s2, v3
+; GFX9-GISEL-NEXT:    v_cmp_le_u32_e32 vcc, s2, v3
+; GFX9-GISEL-NEXT:    v_cndmask_b32_e32 v2, v3, v2, vcc
+; GFX9-GISEL-NEXT:    flat_atomic_cmpswap v2, v[0:1], v[2:3] glc
+; GFX9-GISEL-NEXT:    s_waitcnt vmcnt(0) lgkmcnt(0)
+; GFX9-GISEL-NEXT:    buffer_wbinvl1_vol
+; GFX9-GISEL-NEXT:    v_cmp_eq_u32_e32 vcc, v2, v3
+; GFX9-GISEL-NEXT:    s_or_b64 s[0:1], vcc, s[0:1]
+; GFX9-GISEL-NEXT:    v_mov_b32_e32 v3, v2
+; GFX9-GISEL-NEXT:    s_andn2_b64 exec, exec, s[0:1]
+; GFX9-GISEL-NEXT:    s_cbranch_execnz .LBB0_1
+; GFX9-GISEL-NEXT:  ; %bb.2: ; %atomicrmw.end
+; GFX9-GISEL-NEXT:    s_endpgm
+;
+; GFX12-GISEL-LABEL: flat_atomic_usub_cond_no_rtn_u32:
+; GFX12-GISEL:       ; %bb.0: ; %entry
+; GFX12-GISEL-NEXT:    s_load_b96 s[0:2], s[4:5], 0x24
+; GFX12-GISEL-NEXT:    s_wait_kmcnt 0x0
+; GFX12-GISEL-NEXT:    s_add_co_u32 s0, s0, -16
+; GFX12-GISEL-NEXT:    s_add_co_ci_u32 s1, s1, -1
+; GFX12-GISEL-NEXT:    s_delay_alu instid0(SALU_CYCLE_1)
+; GFX12-GISEL-NEXT:    v_dual_mov_b32 v0, s0 :: v_dual_mov_b32 v1, s1
+; GFX12-GISEL-NEXT:    v_mov_b32_e32 v2, s2
+; GFX12-GISEL-NEXT:    global_wb scope:SCOPE_SYS
+; GFX12-GISEL-NEXT:    s_wait_storecnt 0x0
+; GFX12-GISEL-NEXT:    flat_atomic_cond_sub_u32 v[0:1], v2 scope:SCOPE_SYS
+; GFX12-GISEL-NEXT:    s_wait_storecnt_dscnt 0x0
+; GFX12-GISEL-NEXT:    global_inv scope:SCOPE_SYS
+; GFX12-GISEL-NEXT:    s_endpgm
+entry:
+  %gep = getelementptr i32, ptr %addr, i32 -4
+  %unused = atomicrmw usub_cond ptr %gep, i32 %in seq_cst
+  ret void
+}
+
+define amdgpu_kernel void @flat_atomic_usub_cond_no_rtn_u32_forced(ptr %addr, i32 %in) "target-features"="+atomic-csub-no-rtn-insts" {
----------------
anjenner wrote:

Because it was in atomic_cond_sub.ll from which this file was forked (and which is removed in https://github.com/llvm/llvm-project/pull/105553 ). I have removed these tests in https://github.com/llvm/llvm-project/commit/c2e8ead5ff9586c24830449cd59998882cc3e35e .

https://github.com/llvm/llvm-project/pull/141068


More information about the llvm-commits mailing list