R600/SI: Add common 64-bit LDS atomics
[oota-llvm.git] / test / CodeGen / R600 / local-atomics64.ll
1 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
2
3 ; FUNC-LABEL: @lds_atomic_xchg_ret_i64:
4 ; SI: DS_WRXCHG_RTN_B64
5 ; SI: S_ENDPGM
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
9   ret void
10 }
11
12 ; FUNC-LABEL: @lds_atomic_xchg_ret_i64_offset:
13 ; SI: DS_WRXCHG_RTN_B64 {{.*}} 0x20
14 ; SI: S_ENDPGM
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
19   ret void
20 }
21
22 ; FUNC-LABEL: @lds_atomic_add_ret_i64:
23 ; SI: DS_ADD_RTN_U64
24 ; SI: S_ENDPGM
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
28   ret void
29 }
30
31 ; FUNC-LABEL: @lds_atomic_add_ret_i64_offset:
32 ; SI: S_LOAD_DWORD [[PTR:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
33 ; SI: S_MOV_B64 s{{\[}}[[LOSDATA:[0-9]+]]:[[HISDATA:[0-9]+]]{{\]}}, 9
34 ; SI-DAG: V_MOV_B32_e32 v[[LOVDATA:[0-9]+]], s[[LOSDATA]]
35 ; SI-DAG: V_MOV_B32_e32 v[[HIVDATA:[0-9]+]], s[[HISDATA]]
36 ; SI-DAG: V_MOV_B32_e32 [[VPTR:v[0-9]+]], [[PTR]]
37 ; SI: DS_ADD_RTN_U64 [[RESULT:v\[[0-9]+:[0-9]+\]]], [[VPTR]], v{{\[}}[[LOVDATA]]:[[HIVDATA]]{{\]}}, 0x20, [M0]
38 ; SI: BUFFER_STORE_DWORDX2 [[RESULT]],
39 ; SI: S_ENDPGM
40 define void @lds_atomic_add_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
41   %gep = getelementptr i64 addrspace(3)* %ptr, i64 4
42   %result = atomicrmw add i64 addrspace(3)* %gep, i64 9 seq_cst
43   store i64 %result, i64 addrspace(1)* %out, align 8
44   ret void
45 }
46
47 ; FUNC-LABEL: @lds_atomic_inc_ret_i64:
48 ; SI: DS_INC_RTN_U64
49 ; SI: S_ENDPGM
50 define void @lds_atomic_inc_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
51   %result = atomicrmw add i64 addrspace(3)* %ptr, i64 1 seq_cst
52   store i64 %result, i64 addrspace(1)* %out, align 8
53   ret void
54 }
55
56 ; FUNC-LABEL: @lds_atomic_inc_ret_i64_offset:
57 ; SI: DS_INC_RTN_U64 {{.*}} 0x20
58 ; SI: S_ENDPGM
59 define void @lds_atomic_inc_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
60   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
61   %result = atomicrmw add i64 addrspace(3)* %gep, i64 1 seq_cst
62   store i64 %result, i64 addrspace(1)* %out, align 8
63   ret void
64 }
65
66 ; FUNC-LABEL: @lds_atomic_sub_ret_i64:
67 ; SI: DS_SUB_RTN_U64
68 ; SI: S_ENDPGM
69 define void @lds_atomic_sub_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
70   %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 4 seq_cst
71   store i64 %result, i64 addrspace(1)* %out, align 8
72   ret void
73 }
74
75 ; FUNC-LABEL: @lds_atomic_sub_ret_i64_offset:
76 ; SI: DS_SUB_RTN_U64 {{.*}} 0x20
77 ; SI: S_ENDPGM
78 define void @lds_atomic_sub_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
79   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
80   %result = atomicrmw sub i64 addrspace(3)* %gep, i64 4 seq_cst
81   store i64 %result, i64 addrspace(1)* %out, align 8
82   ret void
83 }
84
85 ; FUNC-LABEL: @lds_atomic_dec_ret_i64:
86 ; SI: DS_DEC_RTN_U64
87 ; SI: S_ENDPGM
88 define void @lds_atomic_dec_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
89   %result = atomicrmw sub i64 addrspace(3)* %ptr, i64 1 seq_cst
90   store i64 %result, i64 addrspace(1)* %out, align 8
91   ret void
92 }
93
94 ; FUNC-LABEL: @lds_atomic_dec_ret_i64_offset:
95 ; SI: DS_DEC_RTN_U64 {{.*}} 0x20
96 ; SI: S_ENDPGM
97 define void @lds_atomic_dec_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
98   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
99   %result = atomicrmw sub i64 addrspace(3)* %gep, i64 1 seq_cst
100   store i64 %result, i64 addrspace(1)* %out, align 8
101   ret void
102 }
103
104 ; FUNC-LABEL: @lds_atomic_and_ret_i64:
105 ; SI: DS_AND_RTN_B64
106 ; SI: S_ENDPGM
107 define void @lds_atomic_and_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
108   %result = atomicrmw and i64 addrspace(3)* %ptr, i64 4 seq_cst
109   store i64 %result, i64 addrspace(1)* %out, align 8
110   ret void
111 }
112
113 ; FUNC-LABEL: @lds_atomic_and_ret_i64_offset:
114 ; SI: DS_AND_RTN_B64 {{.*}} 0x20
115 ; SI: S_ENDPGM
116 define void @lds_atomic_and_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
117   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
118   %result = atomicrmw and i64 addrspace(3)* %gep, i64 4 seq_cst
119   store i64 %result, i64 addrspace(1)* %out, align 8
120   ret void
121 }
122
123 ; FUNC-LABEL: @lds_atomic_or_ret_i64:
124 ; SI: DS_OR_RTN_B64
125 ; SI: S_ENDPGM
126 define void @lds_atomic_or_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
127   %result = atomicrmw or i64 addrspace(3)* %ptr, i64 4 seq_cst
128   store i64 %result, i64 addrspace(1)* %out, align 8
129   ret void
130 }
131
132 ; FUNC-LABEL: @lds_atomic_or_ret_i64_offset:
133 ; SI: DS_OR_RTN_B64 {{.*}} 0x20
134 ; SI: S_ENDPGM
135 define void @lds_atomic_or_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
136   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
137   %result = atomicrmw or i64 addrspace(3)* %gep, i64 4 seq_cst
138   store i64 %result, i64 addrspace(1)* %out, align 8
139   ret void
140 }
141
142 ; FUNC-LABEL: @lds_atomic_xor_ret_i64:
143 ; SI: DS_XOR_RTN_B64
144 ; SI: S_ENDPGM
145 define void @lds_atomic_xor_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
146   %result = atomicrmw xor i64 addrspace(3)* %ptr, i64 4 seq_cst
147   store i64 %result, i64 addrspace(1)* %out, align 8
148   ret void
149 }
150
151 ; FUNC-LABEL: @lds_atomic_xor_ret_i64_offset:
152 ; SI: DS_XOR_RTN_B64 {{.*}} 0x20
153 ; SI: S_ENDPGM
154 define void @lds_atomic_xor_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
155   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
156   %result = atomicrmw xor i64 addrspace(3)* %gep, i64 4 seq_cst
157   store i64 %result, i64 addrspace(1)* %out, align 8
158   ret void
159 }
160
161 ; FIXME: There is no atomic nand instr
162 ; XFUNC-LABEL: @lds_atomic_nand_ret_i64:uction, so we somehow need to expand this.
163 ; define void @lds_atomic_nand_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
164 ;   %result = atomicrmw nand i64 addrspace(3)* %ptr, i32 4 seq_cst
165 ;   store i64 %result, i64 addrspace(1)* %out, align 8
166 ;   ret void
167 ; }
168
169 ; FUNC-LABEL: @lds_atomic_min_ret_i64:
170 ; SI: DS_MIN_RTN_I64
171 ; SI: S_ENDPGM
172 define void @lds_atomic_min_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
173   %result = atomicrmw min i64 addrspace(3)* %ptr, i64 4 seq_cst
174   store i64 %result, i64 addrspace(1)* %out, align 8
175   ret void
176 }
177
178 ; FUNC-LABEL: @lds_atomic_min_ret_i64_offset:
179 ; SI: DS_MIN_RTN_I64 {{.*}} 0x20
180 ; SI: S_ENDPGM
181 define void @lds_atomic_min_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
182   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
183   %result = atomicrmw min i64 addrspace(3)* %gep, i64 4 seq_cst
184   store i64 %result, i64 addrspace(1)* %out, align 8
185   ret void
186 }
187
188 ; FUNC-LABEL: @lds_atomic_max_ret_i64:
189 ; SI: DS_MAX_RTN_I64
190 ; SI: S_ENDPGM
191 define void @lds_atomic_max_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
192   %result = atomicrmw max i64 addrspace(3)* %ptr, i64 4 seq_cst
193   store i64 %result, i64 addrspace(1)* %out, align 8
194   ret void
195 }
196
197 ; FUNC-LABEL: @lds_atomic_max_ret_i64_offset:
198 ; SI: DS_MAX_RTN_I64 {{.*}} 0x20
199 ; SI: S_ENDPGM
200 define void @lds_atomic_max_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
201   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
202   %result = atomicrmw max i64 addrspace(3)* %gep, i64 4 seq_cst
203   store i64 %result, i64 addrspace(1)* %out, align 8
204   ret void
205 }
206
207 ; FUNC-LABEL: @lds_atomic_umin_ret_i64:
208 ; SI: DS_MIN_RTN_U64
209 ; SI: S_ENDPGM
210 define void @lds_atomic_umin_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
211   %result = atomicrmw umin i64 addrspace(3)* %ptr, i64 4 seq_cst
212   store i64 %result, i64 addrspace(1)* %out, align 8
213   ret void
214 }
215
216 ; FUNC-LABEL: @lds_atomic_umin_ret_i64_offset:
217 ; SI: DS_MIN_RTN_U64 {{.*}} 0x20
218 ; SI: S_ENDPGM
219 define void @lds_atomic_umin_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
220   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
221   %result = atomicrmw umin i64 addrspace(3)* %gep, i64 4 seq_cst
222   store i64 %result, i64 addrspace(1)* %out, align 8
223   ret void
224 }
225
226 ; FUNC-LABEL: @lds_atomic_umax_ret_i64:
227 ; SI: DS_MAX_RTN_U64
228 ; SI: S_ENDPGM
229 define void @lds_atomic_umax_ret_i64(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
230   %result = atomicrmw umax i64 addrspace(3)* %ptr, i64 4 seq_cst
231   store i64 %result, i64 addrspace(1)* %out, align 8
232   ret void
233 }
234
235 ; FUNC-LABEL: @lds_atomic_umax_ret_i64_offset:
236 ; SI: DS_MAX_RTN_U64 {{.*}} 0x20
237 ; SI: S_ENDPGM
238 define void @lds_atomic_umax_ret_i64_offset(i64 addrspace(1)* %out, i64 addrspace(3)* %ptr) nounwind {
239   %gep = getelementptr i64 addrspace(3)* %ptr, i32 4
240   %result = atomicrmw umax i64 addrspace(3)* %gep, i64 4 seq_cst
241   store i64 %result, i64 addrspace(1)* %out, align 8
242   ret void
243 }