R600/SI: Add SIFoldOperands pass
[oota-llvm.git] / test / CodeGen / R600 / local-atomics.ll
1 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
2 ; RUN: llc -march=r600 -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -strict-whitespace -check-prefix=CI -check-prefix=FUNC %s
3 ; RUN: llc -march=r600 -mcpu=redwood -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
4
5 ; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i32:
6 ; EG: LDS_WRXCHG_RET *
7 ; SI: s_load_dword [[SPTR:s[0-9]+]],
8 ; SI: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
9 ; SI: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
10 ; SI: ds_wrxchg_rtn_b32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]] [M0]
11 ; SI: buffer_store_dword [[RESULT]],
12 ; SI: s_endpgm
13 define void @lds_atomic_xchg_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
14   %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst
15   store i32 %result, i32 addrspace(1)* %out, align 4
16   ret void
17 }
18
19 ; FUNC-LABEL: {{^}}lds_atomic_xchg_ret_i32_offset:
20 ; EG: LDS_WRXCHG_RET *
21 ; SI: ds_wrxchg_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
22 ; SI: s_endpgm
23 define void @lds_atomic_xchg_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
24   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
25   %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst
26   store i32 %result, i32 addrspace(1)* %out, align 4
27   ret void
28 }
29
30 ; XXX - Is it really necessary to load 4 into VGPR?
31 ; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32:
32 ; EG: LDS_ADD_RET *
33 ; SI: s_load_dword [[SPTR:s[0-9]+]],
34 ; SI: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
35 ; SI: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
36 ; SI: ds_add_rtn_u32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]] [M0]
37 ; SI: buffer_store_dword [[RESULT]],
38 ; SI: s_endpgm
39 define void @lds_atomic_add_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
40   %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst
41   store i32 %result, i32 addrspace(1)* %out, align 4
42   ret void
43 }
44
45 ; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32_offset:
46 ; EG: LDS_ADD_RET *
47 ; SI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
48 ; SI: s_endpgm
49 define void @lds_atomic_add_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
50   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
51   %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
52   store i32 %result, i32 addrspace(1)* %out, align 4
53   ret void
54 }
55
56 ; FUNC-LABEL: {{^}}lds_atomic_add_ret_i32_bad_si_offset:
57 ; EG: LDS_ADD_RET *
58 ; SI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} [M0]
59 ; CI: ds_add_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
60 ; SI: s_endpgm
61 define void @lds_atomic_add_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
62   %sub = sub i32 %a, %b
63   %add = add i32 %sub, 4
64   %gep = getelementptr i32 addrspace(3)* %ptr, i32 %add
65   %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
66   store i32 %result, i32 addrspace(1)* %out, align 4
67   ret void
68 }
69
70 ; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32:
71 ; EG: LDS_ADD_RET *
72 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
73 ; SI: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] [M0]
74 ; SI: s_endpgm
75 define void @lds_atomic_inc_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
76   %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst
77   store i32 %result, i32 addrspace(1)* %out, align 4
78   ret void
79 }
80
81 ; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32_offset:
82 ; EG: LDS_ADD_RET *
83 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
84 ; SI: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] offset:16
85 ; SI: s_endpgm
86 define void @lds_atomic_inc_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
87   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
88   %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
89   store i32 %result, i32 addrspace(1)* %out, align 4
90   ret void
91 }
92
93 ; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32_bad_si_offset:
94 ; EG: LDS_ADD_RET *
95 ; SI: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} [M0]
96 ; CI: ds_inc_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
97 ; SI: s_endpgm
98 define void @lds_atomic_inc_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
99   %sub = sub i32 %a, %b
100   %add = add i32 %sub, 4
101   %gep = getelementptr i32 addrspace(3)* %ptr, i32 %add
102   %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
103   store i32 %result, i32 addrspace(1)* %out, align 4
104   ret void
105 }
106
107 ; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32:
108 ; EG: LDS_SUB_RET *
109 ; SI: ds_sub_rtn_u32
110 ; SI: s_endpgm
111 define void @lds_atomic_sub_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
112   %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst
113   store i32 %result, i32 addrspace(1)* %out, align 4
114   ret void
115 }
116
117 ; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32_offset:
118 ; EG: LDS_SUB_RET *
119 ; SI: ds_sub_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
120 ; SI: s_endpgm
121 define void @lds_atomic_sub_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
122   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
123   %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst
124   store i32 %result, i32 addrspace(1)* %out, align 4
125   ret void
126 }
127
128 ; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i32:
129 ; EG: LDS_SUB_RET *
130 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
131 ; SI: ds_dec_rtn_u32  v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] [M0]
132 ; SI: s_endpgm
133 define void @lds_atomic_dec_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
134   %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst
135   store i32 %result, i32 addrspace(1)* %out, align 4
136   ret void
137 }
138
139 ; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i32_offset:
140 ; EG: LDS_SUB_RET *
141 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
142 ; SI: ds_dec_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]] offset:16
143 ; SI: s_endpgm
144 define void @lds_atomic_dec_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
145   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
146   %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst
147   store i32 %result, i32 addrspace(1)* %out, align 4
148   ret void
149 }
150
151 ; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32:
152 ; EG: LDS_AND_RET *
153 ; SI: ds_and_rtn_b32
154 ; SI: s_endpgm
155 define void @lds_atomic_and_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
156   %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst
157   store i32 %result, i32 addrspace(1)* %out, align 4
158   ret void
159 }
160
161 ; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32_offset:
162 ; EG: LDS_AND_RET *
163 ; SI: ds_and_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
164 ; SI: s_endpgm
165 define void @lds_atomic_and_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
166   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
167   %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst
168   store i32 %result, i32 addrspace(1)* %out, align 4
169   ret void
170 }
171
172 ; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32:
173 ; EG: LDS_OR_RET *
174 ; SI: ds_or_rtn_b32
175 ; SI: s_endpgm
176 define void @lds_atomic_or_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
177   %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst
178   store i32 %result, i32 addrspace(1)* %out, align 4
179   ret void
180 }
181
182 ; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32_offset:
183 ; EG: LDS_OR_RET *
184 ; SI: ds_or_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
185 ; SI: s_endpgm
186 define void @lds_atomic_or_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
187   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
188   %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst
189   store i32 %result, i32 addrspace(1)* %out, align 4
190   ret void
191 }
192
193 ; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32:
194 ; EG: LDS_XOR_RET *
195 ; SI: ds_xor_rtn_b32
196 ; SI: s_endpgm
197 define void @lds_atomic_xor_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
198   %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst
199   store i32 %result, i32 addrspace(1)* %out, align 4
200   ret void
201 }
202
203 ; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32_offset:
204 ; EG: LDS_XOR_RET *
205 ; SI: ds_xor_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
206 ; SI: s_endpgm
207 define void @lds_atomic_xor_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
208   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
209   %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst
210   store i32 %result, i32 addrspace(1)* %out, align 4
211   ret void
212 }
213
214 ; FIXME: There is no atomic nand instr
215 ; XFUNC-LABEL: {{^}}lds_atomic_nand_ret_i32:uction, so we somehow need to expand this.
216 ; define void @lds_atomic_nand_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
217 ;   %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst
218 ;   store i32 %result, i32 addrspace(1)* %out, align 4
219 ;   ret void
220 ; }
221
222 ; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32:
223 ; EG: LDS_MIN_INT_RET *
224 ; SI: ds_min_rtn_i32
225 ; SI: s_endpgm
226 define void @lds_atomic_min_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
227   %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst
228   store i32 %result, i32 addrspace(1)* %out, align 4
229   ret void
230 }
231
232 ; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32_offset:
233 ; EG: LDS_MIN_INT_RET *
234 ; SI: ds_min_rtn_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
235 ; SI: s_endpgm
236 define void @lds_atomic_min_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
237   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
238   %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst
239   store i32 %result, i32 addrspace(1)* %out, align 4
240   ret void
241 }
242
243 ; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32:
244 ; EG: LDS_MAX_INT_RET *
245 ; SI: ds_max_rtn_i32
246 ; SI: s_endpgm
247 define void @lds_atomic_max_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
248   %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst
249   store i32 %result, i32 addrspace(1)* %out, align 4
250   ret void
251 }
252
253 ; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32_offset:
254 ; EG: LDS_MAX_INT_RET *
255 ; SI: ds_max_rtn_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
256 ; SI: s_endpgm
257 define void @lds_atomic_max_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
258   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
259   %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst
260   store i32 %result, i32 addrspace(1)* %out, align 4
261   ret void
262 }
263
264 ; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32:
265 ; EG: LDS_MIN_UINT_RET *
266 ; SI: ds_min_rtn_u32
267 ; SI: s_endpgm
268 define void @lds_atomic_umin_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
269   %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst
270   store i32 %result, i32 addrspace(1)* %out, align 4
271   ret void
272 }
273
274 ; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32_offset:
275 ; EG: LDS_MIN_UINT_RET *
276 ; SI: ds_min_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
277 ; SI: s_endpgm
278 define void @lds_atomic_umin_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
279   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
280   %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst
281   store i32 %result, i32 addrspace(1)* %out, align 4
282   ret void
283 }
284
285 ; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32:
286 ; EG: LDS_MAX_UINT_RET *
287 ; SI: ds_max_rtn_u32
288 ; SI: s_endpgm
289 define void @lds_atomic_umax_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
290   %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst
291   store i32 %result, i32 addrspace(1)* %out, align 4
292   ret void
293 }
294
295 ; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32_offset:
296 ; EG: LDS_MAX_UINT_RET *
297 ; SI: ds_max_rtn_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
298 ; SI: s_endpgm
299 define void @lds_atomic_umax_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
300   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
301   %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst
302   store i32 %result, i32 addrspace(1)* %out, align 4
303   ret void
304 }
305
306 ; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32:
307 ; SI: s_load_dword [[SPTR:s[0-9]+]],
308 ; SI: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
309 ; SI: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
310 ; SI: ds_wrxchg_rtn_b32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]] [M0]
311 ; SI: s_endpgm
312 define void @lds_atomic_xchg_noret_i32(i32 addrspace(3)* %ptr) nounwind {
313   %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst
314   ret void
315 }
316
317 ; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32_offset:
318 ; SI: ds_wrxchg_rtn_b32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}} offset:16
319 ; SI: s_endpgm
320 define void @lds_atomic_xchg_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
321   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
322   %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst
323   ret void
324 }
325
326 ; XXX - Is it really necessary to load 4 into VGPR?
327 ; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32:
328 ; SI: s_load_dword [[SPTR:s[0-9]+]],
329 ; SI: v_mov_b32_e32 [[DATA:v[0-9]+]], 4
330 ; SI: v_mov_b32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
331 ; SI: ds_add_u32 [[VPTR]], [[DATA]] [M0]
332 ; SI: s_endpgm
333 define 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 ; SI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
340 ; SI: s_endpgm
341 define void @lds_atomic_add_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
342   %gep = getelementptr 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]+}} [M0]
349 ; CI: ds_add_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16 [M0]
350 ; SI: s_endpgm
351 define 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 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_inc_noret_i32:
360 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
361 ; SI: ds_inc_u32 v{{[0-9]+}}, [[NEGONE]] [M0]
362 ; SI: s_endpgm
363 define void @lds_atomic_inc_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_inc_noret_i32_offset:
369 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
370 ; SI: ds_inc_u32 v{{[0-9]+}}, [[NEGONE]] offset:16
371 ; SI: s_endpgm
372 define void @lds_atomic_inc_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
373   %gep = getelementptr 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_inc_noret_i32_bad_si_offset:
379 ; SI: ds_inc_u32 v{{[0-9]+}}, v{{[0-9]+}}
380 ; CI: ds_inc_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
381 ; SI: s_endpgm
382 define void @lds_atomic_inc_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 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 ; SI: ds_sub_u32
392 ; SI: s_endpgm
393 define 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 ; SI: ds_sub_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
400 ; SI: s_endpgm
401 define void @lds_atomic_sub_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
402   %gep = getelementptr 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_dec_noret_i32:
408 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
409 ; SI: ds_dec_u32  v{{[0-9]+}}, [[NEGONE]]
410 ; SI: s_endpgm
411 define void @lds_atomic_dec_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_dec_noret_i32_offset:
417 ; SI: v_mov_b32_e32 [[NEGONE:v[0-9]+]], -1
418 ; SI: ds_dec_u32 v{{[0-9]+}}, [[NEGONE]] offset:16
419 ; SI: s_endpgm
420 define void @lds_atomic_dec_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
421   %gep = getelementptr 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 ; SI: ds_and_b32
428 ; SI: s_endpgm
429 define 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 ; SI: ds_and_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
436 ; SI: s_endpgm
437 define void @lds_atomic_and_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
438   %gep = getelementptr 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 ; SI: ds_or_b32
445 ; SI: s_endpgm
446 define 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 ; SI: ds_or_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
453 ; SI: s_endpgm
454 define void @lds_atomic_or_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
455   %gep = getelementptr 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 ; SI: ds_xor_b32
462 ; SI: s_endpgm
463 define 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 ; SI: ds_xor_b32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
470 ; SI: s_endpgm
471 define void @lds_atomic_xor_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
472   %gep = getelementptr 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 ; SI: ds_min_i32
486 ; SI: s_endpgm
487 define 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 ; SI: ds_min_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
494 ; SI: s_endpgm
495 define void @lds_atomic_min_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
496   %gep = getelementptr 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 ; SI: ds_max_i32
503 ; SI: s_endpgm
504 define 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 ; SI: ds_max_i32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
511 ; SI: s_endpgm
512 define void @lds_atomic_max_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
513   %gep = getelementptr 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 ; SI: ds_min_u32
520 ; SI: s_endpgm
521 define 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 ; SI: ds_min_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
528 ; SI: s_endpgm
529 define void @lds_atomic_umin_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
530   %gep = getelementptr 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 ; SI: ds_max_u32
537 ; SI: s_endpgm
538 define 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 ; SI: ds_max_u32 v{{[0-9]+}}, v{{[0-9]+}} offset:16
545 ; SI: s_endpgm
546 define void @lds_atomic_umax_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
547   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
548   %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst
549   ret void
550 }