340290c4f94b0b87691d7630a1acd4201461c3c4
[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 ; 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]], 0x0, [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]+}}, 0x10
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]], 0x0, [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]+}}, 0x10
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]+}}, 0x0
59 ; CI: DS_ADD_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
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: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
73 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
74 ; SI: DS_INC_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]], 0x0
75 ; SI: S_ENDPGM
76 define void @lds_atomic_inc_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_inc_ret_i32_offset:
83 ; EG: LDS_ADD_RET *
84 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
85 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
86 ; SI: DS_INC_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]], 0x10
87 ; SI: S_ENDPGM
88 define void @lds_atomic_inc_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
89   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
90   %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
91   store i32 %result, i32 addrspace(1)* %out, align 4
92   ret void
93 }
94
95 ; FUNC-LABEL: {{^}}lds_atomic_inc_ret_i32_bad_si_offset:
96 ; EG: LDS_ADD_RET *
97 ; SI: DS_INC_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x0
98 ; CI: DS_INC_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
99 ; SI: S_ENDPGM
100 define void @lds_atomic_inc_ret_i32_bad_si_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
101   %sub = sub i32 %a, %b
102   %add = add i32 %sub, 4
103   %gep = getelementptr i32 addrspace(3)* %ptr, i32 %add
104   %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 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:
110 ; EG: LDS_SUB_RET *
111 ; SI: DS_SUB_RTN_U32
112 ; SI: S_ENDPGM
113 define void @lds_atomic_sub_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
114   %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst
115   store i32 %result, i32 addrspace(1)* %out, align 4
116   ret void
117 }
118
119 ; FUNC-LABEL: {{^}}lds_atomic_sub_ret_i32_offset:
120 ; EG: LDS_SUB_RET *
121 ; SI: DS_SUB_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
122 ; SI: S_ENDPGM
123 define void @lds_atomic_sub_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
124   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
125   %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 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:
131 ; EG: LDS_SUB_RET *
132 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
133 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
134 ; SI: DS_DEC_RTN_U32  v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]], 0x0
135 ; SI: S_ENDPGM
136 define void @lds_atomic_dec_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
137   %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst
138   store i32 %result, i32 addrspace(1)* %out, align 4
139   ret void
140 }
141
142 ; FUNC-LABEL: {{^}}lds_atomic_dec_ret_i32_offset:
143 ; EG: LDS_SUB_RET *
144 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
145 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
146 ; SI: DS_DEC_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, [[NEGONE]], 0x10
147 ; SI: S_ENDPGM
148 define void @lds_atomic_dec_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
149   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
150   %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst
151   store i32 %result, i32 addrspace(1)* %out, align 4
152   ret void
153 }
154
155 ; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32:
156 ; EG: LDS_AND_RET *
157 ; SI: DS_AND_RTN_B32
158 ; SI: S_ENDPGM
159 define void @lds_atomic_and_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
160   %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst
161   store i32 %result, i32 addrspace(1)* %out, align 4
162   ret void
163 }
164
165 ; FUNC-LABEL: {{^}}lds_atomic_and_ret_i32_offset:
166 ; EG: LDS_AND_RET *
167 ; SI: DS_AND_RTN_B32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
168 ; SI: S_ENDPGM
169 define void @lds_atomic_and_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
170   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
171   %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst
172   store i32 %result, i32 addrspace(1)* %out, align 4
173   ret void
174 }
175
176 ; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32:
177 ; EG: LDS_OR_RET *
178 ; SI: DS_OR_RTN_B32
179 ; SI: S_ENDPGM
180 define void @lds_atomic_or_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
181   %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst
182   store i32 %result, i32 addrspace(1)* %out, align 4
183   ret void
184 }
185
186 ; FUNC-LABEL: {{^}}lds_atomic_or_ret_i32_offset:
187 ; EG: LDS_OR_RET *
188 ; SI: DS_OR_RTN_B32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
189 ; SI: S_ENDPGM
190 define void @lds_atomic_or_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
191   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
192   %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst
193   store i32 %result, i32 addrspace(1)* %out, align 4
194   ret void
195 }
196
197 ; FUNC-LABEL: {{^}}lds_atomic_xor_ret_i32:
198 ; EG: LDS_XOR_RET *
199 ; SI: DS_XOR_RTN_B32
200 ; SI: S_ENDPGM
201 define void @lds_atomic_xor_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
202   %result = atomicrmw xor 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_xor_ret_i32_offset:
208 ; EG: LDS_XOR_RET *
209 ; SI: DS_XOR_RTN_B32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
210 ; SI: S_ENDPGM
211 define void @lds_atomic_xor_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
212   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
213   %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst
214   store i32 %result, i32 addrspace(1)* %out, align 4
215   ret void
216 }
217
218 ; FIXME: There is no atomic nand instr
219 ; XFUNC-LABEL: {{^}}lds_atomic_nand_ret_i32:uction, so we somehow need to expand this.
220 ; define void @lds_atomic_nand_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
221 ;   %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst
222 ;   store i32 %result, i32 addrspace(1)* %out, align 4
223 ;   ret void
224 ; }
225
226 ; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32:
227 ; EG: LDS_MIN_INT_RET *
228 ; SI: DS_MIN_RTN_I32
229 ; SI: S_ENDPGM
230 define void @lds_atomic_min_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
231   %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst
232   store i32 %result, i32 addrspace(1)* %out, align 4
233   ret void
234 }
235
236 ; FUNC-LABEL: {{^}}lds_atomic_min_ret_i32_offset:
237 ; EG: LDS_MIN_INT_RET *
238 ; SI: DS_MIN_RTN_I32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
239 ; SI: S_ENDPGM
240 define void @lds_atomic_min_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
241   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
242   %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst
243   store i32 %result, i32 addrspace(1)* %out, align 4
244   ret void
245 }
246
247 ; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32:
248 ; EG: LDS_MAX_INT_RET *
249 ; SI: DS_MAX_RTN_I32
250 ; SI: S_ENDPGM
251 define void @lds_atomic_max_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
252   %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst
253   store i32 %result, i32 addrspace(1)* %out, align 4
254   ret void
255 }
256
257 ; FUNC-LABEL: {{^}}lds_atomic_max_ret_i32_offset:
258 ; EG: LDS_MAX_INT_RET *
259 ; SI: DS_MAX_RTN_I32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
260 ; SI: S_ENDPGM
261 define void @lds_atomic_max_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
262   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
263   %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst
264   store i32 %result, i32 addrspace(1)* %out, align 4
265   ret void
266 }
267
268 ; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32:
269 ; EG: LDS_MIN_UINT_RET *
270 ; SI: DS_MIN_RTN_U32
271 ; SI: S_ENDPGM
272 define void @lds_atomic_umin_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
273   %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst
274   store i32 %result, i32 addrspace(1)* %out, align 4
275   ret void
276 }
277
278 ; FUNC-LABEL: {{^}}lds_atomic_umin_ret_i32_offset:
279 ; EG: LDS_MIN_UINT_RET *
280 ; SI: DS_MIN_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
281 ; SI: S_ENDPGM
282 define void @lds_atomic_umin_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
283   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
284   %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst
285   store i32 %result, i32 addrspace(1)* %out, align 4
286   ret void
287 }
288
289 ; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32:
290 ; EG: LDS_MAX_UINT_RET *
291 ; SI: DS_MAX_RTN_U32
292 ; SI: S_ENDPGM
293 define void @lds_atomic_umax_ret_i32(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
294   %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst
295   store i32 %result, i32 addrspace(1)* %out, align 4
296   ret void
297 }
298
299 ; FUNC-LABEL: {{^}}lds_atomic_umax_ret_i32_offset:
300 ; EG: LDS_MAX_UINT_RET *
301 ; SI: DS_MAX_RTN_U32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
302 ; SI: S_ENDPGM
303 define void @lds_atomic_umax_ret_i32_offset(i32 addrspace(1)* %out, i32 addrspace(3)* %ptr) nounwind {
304   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
305   %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst
306   store i32 %result, i32 addrspace(1)* %out, align 4
307   ret void
308 }
309
310 ; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32:
311 ; SI: S_LOAD_DWORD [[SPTR:s[0-9]+]],
312 ; SI: V_MOV_B32_e32 [[DATA:v[0-9]+]], 4
313 ; SI: V_MOV_B32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
314 ; SI: DS_WRXCHG_RTN_B32 [[RESULT:v[0-9]+]], [[VPTR]], [[DATA]], 0x0, [M0]
315 ; SI: S_ENDPGM
316 define void @lds_atomic_xchg_noret_i32(i32 addrspace(3)* %ptr) nounwind {
317   %result = atomicrmw xchg i32 addrspace(3)* %ptr, i32 4 seq_cst
318   ret void
319 }
320
321 ; FUNC-LABEL: {{^}}lds_atomic_xchg_noret_i32_offset:
322 ; SI: DS_WRXCHG_RTN_B32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, 0x10
323 ; SI: S_ENDPGM
324 define void @lds_atomic_xchg_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
325   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
326   %result = atomicrmw xchg i32 addrspace(3)* %gep, i32 4 seq_cst
327   ret void
328 }
329
330 ; XXX - Is it really necessary to load 4 into VGPR?
331 ; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32:
332 ; SI: S_LOAD_DWORD [[SPTR:s[0-9]+]],
333 ; SI: V_MOV_B32_e32 [[DATA:v[0-9]+]], 4
334 ; SI: V_MOV_B32_e32 [[VPTR:v[0-9]+]], [[SPTR]]
335 ; SI: DS_ADD_U32 [[VPTR]], [[DATA]], 0x0, [M0]
336 ; SI: S_ENDPGM
337 define void @lds_atomic_add_noret_i32(i32 addrspace(3)* %ptr) nounwind {
338   %result = atomicrmw add i32 addrspace(3)* %ptr, i32 4 seq_cst
339   ret void
340 }
341
342 ; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_offset:
343 ; SI: DS_ADD_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
344 ; SI: S_ENDPGM
345 define void @lds_atomic_add_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
346   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
347   %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
348   ret void
349 }
350
351 ; FUNC-LABEL: {{^}}lds_atomic_add_noret_i32_bad_si_offset:
352 ; SI: DS_ADD_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x0
353 ; CI: DS_ADD_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
354 ; SI: S_ENDPGM
355 define void @lds_atomic_add_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
356   %sub = sub i32 %a, %b
357   %add = add i32 %sub, 4
358   %gep = getelementptr i32 addrspace(3)* %ptr, i32 %add
359   %result = atomicrmw add i32 addrspace(3)* %gep, i32 4 seq_cst
360   ret void
361 }
362
363 ; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i32:
364 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
365 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
366 ; SI: DS_INC_U32 v{{[0-9]+}}, [[NEGONE]], 0x0
367 ; SI: S_ENDPGM
368 define void @lds_atomic_inc_noret_i32(i32 addrspace(3)* %ptr) nounwind {
369   %result = atomicrmw add i32 addrspace(3)* %ptr, i32 1 seq_cst
370   ret void
371 }
372
373 ; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i32_offset:
374 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
375 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
376 ; SI: DS_INC_U32 v{{[0-9]+}}, [[NEGONE]], 0x10
377 ; SI: S_ENDPGM
378 define void @lds_atomic_inc_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
379   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
380   %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
381   ret void
382 }
383
384 ; FUNC-LABEL: {{^}}lds_atomic_inc_noret_i32_bad_si_offset:
385 ; SI: DS_INC_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x0
386 ; CI: DS_INC_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
387 ; SI: S_ENDPGM
388 define void @lds_atomic_inc_noret_i32_bad_si_offset(i32 addrspace(3)* %ptr, i32 %a, i32 %b) nounwind {
389   %sub = sub i32 %a, %b
390   %add = add i32 %sub, 4
391   %gep = getelementptr i32 addrspace(3)* %ptr, i32 %add
392   %result = atomicrmw add i32 addrspace(3)* %gep, i32 1 seq_cst
393   ret void
394 }
395
396 ; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32:
397 ; SI: DS_SUB_U32
398 ; SI: S_ENDPGM
399 define void @lds_atomic_sub_noret_i32(i32 addrspace(3)* %ptr) nounwind {
400   %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 4 seq_cst
401   ret void
402 }
403
404 ; FUNC-LABEL: {{^}}lds_atomic_sub_noret_i32_offset:
405 ; SI: DS_SUB_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
406 ; SI: S_ENDPGM
407 define void @lds_atomic_sub_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
408   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
409   %result = atomicrmw sub i32 addrspace(3)* %gep, i32 4 seq_cst
410   ret void
411 }
412
413 ; FUNC-LABEL: {{^}}lds_atomic_dec_noret_i32:
414 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
415 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
416 ; SI: DS_DEC_U32  v{{[0-9]+}}, [[NEGONE]], 0x0
417 ; SI: S_ENDPGM
418 define void @lds_atomic_dec_noret_i32(i32 addrspace(3)* %ptr) nounwind {
419   %result = atomicrmw sub i32 addrspace(3)* %ptr, i32 1 seq_cst
420   ret void
421 }
422
423 ; FUNC-LABEL: {{^}}lds_atomic_dec_noret_i32_offset:
424 ; SI: S_MOV_B32 [[SNEGONE:s[0-9]+]], -1
425 ; SI: V_MOV_B32_e32 [[NEGONE:v[0-9]+]], [[SNEGONE]]
426 ; SI: DS_DEC_U32 v{{[0-9]+}}, [[NEGONE]], 0x10
427 ; SI: S_ENDPGM
428 define void @lds_atomic_dec_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
429   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
430   %result = atomicrmw sub i32 addrspace(3)* %gep, i32 1 seq_cst
431   ret void
432 }
433
434 ; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32:
435 ; SI: DS_AND_B32
436 ; SI: S_ENDPGM
437 define void @lds_atomic_and_noret_i32(i32 addrspace(3)* %ptr) nounwind {
438   %result = atomicrmw and i32 addrspace(3)* %ptr, i32 4 seq_cst
439   ret void
440 }
441
442 ; FUNC-LABEL: {{^}}lds_atomic_and_noret_i32_offset:
443 ; SI: DS_AND_B32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
444 ; SI: S_ENDPGM
445 define void @lds_atomic_and_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
446   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
447   %result = atomicrmw and i32 addrspace(3)* %gep, i32 4 seq_cst
448   ret void
449 }
450
451 ; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32:
452 ; SI: DS_OR_B32
453 ; SI: S_ENDPGM
454 define void @lds_atomic_or_noret_i32(i32 addrspace(3)* %ptr) nounwind {
455   %result = atomicrmw or i32 addrspace(3)* %ptr, i32 4 seq_cst
456   ret void
457 }
458
459 ; FUNC-LABEL: {{^}}lds_atomic_or_noret_i32_offset:
460 ; SI: DS_OR_B32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
461 ; SI: S_ENDPGM
462 define void @lds_atomic_or_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
463   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
464   %result = atomicrmw or i32 addrspace(3)* %gep, i32 4 seq_cst
465   ret void
466 }
467
468 ; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32:
469 ; SI: DS_XOR_B32
470 ; SI: S_ENDPGM
471 define void @lds_atomic_xor_noret_i32(i32 addrspace(3)* %ptr) nounwind {
472   %result = atomicrmw xor i32 addrspace(3)* %ptr, i32 4 seq_cst
473   ret void
474 }
475
476 ; FUNC-LABEL: {{^}}lds_atomic_xor_noret_i32_offset:
477 ; SI: DS_XOR_B32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
478 ; SI: S_ENDPGM
479 define void @lds_atomic_xor_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
480   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
481   %result = atomicrmw xor i32 addrspace(3)* %gep, i32 4 seq_cst
482   ret void
483 }
484
485 ; FIXME: There is no atomic nand instr
486 ; XFUNC-LABEL: {{^}}lds_atomic_nand_noret_i32:uction, so we somehow need to expand this.
487 ; define void @lds_atomic_nand_noret_i32(i32 addrspace(3)* %ptr) nounwind {
488 ;   %result = atomicrmw nand i32 addrspace(3)* %ptr, i32 4 seq_cst
489 ;   ret void
490 ; }
491
492 ; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32:
493 ; SI: DS_MIN_I32
494 ; SI: S_ENDPGM
495 define void @lds_atomic_min_noret_i32(i32 addrspace(3)* %ptr) nounwind {
496   %result = atomicrmw min i32 addrspace(3)* %ptr, i32 4 seq_cst
497   ret void
498 }
499
500 ; FUNC-LABEL: {{^}}lds_atomic_min_noret_i32_offset:
501 ; SI: DS_MIN_I32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
502 ; SI: S_ENDPGM
503 define void @lds_atomic_min_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
504   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
505   %result = atomicrmw min i32 addrspace(3)* %gep, i32 4 seq_cst
506   ret void
507 }
508
509 ; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32:
510 ; SI: DS_MAX_I32
511 ; SI: S_ENDPGM
512 define void @lds_atomic_max_noret_i32(i32 addrspace(3)* %ptr) nounwind {
513   %result = atomicrmw max i32 addrspace(3)* %ptr, i32 4 seq_cst
514   ret void
515 }
516
517 ; FUNC-LABEL: {{^}}lds_atomic_max_noret_i32_offset:
518 ; SI: DS_MAX_I32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
519 ; SI: S_ENDPGM
520 define void @lds_atomic_max_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
521   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
522   %result = atomicrmw max i32 addrspace(3)* %gep, i32 4 seq_cst
523   ret void
524 }
525
526 ; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32:
527 ; SI: DS_MIN_U32
528 ; SI: S_ENDPGM
529 define void @lds_atomic_umin_noret_i32(i32 addrspace(3)* %ptr) nounwind {
530   %result = atomicrmw umin i32 addrspace(3)* %ptr, i32 4 seq_cst
531   ret void
532 }
533
534 ; FUNC-LABEL: {{^}}lds_atomic_umin_noret_i32_offset:
535 ; SI: DS_MIN_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
536 ; SI: S_ENDPGM
537 define void @lds_atomic_umin_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
538   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
539   %result = atomicrmw umin i32 addrspace(3)* %gep, i32 4 seq_cst
540   ret void
541 }
542
543 ; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32:
544 ; SI: DS_MAX_U32
545 ; SI: S_ENDPGM
546 define void @lds_atomic_umax_noret_i32(i32 addrspace(3)* %ptr) nounwind {
547   %result = atomicrmw umax i32 addrspace(3)* %ptr, i32 4 seq_cst
548   ret void
549 }
550
551 ; FUNC-LABEL: {{^}}lds_atomic_umax_noret_i32_offset:
552 ; SI: DS_MAX_U32 v{{[0-9]+}}, v{{[0-9]+}}, 0x10
553 ; SI: S_ENDPGM
554 define void @lds_atomic_umax_noret_i32_offset(i32 addrspace(3)* %ptr) nounwind {
555   %gep = getelementptr i32 addrspace(3)* %ptr, i32 4
556   %result = atomicrmw umax i32 addrspace(3)* %gep, i32 4 seq_cst
557   ret void
558 }