[llvm] [SPIRV] Add handling for `uinc_wrap` and `udec_wrap` atomics (PR #179114)

Manuel Carrasco via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 4 04:51:04 PST 2026


================
@@ -0,0 +1,68 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK-DAG: %[[#Int:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#Bool:]] = OpTypeBool
+; CHECK-DAG: %[[#Struct:]] = OpTypeStruct %[[#Int]] %[[#Bool]]
+; CHECK-DAG: %[[#StructPtr:]] = OpTypePointer CrossWorkgroup %[[#Struct]]
+; CHECK-DAG: %[[#IntPtr:]] = OpTypePointer CrossWorkgroup %[[#Int]]
+; CHECK-DAG: %[[#UndefStruct:]] = OpUndef %[[#Struct]]
+; CHECK-DAG: %[[#MemSem:]] = OpConstant %[[#Int]] 16
+; CHECK-DAG: %[[#Value:]] = OpConstant %[[#Int]] 42
+; CHECK-DAG: %[[#One:]] = OpConstant %[[#Int]] 1
+; CHECK-DAG: %[[#Scope:]] = OpConstantNull %[[#Int]]
+; CHECK-DAG: %[[#Pointer:]] = OpVariable %[[#IntPtr]] CrossWorkgroup
+
+ at ui = common dso_local addrspace(1) global i32 0, align 4
+
+define dso_local spir_func void @atomicrmw_uinc_udec_wrap() local_unnamed_addr {
+entry:
+; CHECK: %[[#Entry:]] = OpLabel
+; CHECK: %[[#Cast1:]] = OpBitcast %[[#StructPtr]] %[[#Pointer]]
+; CHECK: %[[#Cast2:]] = OpBitcast %[[#StructPtr]] %[[#Pointer]]
+
+  %0 = atomicrmw uinc_wrap ptr addrspace(1) @ui, i32 42 seq_cst
+; CHECK: %[[#LoadUi1:]] = OpLoad %[[#Int]] %[[#Pointer]] Aligned 4
+; CHECK: OpBranch %[[#Loop1:]]
+; CHECK: %[[#Loop1]] = OpLabel
+; CHECK: %[[#Phi1:]] = OpPhi %[[#Int]] %[[#LoadUi1]] %[[#Entry]] %[[#Phi1Next:]] %[[#Loop1]]
+; CHECK: %[[#Add:]] = OpIAdd %[[#Int]] %[[#Phi1]] %[[#One]]
+; CHECK: %[[#GE:]] = OpUGreaterThanEqual %[[#Bool]] %[[#Phi1]] %[[#Value]]
+; CHECK: %[[#Select1:]] = OpSelect %[[#Int]] %[[#GE]] %[[#Scope]] %[[#Add]]
+; CHECK: %[[#Bitcast1:]] = OpBitcast %[[#IntPtr]] %[[#Cast1]]
+; CHECK: %[[#CmpXChg1:]] = OpAtomicCompareExchange %[[#Int]] %[[#Bitcast1]] %[[#Scope]] %[[#MemSem]] %[[#MemSem]] %[[#Select1]] %[[#Phi1]]
+; CHECK: %[[#Eq1:]] = OpIEqual %[[#Bool]] %[[#CmpXChg1]] %[[#Phi1]]
+; CHECK: %[[#Insert1:]] = OpCompositeInsert %[[#Struct]] %[[#CmpXChg1]] %[[#UndefStruct]] 0
+; CHECK: %[[#Insert2:]] = OpCompositeInsert %[[#Struct]] %[[#Eq1]] %[[#Insert1]] 1
+; CHECK: %[[#Cond1:]] = OpCompositeExtract %[[#Bool]] %[[#Insert2]] 1
+; CHECK: %[[#Phi1Next]] = OpCompositeExtract %[[#Int]] %[[#Insert2]] 0
+; CHECK: OpBranchConditional %[[#Cond1]] %[[#Exit1:]] %[[#Loop1]]
+; CHECK: %[[#Exit1]] = OpLabel
----------------
mgcarrasco wrote:

+1 if we could simplify the checks if they are manually written, otherwise stick with an automated tool (if it works well). Other than that, it looks good to me. 

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


More information about the llvm-commits mailing list