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

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: change comment Created 6 years, 5 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 | « tests_lit/llvm2ice_tests/nacl-atomic-fence-all.ll ('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 define i32 @test_atomic_load_32_ignored(i32 %iptr) {
91 entry:
92 %ptr = inttoptr i32 %iptr to i32*
93 %ignored = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
94 ret i32 0
95 }
96 ; CHECK-LABEL: test_atomic_load_32_ignored
97 ; CHECK: mov {{.*}}, dword
98 ; CHECK: mov {{.*}}, dword
99
100 define i64 @test_atomic_load_64_ignored(i32 %iptr) {
101 entry:
102 %ptr = inttoptr i32 %iptr to i64*
103 %ignored = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6)
104 ret i64 0
105 }
106 ; CHECK-LABEL: test_atomic_load_64_ignored
107 ; CHECK: movq x{{.*}}, qword
108 ; CHECK: movq qword {{.*}}, x{{.*}}
109
110
111 ;;; Store
112
113 define void @test_atomic_store_8(i32 %iptr, i32 %v) {
114 entry:
115 %truncv = trunc i32 %v to i8
116 %ptr = inttoptr i32 %iptr to i8*
117 call void @llvm.nacl.atomic.store.i8(i8 %truncv, i8* %ptr, i32 6)
118 ret void
119 }
120 ; CHECK-LABEL: test_atomic_store_8
121 ; CHECK: mov byte
122 ; CHECK: mfence
123
124 define void @test_atomic_store_16(i32 %iptr, i32 %v) {
125 entry:
126 %truncv = trunc i32 %v to i16
127 %ptr = inttoptr i32 %iptr to i16*
128 call void @llvm.nacl.atomic.store.i16(i16 %truncv, i16* %ptr, i32 6)
129 ret void
130 }
131 ; CHECK-LABEL: test_atomic_store_16
132 ; CHECK: mov word
133 ; CHECK: mfence
134
135 define void @test_atomic_store_32(i32 %iptr, i32 %v) {
136 entry:
137 %ptr = inttoptr i32 %iptr to i32*
138 call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 6)
139 ret void
140 }
141 ; CHECK-LABEL: test_atomic_store_32
142 ; CHECK: mov dword
143 ; CHECK: mfence
144
145 define void @test_atomic_store_64(i32 %iptr, i64 %v) {
146 entry:
147 %ptr = inttoptr i32 %iptr to i64*
148 call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 6)
149 ret void
150 }
151 ; CHECK-LABEL: test_atomic_store_64
152 ; CHECK: movq x{{.*}}, qword
153 ; CHECK: movq qword {{.*}}, x{{.*}}
154 ; CHECK: mfence
155
156 define void @test_atomic_store_64_const(i32 %iptr) {
157 entry:
158 %ptr = inttoptr i32 %iptr to i64*
159 call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6)
160 ret void
161 }
162 ; CHECK-LABEL: test_atomic_store_64_const
163 ; CHECK: mov {{.*}}, 1942892530
164 ; CHECK: mov {{.*}}, 2874
165 ; CHECK: movq x{{.*}}, qword
166 ; CHECK: movq qword {{.*}}, x{{.*}}
167 ; CHECK: mfence
168
169
170 ;;; RMW
171
172 define i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) {
173 entry:
174 %trunc = trunc i32 %v to i8
175 %ptr = inttoptr i32 %iptr to i8*
176 ; "1" is an atomic add, and "6" is sequential consistency.
177 %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 6)
178 %a_ext = zext i8 %a to i32
179 ret i32 %a_ext
180 }
181 ; CHECK-LABEL: test_atomic_rmw_add_8
182 ; CHECK: lock xadd byte {{.*}}, [[REG:.*]]
183 ; CHECK: mov {{.*}}, {{.*}}[[REG]]
184
185 define i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) {
186 entry:
187 %trunc = trunc i32 %v to i16
188 %ptr = inttoptr i32 %iptr to i16*
189 %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i16* %ptr, i16 %trunc, i32 6)
190 %a_ext = zext i16 %a to i32
191 ret i32 %a_ext
192 }
193 ; CHECK-LABEL: test_atomic_rmw_add_16
194 ; CHECK: lock xadd word {{.*}}, [[REG:.*]]
195 ; CHECK: mov {{.*}}, {{.*}}[[REG]]
196
197 define i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) {
198 entry:
199 %ptr = inttoptr i32 %iptr to i32*
200 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6)
201 ret i32 %a
202 }
203 ; CHECK-LABEL: test_atomic_rmw_add_32
204 ; CHECK: lock xadd dword {{.*}}, [[REG:.*]]
205 ; CHECK: mov {{.*}}, {{.*}}[[REG]]
206
207 ;define i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) {
208 ;entry:
209 ; %ptr = inttoptr i32 %iptr to i64*
210 ; %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6)
211 ; ret i64 %a
212 ;}
213 ; CHECKLATER-LABEL: test_atomic_rmw_add_64
214 ; CHECKLATER: uh need a... cmpxchg8b loop.
215
216 define i32 @test_atomic_rmw_add_32_ignored(i32 %iptr, i32 %v) {
217 entry:
218 %ptr = inttoptr i32 %iptr to i32*
219 %ignored = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6)
220 ret i32 %v
221 }
222 ; CHECK-LABEL: test_atomic_rmw_add_32_ignored
223 ; CHECK: lock xadd dword {{.*}}, [[REG:.*]]
224
225 ;define i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) {
226 ;entry:
227 ; %ptr = inttoptr i32 %iptr to i32*
228 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6)
229 ; ret i32 %a
230 ;}
231 ; CHECKLATER-LABEL: test_atomic_rmw_sub_32
232 ; CHECKLATER: neg
233 ; CHECKLATER: lock
234 ; CHECKLATER: xadd
235
236 ;define i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) {
237 ;entry:
238 ; %ptr = inttoptr i32 %iptr to i32*
239 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6)
240 ; ret i32 %a
241 ;}
242 ; CHECKLATER-LABEL: test_atomic_rmw_or_32
243 ; Need a cmpxchg loop.
244
245 ;define i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) {
246 ;entry:
247 ; %ptr = inttoptr i32 %iptr to i32*
248 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6)
249 ; ret i32 %a
250 ;}
251 ; CHECKLATER-LABEL: test_atomic_rmw_and_32
252 ; Also a cmpxchg loop.
253
254 ;define i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) {
255 ;entry:
256 ; %ptr = inttoptr i32 %iptr to i32*
257 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6)
258 ; ret i32 %a
259 ;}
260 ; CHECKLATER-LABEL: test_atomic_rmw_xor_32
261 ; Also a cmpxchg loop.
262
263 ;define i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) {
264 ;entry:
265 ; %ptr = inttoptr i32 %iptr to i32*
266 ; %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6)
267 ; ret i32 %a
268 ;}
269 ; CHECKLATER-LABEL: test_atomic_rmw_xchg_32
270
271 ;;;; Cmpxchg
272
273 ;define i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) {
274 ;entry:
275 ; %ptr = inttoptr i32 %iptr to i8*
276 ; %trunc_exp = trunc i32 %expected to i8
277 ; %trunc_des = trunc i32 %desired to i8
278 ; %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp,
279 ; i8 %trunc_des, i32 6, i32 6)
280 ; %old_ext = zext i8 %old to i32
281 ; ret i32 %old_ext
282 ;}
283 ; CHECKLATER-LABEL: test_atomic_cmpxchg_8
284 ; CHECKLATER: lock cmpxchg byte
285
286 ;define i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) {
287 ;entry:
288 ; %ptr = inttoptr i32 %iptr to i16*
289 ; %trunc_exp = trunc i32 %expected to i16
290 ; %trunc_des = trunc i32 %desired to i16
291 ; %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp,
292 ; i16 %trunc_des, i32 6, i32 6)
293 ; %old_ext = zext i16 %old to i32
294 ; ret i32 %old_ext
295 ;}
296 ; CHECKLATER-LABEL: test_atomic_cmpxchg_16
297 ; This one is a bit gross for NaCl right now.
298 ; https://code.google.com/p/nativeclient/issues/detail?id=2981
299 ; But we'll assume that NaCl will have it fixed...
300 ; CHECKLATER: lock cmpxchg word
301
302 ;define i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) {
303 ;entry:
304 ; %ptr = inttoptr i32 %iptr to i32*
305 ; %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
306 ; i32 %desired, i32 6, i32 6)
307 ; ret i32 %old
308 ;}
309 ; CHECKLATER-LABEL: test_atomic_cmpxchg_32
310 ; CHECKLATER: mov eax
311 ; CHECKLATER: mov ecx
312 ; CHECKLATER: lock cmpxchg dword
313
314 ;define i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) {
315 ;entry:
316 ; %ptr = inttoptr i32 %iptr to i64*
317 ; %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
318 ; i64 %desired, i32 6, i32 6)
319 ; ret i64 %old
320 ;}
321 ; CHECKLATER-LABEL: test_atomic_cmpxchg_64
322 ; CHECKLATER: mov eax
323 ; CHECKLATER: mov edx
324 ; CHECKLATER: mov ebx
325 ; CHECKLATER: mov ecx
326 ; CHECKLATER: lock cmpxchg8b qword
327
328 ;define i32 @test_atomic_cmpxchg_32_loop(i32 %iptr,
329 ; i32 %expected, i32 %desired) {
330 ;entry:
331 ; br label %loop
332 ;
333 ;loop:
334 ; %cmp = phi i32 [ %expected, %entry], [%old, %loop]
335 ; %ptr = inttoptr i32 %iptr to i32*
336 ; %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %cmp,
337 ; i32 %desired, i32 6, i32 6)
338 ; %success = icmp eq i32 %cmp, %old
339 ; br i1 %success, label %done, label %loop
340 ;
341 ;done:
342 ; ret i32 %old
343 ;}
344 ; CHECKLATER-LABEL: test_atomic_cmpxchg_32_loop
345
346 ;;;; Fence and is-lock-free.
347
348 define void @test_atomic_fence() {
349 entry:
350 call void @llvm.nacl.atomic.fence(i32 6)
351 ret void
352 }
353 ; CHECK-LABEL: test_atomic_fence
354 ; CHECK: mfence
355
356 define void @test_atomic_fence_all() {
357 entry:
358 call void @llvm.nacl.atomic.fence.all()
359 ret void
360 }
361 ; CHECK-LABEL: test_atomic_fence_all
362 ; CHECK: mfence
363
364 define i32 @test_atomic_is_lock_free(i32 %iptr) {
365 entry:
366 %ptr = inttoptr i32 %iptr to i8*
367 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr)
368 %r = zext i1 %i to i32
369 ret i32 %r
370 }
371 ; CHECK-LABEL: test_atomic_is_lock_free
372 ; CHECK: mov {{.*}}, 1
373
374 define i32 @test_not_lock_free(i32 %iptr) {
375 entry:
376 %ptr = inttoptr i32 %iptr to i8*
377 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 7, i8* %ptr)
378 %r = zext i1 %i to i32
379 ret i32 %r
380 }
381 ; CHECK-LABEL: test_not_lock_free
382 ; CHECK: mov {{.*}}, 0
383
384 ; TODO(jvoung): at some point we can take advantage of the
385 ; fact that nacl.atomic.is.lock.free will resolve to a constant
386 ; (which adds DCE opportunities). Once we optimize, the test expectations
387 ; for this case should change.
388 define i32 @test_atomic_is_lock_free_can_dce(i32 %iptr, i32 %x, i32 %y) {
389 entry:
390 %ptr = inttoptr i32 %iptr to i8*
391 %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr)
392 %i_ext = zext i1 %i to i32
393 %cmp = icmp eq i32 %i_ext, 1
394 br i1 %cmp, label %lock_free, label %not_lock_free
395 lock_free:
396 ret i32 %i_ext
397
398 not_lock_free:
399 %z = add i32 %x, %y
400 ret i32 %z
401 }
402 ; CHECK-LABEL: test_atomic_is_lock_free_can_dce
403 ; CHECK: mov {{.*}}, 1
404 ; CHECK: ret
405 ; CHECK: add
406 ; CHECK: ret
407
408 ; ERRORS-NOT: ICE translation error
409 ; DUMP-NOT: SZ
OLDNEW
« no previous file with comments | « tests_lit/llvm2ice_tests/nacl-atomic-fence-all.ll ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698