1; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=FUNC %s
2; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefix=CIVI -check-prefix=GCN -check-prefix=FUNC %s
3; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=CIVI -check-prefix=GCN -check-prefix=FUNC %s
4; RUN: llc -march=r600 -mcpu=redwood -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
5
6; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i32:
7; EG: LDS_WRXCHG_RET *
8; GCN: s_load_dword [[SPTR:s[0-9]+]],
9; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
10; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
11; GCN: ds_wrxchg_rtn_b32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]]
12; GCN: buffer_store_dword [[RESULT]],
13; GCN: s_endpgm
14define void @lds_atomic_xchg_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
15  %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst
16  store i32 %result, i32 addrspace(1)* %out, align 4
17  ret void
18}
19
20; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i32_offset:
21; EG: LDS_WRXCHG_RET *
22; GCN: ds_wrxchg_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
23; GCN: s_endpgm
24define void @lds_atomic_xchg_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
25  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
26  %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst
27  store i32 %result, i32 addrspace(1)* %out, align 4
28  ret void
29}
30
31; XXX - Is it really necessary to load 4 into VGPR?
32; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32:
33; EG: LDS_ADD_RET *
34; GCN: s_load_dword [[SPTR:s[0-9]+]],
35; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
36; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
37; GCN: ds_add_rtn_u32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]]
38; GCN: buffer_store_dword [[RESULT]],
39; GCN: s_endpgm
40define void @lds_atomic_add_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
41  %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst
42  store i32 %result, i32 addrspace(1)* %out, align 4
43  ret void
44}
45
46; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32_offset:
47; EG: LDS_ADD_RET *
48; GCN: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
49; GCN: s_endpgm
50define void @lds_atomic_add_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
51  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
52  %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
53  store i32 %result, i32 addrspace(1)* %out, align 4
54  ret void
55}
56
57; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32_bad_si_offset:
58; EG: LDS_ADD_RET *
59; SI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
60; CIVI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
61; GCN: s_endpgm
62define void @lds_atomic_add_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
63  %sub = sub i32 %a, %b
64  %add = add i32 %sub, 4
65  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add
66  %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
67  store i32 %result, i32 addrspace(1)* %out, align 4
68  ret void
69}
70
71; FUNC-LABEL: {{^}}lds_atomic_add1_ret_i32:
72; EG: LDS_ADD_RET *
73; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
74; GCN: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]]
75; GCN: s_endpgm
76define void @lds_atomic_add1_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
77  %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst
78  store i32 %result, i32 addrspace(1)* %out, align 4
79  ret void
80}
81
82; FUNC-LABEL: {{^}}lds_atomic_add1_ret_i32_offset:
83; EG: LDS_ADD_RET *
84; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
85; GCN: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]] offset:16
86; GCN: s_endpgm
87define void @lds_atomic_add1_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
88  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
89  %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
90  store i32 %result, i32 addrspace(1)* %out, align 4
91  ret void
92}
93
94; FUNC-LABEL: {{^}}lds_atomic_add1_ret_i32_bad_si_offset:
95; EG: LDS_ADD_RET *
96; SI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
97; CIVI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
98; GCN: s_endpgm
99define void @lds_atomic_add1_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
100  %sub = sub i32 %a, %b
101  %add = add i32 %sub, 4
102  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add
103  %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
104  store i32 %result, i32 addrspace(1)* %out, align 4
105  ret void
106}
107
108; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32:
109; EG: LDS_SUB_RET *
110; GCN: ds_sub_rtn_u32
111; GCN: s_endpgm
112define void @lds_atomic_sub_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
113  %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst
114  store i32 %result, i32 addrspace(1)* %out, align 4
115  ret void
116}
117
118; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32_offset:
119; EG: LDS_SUB_RET *
120; GCN: ds_sub_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
121; GCN: s_endpgm
122define void @lds_atomic_sub_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
123  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
124  %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst
125  store i32 %result, i32 addrspace(1)* %out, align 4
126  ret void
127}
128
129; FUNC-LABEL: {{^}}lds_atomic_sub1_ret_i32:
130; EG: LDS_SUB_RET *
131; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
132; GCN: ds_sub_rtn_u32  v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]]
133; GCN: s_endpgm
134define void @lds_atomic_sub1_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
135  %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst
136  store i32 %result, i32 addrspace(1)* %out, align 4
137  ret void
138}
139
140; FUNC-LABEL: {{^}}lds_atomic_sub1_ret_i32_offset:
141; EG: LDS_SUB_RET *
142; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
143; GCN: ds_sub_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[ONE]] offset:16
144; GCN: s_endpgm
145define void @lds_atomic_sub1_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
146  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
147  %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst
148  store i32 %result, i32 addrspace(1)* %out, align 4
149  ret void
150}
151
152; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32:
153; EG: LDS_AND_RET *
154; GCN: ds_and_rtn_b32
155; GCN: s_endpgm
156define void @lds_atomic_and_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
157  %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst
158  store i32 %result, i32 addrspace(1)* %out, align 4
159  ret void
160}
161
162; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32_offset:
163; EG: LDS_AND_RET *
164; GCN: ds_and_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
165; GCN: s_endpgm
166define void @lds_atomic_and_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
167  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
168  %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst
169  store i32 %result, i32 addrspace(1)* %out, align 4
170  ret void
171}
172
173; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32:
174; EG: LDS_OR_RET *
175; GCN: ds_or_rtn_b32
176; GCN: s_endpgm
177define void @lds_atomic_or_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
178  %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst
179  store i32 %result, i32 addrspace(1)* %out, align 4
180  ret void
181}
182
183; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32_offset:
184; EG: LDS_OR_RET *
185; GCN: ds_or_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
186; GCN: s_endpgm
187define void @lds_atomic_or_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
188  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
189  %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst
190  store i32 %result, i32 addrspace(1)* %out, align 4
191  ret void
192}
193
194; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32:
195; EG: LDS_XOR_RET *
196; GCN: ds_xor_rtn_b32
197; GCN: s_endpgm
198define void @lds_atomic_xor_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
199  %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst
200  store i32 %result, i32 addrspace(1)* %out, align 4
201  ret void
202}
203
204; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32_offset:
205; EG: LDS_XOR_RET *
206; GCN: ds_xor_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
207; GCN: s_endpgm
208define void @lds_atomic_xor_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
209  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
210  %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst
211  store i32 %result, i32 addrspace(1)* %out, align 4
212  ret void
213}
214
215; FIXME: There is no atomic nand instr
216; XFUNC-LABEL: {{^}}lds_atomic_nand_ret_i32:uction, so we somehow need to expand this.
217; define void @lds_atomic_nand_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
218;   %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst
219;   store i32 %result, i32 addrspace(1)* %out, align 4
220;   ret void
221; }
222
223; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32:
224; EG: LDS_MIN_INT_RET *
225; GCN: ds_min_rtn_i32
226; GCN: s_endpgm
227define void @lds_atomic_min_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
228  %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst
229  store i32 %result, i32 addrspace(1)* %out, align 4
230  ret void
231}
232
233; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32_offset:
234; EG: LDS_MIN_INT_RET *
235; GCN: ds_min_rtn_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
236; GCN: s_endpgm
237define void @lds_atomic_min_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
238  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
239  %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst
240  store i32 %result, i32 addrspace(1)* %out, align 4
241  ret void
242}
243
244; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32:
245; EG: LDS_MAX_INT_RET *
246; GCN: ds_max_rtn_i32
247; GCN: s_endpgm
248define void @lds_atomic_max_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
249  %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst
250  store i32 %result, i32 addrspace(1)* %out, align 4
251  ret void
252}
253
254; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32_offset:
255; EG: LDS_MAX_INT_RET *
256; GCN: ds_max_rtn_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
257; GCN: s_endpgm
258define void @lds_atomic_max_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
259  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
260  %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst
261  store i32 %result, i32 addrspace(1)* %out, align 4
262  ret void
263}
264
265; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32:
266; EG: LDS_MIN_UINT_RET *
267; GCN: ds_min_rtn_u32
268; GCN: s_endpgm
269define void @lds_atomic_umin_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
270  %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst
271  store i32 %result, i32 addrspace(1)* %out, align 4
272  ret void
273}
274
275; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32_offset:
276; EG: LDS_MIN_UINT_RET *
277; GCN: ds_min_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
278; GCN: s_endpgm
279define void @lds_atomic_umin_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
280  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
281  %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst
282  store i32 %result, i32 addrspace(1)* %out, align 4
283  ret void
284}
285
286; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32:
287; EG: LDS_MAX_UINT_RET *
288; GCN: ds_max_rtn_u32
289; GCN: s_endpgm
290define void @lds_atomic_umax_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
291  %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst
292  store i32 %result, i32 addrspace(1)* %out, align 4
293  ret void
294}
295
296; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32_offset:
297; EG: LDS_MAX_UINT_RET *
298; GCN: ds_max_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
299; GCN: s_endpgm
300define void @lds_atomic_umax_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
301  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
302  %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst
303  store i32 %result, i32 addrspace(1)* %out, align 4
304  ret void
305}
306
307; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32:
308; GCN: s_load_dword [[SPTR:s[0-9]+]],
309; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
310; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
311; GCN: ds_wrxchg_rtn_b32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]]
312; GCN: s_endpgm
313define void @lds_atomic_xchg_noret_i32(i32 addrspace(3)* %ptr) nounwind {
314  %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst
315  ret void
316}
317
318; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32_offset:
319; GCN: ds_wrxchg_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
320; GCN: s_endpgm
321define void @lds_atomic_xchg_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
322  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
323  %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst
324  ret void
325}
326
327; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32:
328; GCN: s_load_dword [[SPTR:s[0-9]+]],
329; GCN: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
330; GCN: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
331; GCN: ds_add_u32 [[VPTR]], [[DATA]]
332; GCN: s_endpgm
333define void @lds_atomic_add_noret_i32(i32 addrspace(3)* %ptr) nounwind {
334  %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst
335  ret void
336}
337
338; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_offset:
339; GCN: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
340; GCN: s_endpgm
341define void @lds_atomic_add_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
342  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
343  %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
344  ret void
345}
346
347; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_bad_si_offset
348; SI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}}
349; CIVI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
350; GCN: s_endpgm
351define void @lds_atomic_add_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
352  %sub = sub i32 %a, %b
353  %add = add i32 %sub, 4
354  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add
355  %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
356  ret void
357}
358
359; FUNC-LABEL: {{^}}lds_atomic_add1_noret_i32:
360; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
361; GCN: ds_add_u32 v{{[0-9]+}}, [[ONE]]
362; GCN: s_endpgm
363define void @lds_atomic_add1_noret_i32(i32 addrspace(3)* %ptr) nounwind {
364  %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst
365  ret void
366}
367
368; FUNC-LABEL: {{^}}lds_atomic_add1_noret_i32_offset:
369; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
370; GCN: ds_add_u32 v{{[0-9]+}}, [[ONE]] offset:16
371; GCN: s_endpgm
372define void @lds_atomic_add1_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
373  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
374  %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
375  ret void
376}
377
378; FUNC-LABEL: {{^}}lds_atomic_add1_noret_i32_bad_si_offset:
379; SI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}}
380; CIVI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
381; GCN: s_endpgm
382define void @lds_atomic_add1_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
383  %sub = sub i32 %a, %b
384  %add = add i32 %sub, 4
385  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 %add
386  %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
387  ret void
388}
389
390; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32:
391; GCN: ds_sub_u32
392; GCN: s_endpgm
393define void @lds_atomic_sub_noret_i32(i32 addrspace(3)* %ptr) nounwind {
394  %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst
395  ret void
396}
397
398; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32_offset:
399; GCN: ds_sub_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
400; GCN: s_endpgm
401define void @lds_atomic_sub_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
402  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
403  %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst
404  ret void
405}
406
407; FUNC-LABEL: {{^}}lds_atomic_sub1_noret_i32:
408; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
409; GCN: ds_sub_u32 v{{[0-9]+}}, [[ONE]]
410; GCN: s_endpgm
411define void @lds_atomic_sub1_noret_i32(i32 addrspace(3)* %ptr) nounwind {
412  %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst
413  ret void
414}
415
416; FUNC-LABEL: {{^}}lds_atomic_sub1_noret_i32_offset:
417; GCN: v_mov_b32_e32 [[ONE:v[0-9]+]], 1{{$}}
418; GCN: ds_sub_u32 v{{[0-9]+}}, [[ONE]] offset:16
419; GCN: s_endpgm
420define void @lds_atomic_sub1_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
421  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
422  %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst
423  ret void
424}
425
426; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32:
427; GCN: ds_and_b32
428; GCN: s_endpgm
429define void @lds_atomic_and_noret_i32(i32 addrspace(3)* %ptr) nounwind {
430  %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst
431  ret void
432}
433
434; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32_offset:
435; GCN: ds_and_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
436; GCN: s_endpgm
437define void @lds_atomic_and_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
438  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
439  %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst
440  ret void
441}
442
443; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32:
444; GCN: ds_or_b32
445; GCN: s_endpgm
446define void @lds_atomic_or_noret_i32(i32 addrspace(3)* %ptr) nounwind {
447  %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst
448  ret void
449}
450
451; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32_offset:
452; GCN: ds_or_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
453; GCN: s_endpgm
454define void @lds_atomic_or_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
455  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
456  %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst
457  ret void
458}
459
460; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32:
461; GCN: ds_xor_b32
462; GCN: s_endpgm
463define void @lds_atomic_xor_noret_i32(i32 addrspace(3)* %ptr) nounwind {
464  %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst
465  ret void
466}
467
468; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32_offset:
469; GCN: ds_xor_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
470; GCN: s_endpgm
471define void @lds_atomic_xor_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
472  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
473  %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst
474  ret void
475}
476
477; FIXME: There is no atomic nand instr
478; XFUNC-LABEL: {{^}}lds_atomic_nand_noret_i32:uction, so we somehow need to expand this.
479; define void @lds_atomic_nand_noret_i32(i32 addrspace(3)* %ptr) nounwind {
480;   %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst
481;   ret void
482; }
483
484; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32:
485; GCN: ds_min_i32
486; GCN: s_endpgm
487define void @lds_atomic_min_noret_i32(i32 addrspace(3)* %ptr) nounwind {
488  %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst
489  ret void
490}
491
492; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32_offset:
493; GCN: ds_min_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
494; GCN: s_endpgm
495define void @lds_atomic_min_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
496  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
497  %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst
498  ret void
499}
500
501; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32:
502; GCN: ds_max_i32
503; GCN: s_endpgm
504define void @lds_atomic_max_noret_i32(i32 addrspace(3)* %ptr) nounwind {
505  %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst
506  ret void
507}
508
509; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32_offset:
510; GCN: ds_max_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
511; GCN: s_endpgm
512define void @lds_atomic_max_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
513  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
514  %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst
515  ret void
516}
517
518; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32:
519; GCN: ds_min_u32
520; GCN: s_endpgm
521define void @lds_atomic_umin_noret_i32(i32 addrspace(3)* %ptr) nounwind {
522  %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst
523  ret void
524}
525
526; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32_offset:
527; GCN: ds_min_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
528; GCN: s_endpgm
529define void @lds_atomic_umin_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
530  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
531  %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst
532  ret void
533}
534
535; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32:
536; GCN: ds_max_u32
537; GCN: s_endpgm
538define void @lds_atomic_umax_noret_i32(i32 addrspace(3)* %ptr) nounwind {
539  %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst
540  ret void
541}
542
543; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32_offset:
544; GCN: ds_max_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
545; GCN: s_endpgm
546define void @lds_atomic_umax_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
547  %gep = getelementptr i32, i32 addrspace(3)* %ptr, i32 4
548  %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst
549  ret void
550}
551