Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Side by Side Diff: tests_lit/llvm2ice_tests/nacl-atomic-intrinsics.ll

Issue 342763004: Add atomic load/store, fetch_add, fence, and is-lock-free lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: beef up test a bit Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/llvm2ice.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 ; This tests each of the supported NaCl atomic instructions for every
2 ; size allowed.
3
4 ; RUN: %llvm2ice -O2 --verbose none %s | FileCheck %s
5 ; RUN: %llvm2ice -Om1 --verbose none %s | FileCheck %s
6 ; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s
7 ; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s
8 ; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \
9 ; RUN: | FileCheck --check-prefix=DUMP %s
10
11 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
12 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
13 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32)
14 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32)
15 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32)
16 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32)
17 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32)
18 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32)
19 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32)
20 declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32)
21 declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32)
22 declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32)
23 declare i8 @llvm.nacl.atomic.cmpxchg.i8(i8*, i8, i8, i32, i32)
24 declare i16 @llvm.nacl.atomic.cmpxchg.i16(i16*, i16, i16, i32, i32)
25 declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32)
26 declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32)
27 declare void @llvm.nacl.atomic.fence(i32)
28 declare void @llvm.nacl.atomic.fence.all()
29 declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*)
30
31 ;;; Load
32
33 ; x86 guarantees load/store to be atomic if naturally aligned.
34 ; The PNaCl IR requires all atomic accesses to be naturally aligned.
35
36 define i32 @test_atomic_load_8(i32 %iptr) {
37 entry:
38 %ptr = inttoptr i32 %iptr to i8*
39 ; parameter value "6" is for the sequential consistency memory order.
40 %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 6)
41 %r = zext i8 %i to i32
42 ret i32 %r
43 }
44 ; CHECK-LABEL: test_atomic_load_8
45 ; CHECK: mov {{.*}}, dword
46 ; CHECK: mov {{.*}}, byte
47
48 define i32 @test_atomic_load_16(i32 %iptr) {
49 entry:
50 %ptr = inttoptr i32 %iptr to i16*
51 %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 6)
52 %r = zext i16 %i to i32
53 ret i32 %r
54 }
55 ; CHECK-LABEL: test_atomic_load_16
56 ; CHECK: mov {{.*}}, dword
57 ; CHECK: mov {{.*}}, word
58
59 define i32 @test_atomic_load_32(i32 %iptr) {
60 entry:
61 %ptr = inttoptr i32 %iptr to i32*
62 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
63 ret i32 %r
64 }
65 ; CHECK-LABEL: test_atomic_load_32
66 ; CHECK: mov {{.*}}, dword
67 ; CHECK: mov {{.*}}, dword
68
69 define i64 @test_atomic_load_64(i32 %iptr) {
70 entry:
71 %ptr = inttoptr i32 %iptr to i64*
72 %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6)
73 ret i64 %r
74 }
75 ; CHECK-LABEL: test_atomic_load_64
76 ; CHECK: movq x{{.*}}, qword
77 ; CHECK: movq qword {{.*}}, x{{.*}}
78
79 define i32 @test_atomic_load_32_with_arith(i32 %iptr) {
80 entry:
81 %ptr = inttoptr i32 %iptr to i32*
82 %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
83 %r2 = add i32 %r, 32
84 ret i32 %r2
85 }
86 ; CHECK-LABEL: test_atomic_load_32_with_arith
87 ; CHECK: mov {{.*}}, dword
88 ; The next instruction may be a separate load or folded into an add.
89
90 ;;; Store
91
92 define void @test_atomic_store_8(i32 %iptr, i32 %v) {
93 entry:
94 %truncv = trunc i32 %v to i8
95 %ptr = inttoptr i32 %iptr to i8*
96 call void @llvm.nacl.atomic.store.i8(i8 %truncv, i8* %ptr, i32 6)
97 ret void
98 }
99 ; CHECK-LABEL: test_atomic_store_8
100 ; CHECK: mov byte
101 ; CHECK: mfence
102
103 define void @test_atomic_store_16(i32 %iptr, i32 %v) {
104 entry:
105 %truncv = trunc i32 %v to i16
106 %ptr = inttoptr i32 %iptr to i16*
107 call void @llvm.nacl.atomic.store.i16(i16 %truncv, i16* %ptr, i32 6)
108 ret void
109 }
110 ; CHECK-LABEL: test_atomic_store_16
111 ; CHECK: mov word
112 ; CHECK: mfence
113
114 define void @test_atomic_store_32(i32 %iptr, i32 %v) {
115 entry:
116 %ptr = inttoptr i32 %iptr to i32*
117 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 6)
118 ret void
119 }
120 ; CHECK-LABEL: test_atomic_store_32
121 ; CHECK: mov dword
122 ; CHECK: mfence
123
124 define void @test_atomic_store_64(i32 %iptr, i64 %v) {
125 entry:
126 %ptr = inttoptr i32 %iptr to i64*
127 call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 6)
128 ret void
129 }
130 ; CHECK-LABEL: test_atomic_store_64
131 ; CHECK: movq x{{.*}}, qword
132 ; CHECK: movq qword {{.*}}, x{{.*}}
133 ; CHECK: mfence
134
135 define void @test_atomic_store_64_const(i32 %iptr) {
136 entry:
137 %ptr = inttoptr i32 %iptr to i64*
138 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6)
139 ret void
140 }
141 ; CHECK-LABEL: test_atomic_store_64_const
142 ; TODO(jvoung): the 64-bit constant materialization
jvoung (off chromium) 2014/06/20 23:21:07 Started looking into this: looks like this is beca
143 ; doesn't seem to be right (not split up).
144 ; CHECK: movq x{{.*}}, qword
145 ; CHECK: movq qword {{.*}}, x{{.*}}
146 ; CHECK: mfence
147
148
149 ;;; RMW
150
151 define i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) {
152 entry:
153 %trunc = trunc i32 %v to i8
154 %ptr = inttoptr i32 %iptr to i8*
155 ; "1" is an atomic add, and "6" is sequential consistency.
156 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 6)
157 %a_ext = zext i8 %a to i32
158 ret i32 %a_ext
159 }
160 ; CHECK-LABEL: test_atomic_rmw_add_8
161 ; CHECK: lock xadd byte {{.*}}, [[REG:.*]]
162 ; CHECK: mov {{.*}}, {{.*}}[[REG]]
163
164 define i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) {
165 entry:
166 %trunc = trunc i32 %v to i16
167 %ptr = inttoptr i32 %iptr to i16*
168 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i16* %ptr, i16 %trunc, i32 6)
169 %a_ext = zext i16 %a to i32
170 ret i32 %a_ext
171 }
172 ; CHECK-LABEL: test_atomic_rmw_add_16
173 ; CHECK: lock xadd word {{.*}}, [[REG:.*]]
174 ; CHECK: mov {{.*}}, {{.*}}[[REG]]
175
176 define i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) {
177 entry:
178 %ptr = inttoptr i32 %iptr to i32*
179 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6)
180 ret i32 %a
181 }
182 ; CHECK-LABEL: test_atomic_rmw_add_32
183 ; CHECK: lock xadd dword {{.*}}, [[REG:.*]]
184 ; CHECK: mov {{.*}}, {{.*}}[[REG]]
185
186 ;define i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) {
187 ;entry:
188 ; %ptr = inttoptr i32 %iptr to i64*
189 ; %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6)
190 ; ret i64 %a
191 ;}
192 ; CHECKLATER-LABEL: test_atomic_rmw_add_64
193 ; CHECKLATER: uh need a... cmpxchg8b loop.
194
195 ;define i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) {
196 ;entry:
197 ; %ptr = inttoptr i32 %iptr to i32*
198 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6)
199 ; ret i32 %a
200 ;}
201 ; CHECKLATER-LABEL: test_atomic_rmw_sub_32
202 ; CHECKLATER: neg
203 ; CHECKLATER: lock
204 ; CHECKLATER: xadd
205
206 ;define i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) {
207 ;entry:
208 ; %ptr = inttoptr i32 %iptr to i32*
209 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6)
210 ; ret i32 %a
211 ;}
212 ; CHECKLATER-LABEL: test_atomic_rmw_or_32
213 ; Need a cmpxchg loop.
214
215 ;define i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) {
216 ;entry:
217 ; %ptr = inttoptr i32 %iptr to i32*
218 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6)
219 ; ret i32 %a
220 ;}
221 ; CHECKLATER-LABEL: test_atomic_rmw_and_32
222 ; Also a cmpxchg loop.
223
224 ;define i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) {
225 ;entry:
226 ; %ptr = inttoptr i32 %iptr to i32*
227 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6)
228 ; ret i32 %a
229 ;}
230 ; CHECKLATER-LABEL: test_atomic_rmw_xor_32
231 ; Also a cmpxchg loop.
232
233 ;define i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) {
234 ;entry:
235 ; %ptr = inttoptr i32 %iptr to i32*
236 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6)
237 ; ret i32 %a
238 ;}
239 ; CHECKLATER-LABEL: test_atomic_rmw_xchg_32
240
241 ;;;; Cmpxchg
242
243 ;define i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) {
244 ;entry:
245 ; %ptr = inttoptr i32 %iptr to i8*
246 ; %trunc_exp = trunc i32 %expected to i8
247 ; %trunc_des = trunc i32 %desired to i8
248 ; %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp,
249 ; i8 %trunc_des, i32 6, i32 6)
250 ; %old_ext = zext i8 %old to i32
251 ; ret i32 %old_ext
252 ;}
253 ; CHECKLATER-LABEL: test_atomic_cmpxchg_8
254 ; CHECKLATER: lock cmpxchg byte
255
256 ;define i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) {
257 ;entry:
258 ; %ptr = inttoptr i32 %iptr to i16*
259 ; %trunc_exp = trunc i32 %expected to i16
260 ; %trunc_des = trunc i32 %desired to i16
261 ; %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp,
262 ; i16 %trunc_des, i32 6, i32 6)
263 ; %old_ext = zext i16 %old to i32
264 ; ret i32 %old_ext
265 ;}
266 ; CHECKLATER-LABEL: test_atomic_cmpxchg_16
267 ; This one is a bit gross for NaCl right now.
268 ; https://code.google.com/p/nativeclient/issues/detail?id=2981
269 ; But we'll assume that NaCl will have it fixed...
270 ; CHECKLATER: lock cmpxchg word
271
272 ;define i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) {
273 ;entry:
274 ; %ptr = inttoptr i32 %iptr to i32*
275 ; %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
276 ; i32 %desired, i32 6, i32 6)
277 ; ret i32 %old
278 ;}
279 ; CHECKLATER-LABEL: test_atomic_cmpxchg_32
280 ; CHECKLATER: mov eax
281 ; CHECKLATER: mov ecx
282 ; CHECKLATER: lock cmpxchg dword
283
284 ;define i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) {
285 ;entry:
286 ; %ptr = inttoptr i32 %iptr to i64*
287 ; %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
288 ; i64 %desired, i32 6, i32 6)
289 ; ret i64 %old
290 ;}
291 ; CHECKLATER-LABEL: test_atomic_cmpxchg_64
292 ; CHECKLATER: mov eax
293 ; CHECKLATER: mov edx
294 ; CHECKLATER: mov ebx
295 ; CHECKLATER: mov ecx
296 ; CHECKLATER: lock cmpxchg8b qword
297
298 ;define i32 @test_atomic_cmpxchg_32_loop(i32 %iptr,
299 ; i32 %expected, i32 %desired) {
300 ;entry:
301 ; br label %loop
302 ;
303 ;loop:
304 ; %cmp = phi i32 [ %expected, %entry], [%old, %loop]
305 ; %ptr = inttoptr i32 %iptr to i32*
306 ; %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %cmp,
307 ; i32 %desired, i32 6, i32 6)
308 ; %success = icmp eq i32 %cmp, %old
309 ; br i1 %success, label %done, label %loop
310 ;
311 ;done:
312 ; ret i32 %old
313 ;}
314 ; CHECKLATER-LABEL: test_atomic_cmpxchg_32_loop
315
316 ;;;; Fence and is-lock-free.
317
318 define void @test_atomic_fence() {
319 entry:
320 call void @llvm.nacl.atomic.fence(i32 6)
321 ret void
322 }
323 ; CHECK-LABEL: test_atomic_fence
324 ; CHECK: mfence
325
326 define void @test_atomic_fence_all() {
327 entry:
328 call void @llvm.nacl.atomic.fence.all()
329 ret void
330 }
331 ; CHECK-LABEL: test_atomic_fence_all
332 ; CHECK: mfence
333
334 define i32 @test_atomic_is_lock_free(i32 %iptr) {
335 entry:
336 %ptr = inttoptr i32 %iptr to i8*
337 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 6, i8* %ptr)
338 %r = zext i1 %i to i32
339 ret i32 %r
340 }
341 ; CHECK-LABEL: test_atomic_is_lock_free
342 ; CHECK: mov {{.*}}, 1
343
344 ; ERRORS-NOT: ICE translation error
345 ; DUMP-NOT: SZ
OLDNEW
« no previous file with comments | « src/llvm2ice.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698