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