1 ; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -strict-whitespace -check-prefix=SI %s
3 ; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i64:
4 ; SI: ds_wrxchg_rtn_b64
6 define void @lds_atomic_xchg_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
7 %result = atomicrmw xchg i64 addrspace(3)* %ptr, i64 4 seq_cst
8 store i64 %result, i64 addrspace(1)* %out, align 8
12 ; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i64_offset:
13 ; SI: ds_wrxchg_rtn_b64 {{.*}} offset:32
15 define void @lds_atomic_xchg_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
16 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
17 %result = atomicrmw xchg i64 addrspace(3)* %gep, i64 4 seq_cst
18 store i64 %result, i64 addrspace(1)* %out, align 8
22 ; FUNC-LABEL: {{^}}lds_atomic_add_ret_i64:
25 define void @lds_atomic_add_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
26 %result = atomicrmw add i64 addrspace(3)* %ptr, i64 4 seq_cst
27 store i64 %result, i64 addrspace(1)* %out, align 8
31 ; FUNC-LABEL: {{^}}lds_atomic_add_ret_i64_offset:
32 ; SI: v_mov_b32_e32 v[[LOVDATA:[0-9]+]], 9
33 ; SI: v_mov_b32_e32 v[[HIVDATA:[0-9]+]], 0
34 ; SI: s_load_dword [[PTR:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
35 ; SI-DAG: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[PTR]]
36 ; SI: ds_add_rtn_u64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}} offset:32 [M0]
37 ; SI: buffer_store_dwordx2 [[RESULT]],
39 define void @lds_atomic_add_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
40 %gep = getelementptr i64 addrspace(3)* %ptr, i64 4
41 %result = atomicrmw add i64 addrspace(3)* %gep, i64 9 seq_cst
42 store i64 %result, i64 addrspace(1)* %out, align 8
46 ; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i64:
47 ; SI: v_mov_b32_e32 v[[LOVDATA:[0-9]+]], -1
48 ; SI: v_mov_b32_e32 v[[HIVDATA:[0-9]+]], -1
49 ; SI: ds_inc_rtn_u64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}}
50 ; SI: buffer_store_dwordx2 [[RESULT]],
52 define void @lds_atomic_inc_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
53 %result = atomicrmw add i64 addrspace(3)* %ptr, i64 1 seq_cst
54 store i64 %result, i64 addrspace(1)* %out, align 8
58 ; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i64_offset:
59 ; SI: ds_inc_rtn_u64 {{.*}} offset:32
61 define void @lds_atomic_inc_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
62 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
63 %result = atomicrmw add i64 addrspace(3)* %gep, i64 1 seq_cst
64 store i64 %result, i64 addrspace(1)* %out, align 8
68 ; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i64:
71 define void @lds_atomic_sub_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
72 %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 4 seq_cst
73 store i64 %result, i64 addrspace(1)* %out, align 8
77 ; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i64_offset:
78 ; SI: ds_sub_rtn_u64 {{.*}} offset:32
80 define void @lds_atomic_sub_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
81 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
82 %result = atomicrmw sub i64 addrspace(3)* %gep, i64 4 seq_cst
83 store i64 %result, i64 addrspace(1)* %out, align 8
87 ; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i64:
88 ; SI: v_mov_b32_e32 v[[LOVDATA:[0-9]+]], -1
89 ; SI: v_mov_b32_e32 v[[HIVDATA:[0-9]+]], -1
90 ; SI: ds_dec_rtn_u64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}}
91 ; SI: buffer_store_dwordx2 [[RESULT]],
93 define void @lds_atomic_dec_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
94 %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 1 seq_cst
95 store i64 %result, i64 addrspace(1)* %out, align 8
99 ; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i64_offset:
100 ; SI: ds_dec_rtn_u64 {{.*}} offset:32
102 define void @lds_atomic_dec_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
103 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
104 %result = atomicrmw sub i64 addrspace(3)* %gep, i64 1 seq_cst
105 store i64 %result, i64 addrspace(1)* %out, align 8
109 ; FUNC-LABEL: {{^}}lds_atomic_and_ret_i64:
112 define void @lds_atomic_and_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
113 %result = atomicrmw and i64 addrspace(3)* %ptr, i64 4 seq_cst
114 store i64 %result, i64 addrspace(1)* %out, align 8
118 ; FUNC-LABEL: {{^}}lds_atomic_and_ret_i64_offset:
119 ; SI: ds_and_rtn_b64 {{.*}} offset:32
121 define void @lds_atomic_and_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
122 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
123 %result = atomicrmw and i64 addrspace(3)* %gep, i64 4 seq_cst
124 store i64 %result, i64 addrspace(1)* %out, align 8
128 ; FUNC-LABEL: {{^}}lds_atomic_or_ret_i64:
131 define void @lds_atomic_or_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
132 %result = atomicrmw or i64 addrspace(3)* %ptr, i64 4 seq_cst
133 store i64 %result, i64 addrspace(1)* %out, align 8
137 ; FUNC-LABEL: {{^}}lds_atomic_or_ret_i64_offset:
138 ; SI: ds_or_rtn_b64 {{.*}} offset:32
140 define void @lds_atomic_or_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
141 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
142 %result = atomicrmw or i64 addrspace(3)* %gep, i64 4 seq_cst
143 store i64 %result, i64 addrspace(1)* %out, align 8
147 ; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i64:
150 define void @lds_atomic_xor_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
151 %result = atomicrmw xor i64 addrspace(3)* %ptr, i64 4 seq_cst
152 store i64 %result, i64 addrspace(1)* %out, align 8
156 ; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i64_offset:
157 ; SI: ds_xor_rtn_b64 {{.*}} offset:32
159 define void @lds_atomic_xor_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
160 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
161 %result = atomicrmw xor i64 addrspace(3)* %gep, i64 4 seq_cst
162 store i64 %result, i64 addrspace(1)* %out, align 8
166 ; FIXME: There is no atomic nand instr
167 ; XFUNC-LABEL: {{^}}lds_atomic_nand_ret_i64:uction, so we somehow need to expand this.
168 ; define void @lds_atomic_nand_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
169 ; %result = atomicrmw nand i64 addrspace(3)* %ptr, i32 4 seq_cst
170 ; store i64 %result, i64 addrspace(1)* %out, align 8
174 ; FUNC-LABEL: {{^}}lds_atomic_min_ret_i64:
177 define void @lds_atomic_min_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
178 %result = atomicrmw min i64 addrspace(3)* %ptr, i64 4 seq_cst
179 store i64 %result, i64 addrspace(1)* %out, align 8
183 ; FUNC-LABEL: {{^}}lds_atomic_min_ret_i64_offset:
184 ; SI: ds_min_rtn_i64 {{.*}} offset:32
186 define void @lds_atomic_min_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
187 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
188 %result = atomicrmw min i64 addrspace(3)* %gep, i64 4 seq_cst
189 store i64 %result, i64 addrspace(1)* %out, align 8
193 ; FUNC-LABEL: {{^}}lds_atomic_max_ret_i64:
196 define void @lds_atomic_max_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
197 %result = atomicrmw max i64 addrspace(3)* %ptr, i64 4 seq_cst
198 store i64 %result, i64 addrspace(1)* %out, align 8
202 ; FUNC-LABEL: {{^}}lds_atomic_max_ret_i64_offset:
203 ; SI: ds_max_rtn_i64 {{.*}} offset:32
205 define void @lds_atomic_max_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
206 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
207 %result = atomicrmw max i64 addrspace(3)* %gep, i64 4 seq_cst
208 store i64 %result, i64 addrspace(1)* %out, align 8
212 ; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i64:
215 define void @lds_atomic_umin_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
216 %result = atomicrmw umin i64 addrspace(3)* %ptr, i64 4 seq_cst
217 store i64 %result, i64 addrspace(1)* %out, align 8
221 ; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i64_offset:
222 ; SI: ds_min_rtn_u64 {{.*}} offset:32
224 define void @lds_atomic_umin_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
225 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
226 %result = atomicrmw umin i64 addrspace(3)* %gep, i64 4 seq_cst
227 store i64 %result, i64 addrspace(1)* %out, align 8
231 ; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i64:
234 define void @lds_atomic_umax_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
235 %result = atomicrmw umax i64 addrspace(3)* %ptr, i64 4 seq_cst
236 store i64 %result, i64 addrspace(1)* %out, align 8
240 ; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i64_offset:
241 ; SI: ds_max_rtn_u64 {{.*}} offset:32
243 define void @lds_atomic_umax_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
244 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
245 %result = atomicrmw umax i64 addrspace(3)* %gep, i64 4 seq_cst
246 store i64 %result, i64 addrspace(1)* %out, align 8
250 ; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i64:
251 ; SI: ds_wrxchg_rtn_b64
253 define void @lds_atomic_xchg_noret_i64(i64 addrspace(3)* %ptr) nounwind {
254 %result = atomicrmw xchg i64 addrspace(3)* %ptr, i64 4 seq_cst
258 ; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i64_offset:
259 ; SI: ds_wrxchg_rtn_b64 {{.*}} offset:32
261 define void @lds_atomic_xchg_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
262 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
263 %result = atomicrmw xchg i64 addrspace(3)* %gep, i64 4 seq_cst
267 ; FUNC-LABEL: {{^}}lds_atomic_add_noret_i64:
270 define void @lds_atomic_add_noret_i64(i64 addrspace(3)* %ptr) nounwind {
271 %result = atomicrmw add i64 addrspace(3)* %ptr, i64 4 seq_cst
275 ; FUNC-LABEL: {{^}}lds_atomic_add_noret_i64_offset:
276 ; SI: s_load_dword [[PTR:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0x9
277 ; SI: v_mov_b32_e32 v[[LOVDATA:[0-9]+]], 9
278 ; SI: v_mov_b32_e32 v[[HIVDATA:[0-9]+]], 0
279 ; SI: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[PTR]]
280 ; SI: ds_add_u64 [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}} offset:32 [M0]
282 define void @lds_atomic_add_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
283 %gep = getelementptr i64 addrspace(3)* %ptr, i64 4
284 %result = atomicrmw add i64 addrspace(3)* %gep, i64 9 seq_cst
288 ; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i64:
289 ; SI: v_mov_b32_e32 v[[LOVDATA:[0-9]+]], -1
290 ; SI: v_mov_b32_e32 v[[HIVDATA:[0-9]+]], -1
291 ; SI: ds_inc_u64 [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}}
293 define void @lds_atomic_inc_noret_i64(i64 addrspace(3)* %ptr) nounwind {
294 %result = atomicrmw add i64 addrspace(3)* %ptr, i64 1 seq_cst
298 ; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i64_offset:
299 ; SI: ds_inc_u64 {{.*}} offset:32
301 define void @lds_atomic_inc_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
302 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
303 %result = atomicrmw add i64 addrspace(3)* %gep, i64 1 seq_cst
307 ; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i64:
310 define void @lds_atomic_sub_noret_i64(i64 addrspace(3)* %ptr) nounwind {
311 %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 4 seq_cst
315 ; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i64_offset:
316 ; SI: ds_sub_u64 {{.*}} offset:32
318 define void @lds_atomic_sub_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
319 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
320 %result = atomicrmw sub i64 addrspace(3)* %gep, i64 4 seq_cst
324 ; FUNC-LABEL: {{^}}lds_atomic_dec_noret_i64:
325 ; SI: v_mov_b32_e32 v[[LOVDATA:[0-9]+]], -1
326 ; SI: v_mov_b32_e32 v[[HIVDATA:[0-9]+]], -1
327 ; SI: ds_dec_u64 [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}}
329 define void @lds_atomic_dec_noret_i64(i64 addrspace(3)* %ptr) nounwind {
330 %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 1 seq_cst
334 ; FUNC-LABEL: {{^}}lds_atomic_dec_noret_i64_offset:
335 ; SI: ds_dec_u64 {{.*}} offset:32
337 define void @lds_atomic_dec_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
338 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
339 %result = atomicrmw sub i64 addrspace(3)* %gep, i64 1 seq_cst
343 ; FUNC-LABEL: {{^}}lds_atomic_and_noret_i64:
346 define void @lds_atomic_and_noret_i64(i64 addrspace(3)* %ptr) nounwind {
347 %result = atomicrmw and i64 addrspace(3)* %ptr, i64 4 seq_cst
351 ; FUNC-LABEL: {{^}}lds_atomic_and_noret_i64_offset:
352 ; SI: ds_and_b64 {{.*}} offset:32
354 define void @lds_atomic_and_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
355 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
356 %result = atomicrmw and i64 addrspace(3)* %gep, i64 4 seq_cst
360 ; FUNC-LABEL: {{^}}lds_atomic_or_noret_i64:
363 define void @lds_atomic_or_noret_i64(i64 addrspace(3)* %ptr) nounwind {
364 %result = atomicrmw or i64 addrspace(3)* %ptr, i64 4 seq_cst
368 ; FUNC-LABEL: {{^}}lds_atomic_or_noret_i64_offset:
369 ; SI: ds_or_b64 {{.*}} offset:32
371 define void @lds_atomic_or_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
372 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
373 %result = atomicrmw or i64 addrspace(3)* %gep, i64 4 seq_cst
377 ; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i64:
380 define void @lds_atomic_xor_noret_i64(i64 addrspace(3)* %ptr) nounwind {
381 %result = atomicrmw xor i64 addrspace(3)* %ptr, i64 4 seq_cst
385 ; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i64_offset:
386 ; SI: ds_xor_b64 {{.*}} offset:32
388 define void @lds_atomic_xor_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
389 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
390 %result = atomicrmw xor i64 addrspace(3)* %gep, i64 4 seq_cst
394 ; FIXME: There is no atomic nand instr
395 ; XFUNC-LABEL: {{^}}lds_atomic_nand_noret_i64:uction, so we somehow need to expand this.
396 ; define void @lds_atomic_nand_noret_i64(i64 addrspace(3)* %ptr) nounwind {
397 ; %result = atomicrmw nand i64 addrspace(3)* %ptr, i32 4 seq_cst
401 ; FUNC-LABEL: {{^}}lds_atomic_min_noret_i64:
404 define void @lds_atomic_min_noret_i64(i64 addrspace(3)* %ptr) nounwind {
405 %result = atomicrmw min i64 addrspace(3)* %ptr, i64 4 seq_cst
409 ; FUNC-LABEL: {{^}}lds_atomic_min_noret_i64_offset:
410 ; SI: ds_min_i64 {{.*}} offset:32
412 define void @lds_atomic_min_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
413 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
414 %result = atomicrmw min i64 addrspace(3)* %gep, i64 4 seq_cst
418 ; FUNC-LABEL: {{^}}lds_atomic_max_noret_i64:
421 define void @lds_atomic_max_noret_i64(i64 addrspace(3)* %ptr) nounwind {
422 %result = atomicrmw max i64 addrspace(3)* %ptr, i64 4 seq_cst
426 ; FUNC-LABEL: {{^}}lds_atomic_max_noret_i64_offset:
427 ; SI: ds_max_i64 {{.*}} offset:32
429 define void @lds_atomic_max_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
430 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
431 %result = atomicrmw max i64 addrspace(3)* %gep, i64 4 seq_cst
435 ; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i64:
438 define void @lds_atomic_umin_noret_i64(i64 addrspace(3)* %ptr) nounwind {
439 %result = atomicrmw umin i64 addrspace(3)* %ptr, i64 4 seq_cst
443 ; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i64_offset:
444 ; SI: ds_min_u64 {{.*}} offset:32
446 define void @lds_atomic_umin_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
447 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
448 %result = atomicrmw umin i64 addrspace(3)* %gep, i64 4 seq_cst
452 ; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i64:
455 define void @lds_atomic_umax_noret_i64(i64 addrspace(3)* %ptr) nounwind {
456 %result = atomicrmw umax i64 addrspace(3)* %ptr, i64 4 seq_cst
460 ; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i64_offset:
461 ; SI: ds_max_u64 {{.*}} offset:32
463 define void @lds_atomic_umax_noret_i64_offset(i64 addrspace(3)* %ptr) nounwind {
464 %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
465 %result = atomicrmw umax i64 addrspace(3)* %gep, i64 4 seq_cst