• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Test parsing NaCl atomic instructions.
2
3; RUN: %p2i -i %s --insts | FileCheck %s
4; RUN:   %p2i -i %s --args -notranslate -timing | \
5; RUN:   FileCheck --check-prefix=NOIR %s
6
7declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
8declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
9declare i32 @llvm.nacl.atomic.load.i32(i32*, i32)
10declare i64 @llvm.nacl.atomic.load.i64(i64*, i32)
11declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32)
12declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32)
13declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32)
14declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32)
15declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32)
16declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32)
17declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32)
18declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32)
19declare i8 @llvm.nacl.atomic.cmpxchg.i8(i8*, i8, i8, i32, i32)
20declare i16 @llvm.nacl.atomic.cmpxchg.i16(i16*, i16, i16, i32, i32)
21declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32)
22declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32)
23declare void @llvm.nacl.atomic.fence(i32)
24declare void @llvm.nacl.atomic.fence.all()
25declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*)
26
27;;; Load
28
29define internal i32 @test_atomic_load_8(i32 %iptr) {
30entry:
31  %ptr = inttoptr i32 %iptr to i8*
32  ; parameter value "6" is for the sequential consistency memory order.
33  %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 6)
34  %r = zext i8 %i to i32
35  ret i32 %r
36}
37
38; CHECK:      define internal i32 @test_atomic_load_8(i32 %iptr) {
39; CHECK-NEXT: entry:
40; CHECK-NEXT:   %i = call i8 @llvm.nacl.atomic.load.i8(i32 %iptr, i32 6)
41; CHECK-NEXT:   %r = zext i8 %i to i32
42; CHECK-NEXT:   ret i32 %r
43; CHECK-NEXT: }
44
45define internal i32 @test_atomic_load_16(i32 %iptr) {
46entry:
47  %ptr = inttoptr i32 %iptr to i16*
48  %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 6)
49  %r = zext i16 %i to i32
50  ret i32 %r
51}
52
53; CHECK-NEXT: define internal i32 @test_atomic_load_16(i32 %iptr) {
54; CHECK-NEXT: entry:
55; CHECK-NEXT:   %i = call i16 @llvm.nacl.atomic.load.i16(i32 %iptr, i32 6)
56; CHECK-NEXT:   %r = zext i16 %i to i32
57; CHECK-NEXT:   ret i32 %r
58; CHECK-NEXT: }
59
60define internal i32 @test_atomic_load_32(i32 %iptr) {
61entry:
62  %ptr = inttoptr i32 %iptr to i32*
63  %r = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
64  ret i32 %r
65}
66
67; CHECK-NEXT: define internal i32 @test_atomic_load_32(i32 %iptr) {
68; CHECK-NEXT: entry:
69; CHECK-NEXT:   %r = call i32 @llvm.nacl.atomic.load.i32(i32 %iptr, i32 6)
70; CHECK-NEXT:   ret i32 %r
71; CHECK-NEXT: }
72
73define internal i64 @test_atomic_load_64(i32 %iptr) {
74entry:
75  %ptr = inttoptr i32 %iptr to i64*
76  %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6)
77  ret i64 %r
78}
79
80; CHECK-NEXT: define internal i64 @test_atomic_load_64(i32 %iptr) {
81; CHECK-NEXT: entry:
82; CHECK-NEXT:   %r = call i64 @llvm.nacl.atomic.load.i64(i32 %iptr, i32 6)
83; CHECK-NEXT:   ret i64 %r
84; CHECK-NEXT: }
85
86;;; Store
87
88define internal void @test_atomic_store_8(i32 %iptr, i32 %v) {
89entry:
90  %truncv = trunc i32 %v to i8
91  %ptr = inttoptr i32 %iptr to i8*
92  call void @llvm.nacl.atomic.store.i8(i8 %truncv, i8* %ptr, i32 6)
93  ret void
94}
95
96; CHECK-NEXT: define internal void @test_atomic_store_8(i32 %iptr, i32 %v) {
97; CHECK-NEXT: entry:
98; CHECK-NEXT:   %truncv = trunc i32 %v to i8
99; CHECK-NEXT:   call void @llvm.nacl.atomic.store.i8(i8 %truncv, i32 %iptr, i32 6)
100; CHECK-NEXT:   ret void
101; CHECK-NEXT: }
102
103define internal void @test_atomic_store_16(i32 %iptr, i32 %v) {
104entry:
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
111; CHECK-NEXT: define internal void @test_atomic_store_16(i32 %iptr, i32 %v) {
112; CHECK-NEXT: entry:
113; CHECK-NEXT:   %truncv = trunc i32 %v to i16
114; CHECK-NEXT:   call void @llvm.nacl.atomic.store.i16(i16 %truncv, i32 %iptr, i32 6)
115; CHECK-NEXT:   ret void
116; CHECK-NEXT: }
117
118define internal void @test_atomic_store_32(i32 %iptr, i32 %v) {
119entry:
120  %ptr = inttoptr i32 %iptr to i32*
121  call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 6)
122  ret void
123}
124
125; CHECK-NEXT: define internal void @test_atomic_store_32(i32 %iptr, i32 %v) {
126; CHECK-NEXT: entry:
127; CHECK-NEXT:   call void @llvm.nacl.atomic.store.i32(i32 %v, i32 %iptr, i32 6)
128; CHECK-NEXT:   ret void
129; CHECK-NEXT: }
130
131define internal void @test_atomic_store_64(i32 %iptr, i64 %v) {
132entry:
133  %ptr = inttoptr i32 %iptr to i64*
134  call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 6)
135  ret void
136}
137
138; CHECK-NEXT: define internal void @test_atomic_store_64(i32 %iptr, i64 %v) {
139; CHECK-NEXT: entry:
140; CHECK-NEXT:   call void @llvm.nacl.atomic.store.i64(i64 %v, i32 %iptr, i32 6)
141; CHECK-NEXT:   ret void
142; CHECK-NEXT: }
143
144define internal void @test_atomic_store_64_const(i32 %iptr) {
145entry:
146  %ptr = inttoptr i32 %iptr to i64*
147  call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 6)
148  ret void
149}
150
151; CHECK-NEXT: define internal void @test_atomic_store_64_const(i32 %iptr) {
152; CHECK-NEXT: entry:
153; CHECK-NEXT:   call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i32 %iptr, i32 6)
154; CHECK-NEXT:   ret void
155; CHECK-NEXT: }
156
157;;; RMW
158
159;; add
160
161define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) {
162entry:
163  %trunc = trunc i32 %v to i8
164  %ptr = inttoptr i32 %iptr to i8*
165  ; "1" is an atomic add, and "6" is sequential consistency.
166  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 6)
167  %a_ext = zext i8 %a to i32
168  ret i32 %a_ext
169}
170
171; CHECK-NEXT: define internal i32 @test_atomic_rmw_add_8(i32 %iptr, i32 %v) {
172; CHECK-NEXT: entry:
173; CHECK-NEXT:   %trunc = trunc i32 %v to i8
174; CHECK-NEXT:   %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i32 %iptr, i8 %trunc, i32 6)
175; CHECK-NEXT:   %a_ext = zext i8 %a to i32
176; CHECK-NEXT:   ret i32 %a_ext
177; CHECK-NEXT: }
178
179define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) {
180entry:
181  %trunc = trunc i32 %v to i16
182  %ptr = inttoptr i32 %iptr to i16*
183  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i16* %ptr, i16 %trunc, i32 6)
184  %a_ext = zext i16 %a to i32
185  ret i32 %a_ext
186}
187
188; CHECK-NEXT: define internal i32 @test_atomic_rmw_add_16(i32 %iptr, i32 %v) {
189; CHECK-NEXT: entry:
190; CHECK-NEXT:   %trunc = trunc i32 %v to i16
191; CHECK-NEXT:   %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 1, i32 %iptr, i16 %trunc, i32 6)
192; CHECK-NEXT:   %a_ext = zext i16 %a to i32
193; CHECK-NEXT:   ret i32 %a_ext
194; CHECK-NEXT: }
195
196define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) {
197entry:
198  %ptr = inttoptr i32 %iptr to i32*
199  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %v, i32 6)
200  ret i32 %a
201}
202
203; CHECK-NEXT: define internal i32 @test_atomic_rmw_add_32(i32 %iptr, i32 %v) {
204; CHECK-NEXT: entry:
205; CHECK-NEXT:   %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32 %iptr, i32 %v, i32 6)
206; CHECK-NEXT:   ret i32 %a
207; CHECK-NEXT: }
208
209define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) {
210entry:
211  %ptr = inttoptr i32 %iptr to i64*
212  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 6)
213  ret i64 %a
214}
215
216; CHECK-NEXT: define internal i64 @test_atomic_rmw_add_64(i32 %iptr, i64 %v) {
217; CHECK-NEXT: entry:
218; CHECK-NEXT:   %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i32 %iptr, i64 %v, i32 6)
219; CHECK-NEXT:   ret i64 %a
220; CHECK-NEXT: }
221
222;; sub
223
224define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) {
225entry:
226  %trunc = trunc i32 %v to i8
227  %ptr = inttoptr i32 %iptr to i8*
228  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 2, i8* %ptr, i8 %trunc, i32 6)
229  %a_ext = zext i8 %a to i32
230  ret i32 %a_ext
231}
232
233; CHECK-NEXT: define internal i32 @test_atomic_rmw_sub_8(i32 %iptr, i32 %v) {
234; CHECK-NEXT: entry:
235; CHECK-NEXT:   %trunc = trunc i32 %v to i8
236; CHECK-NEXT:   %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 2, i32 %iptr, i8 %trunc, i32 6)
237; CHECK-NEXT:   %a_ext = zext i8 %a to i32
238; CHECK-NEXT:   ret i32 %a_ext
239; CHECK-NEXT: }
240
241define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) {
242entry:
243  %trunc = trunc i32 %v to i16
244  %ptr = inttoptr i32 %iptr to i16*
245  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 2, i16* %ptr, i16 %trunc, i32 6)
246  %a_ext = zext i16 %a to i32
247  ret i32 %a_ext
248}
249
250; CHECK-NEXT: define internal i32 @test_atomic_rmw_sub_16(i32 %iptr, i32 %v) {
251; CHECK-NEXT: entry:
252; CHECK-NEXT:   %trunc = trunc i32 %v to i16
253; CHECK-NEXT:   %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 2, i32 %iptr, i16 %trunc, i32 6)
254; CHECK-NEXT:   %a_ext = zext i16 %a to i32
255; CHECK-NEXT:   ret i32 %a_ext
256; CHECK-NEXT: }
257
258define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) {
259entry:
260  %ptr = inttoptr i32 %iptr to i32*
261  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %v, i32 6)
262  ret i32 %a
263}
264
265; CHECK-NEXT: define internal i32 @test_atomic_rmw_sub_32(i32 %iptr, i32 %v) {
266; CHECK-NEXT: entry:
267; CHECK-NEXT:   %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32 %iptr, i32 %v, i32 6)
268; CHECK-NEXT:   ret i32 %a
269; CHECK-NEXT: }
270
271define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) {
272entry:
273  %ptr = inttoptr i32 %iptr to i64*
274  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 2, i64* %ptr, i64 %v, i32 6)
275  ret i64 %a
276}
277
278; CHECK-NEXT: define internal i64 @test_atomic_rmw_sub_64(i32 %iptr, i64 %v) {
279; CHECK-NEXT: entry:
280; CHECK-NEXT:   %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 2, i32 %iptr, i64 %v, i32 6)
281; CHECK-NEXT:   ret i64 %a
282; CHECK-NEXT: }
283
284;; or
285
286define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) {
287entry:
288  %trunc = trunc i32 %v to i8
289  %ptr = inttoptr i32 %iptr to i8*
290  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i8* %ptr, i8 %trunc, i32 6)
291  %a_ext = zext i8 %a to i32
292  ret i32 %a_ext
293}
294
295; CHECK-NEXT: define internal i32 @test_atomic_rmw_or_8(i32 %iptr, i32 %v) {
296; CHECK-NEXT: entry:
297; CHECK-NEXT:   %trunc = trunc i32 %v to i8
298; CHECK-NEXT:   %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 3, i32 %iptr, i8 %trunc, i32 6)
299; CHECK-NEXT:   %a_ext = zext i8 %a to i32
300; CHECK-NEXT:   ret i32 %a_ext
301; CHECK-NEXT: }
302
303define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) {
304entry:
305  %trunc = trunc i32 %v to i16
306  %ptr = inttoptr i32 %iptr to i16*
307  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i16* %ptr, i16 %trunc, i32 6)
308  %a_ext = zext i16 %a to i32
309  ret i32 %a_ext
310}
311
312; CHECK-NEXT: define internal i32 @test_atomic_rmw_or_16(i32 %iptr, i32 %v) {
313; CHECK-NEXT: entry:
314; CHECK-NEXT:   %trunc = trunc i32 %v to i16
315; CHECK-NEXT:   %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 3, i32 %iptr, i16 %trunc, i32 6)
316; CHECK-NEXT:   %a_ext = zext i16 %a to i32
317; CHECK-NEXT:   ret i32 %a_ext
318; CHECK-NEXT: }
319
320define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) {
321entry:
322  %ptr = inttoptr i32 %iptr to i32*
323  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %v, i32 6)
324  ret i32 %a
325}
326
327; CHECK-NEXT: define internal i32 @test_atomic_rmw_or_32(i32 %iptr, i32 %v) {
328; CHECK-NEXT: entry:
329; CHECK-NEXT:   %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32 %iptr, i32 %v, i32 6)
330; CHECK-NEXT:   ret i32 %a
331; CHECK-NEXT: }
332
333define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) {
334entry:
335  %ptr = inttoptr i32 %iptr to i64*
336  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i64* %ptr, i64 %v, i32 6)
337  ret i64 %a
338}
339
340; CHECK-NEXT: define internal i64 @test_atomic_rmw_or_64(i32 %iptr, i64 %v) {
341; CHECK-NEXT: entry:
342; CHECK-NEXT:   %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 3, i32 %iptr, i64 %v, i32 6)
343; CHECK-NEXT:   ret i64 %a
344; CHECK-NEXT: }
345
346;; and
347
348define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) {
349entry:
350  %trunc = trunc i32 %v to i8
351  %ptr = inttoptr i32 %iptr to i8*
352  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 4, i8* %ptr, i8 %trunc, i32 6)
353  %a_ext = zext i8 %a to i32
354  ret i32 %a_ext
355}
356
357; CHECK-NEXT: define internal i32 @test_atomic_rmw_and_8(i32 %iptr, i32 %v) {
358; CHECK-NEXT: entry:
359; CHECK-NEXT:   %trunc = trunc i32 %v to i8
360; CHECK-NEXT:   %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 4, i32 %iptr, i8 %trunc, i32 6)
361; CHECK-NEXT:   %a_ext = zext i8 %a to i32
362; CHECK-NEXT:   ret i32 %a_ext
363; CHECK-NEXT: }
364
365define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) {
366entry:
367  %trunc = trunc i32 %v to i16
368  %ptr = inttoptr i32 %iptr to i16*
369  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 4, i16* %ptr, i16 %trunc, i32 6)
370  %a_ext = zext i16 %a to i32
371  ret i32 %a_ext
372}
373
374; CHECK-NEXT: define internal i32 @test_atomic_rmw_and_16(i32 %iptr, i32 %v) {
375; CHECK-NEXT: entry:
376; CHECK-NEXT:   %trunc = trunc i32 %v to i16
377; CHECK-NEXT:   %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 4, i32 %iptr, i16 %trunc, i32 6)
378; CHECK-NEXT:   %a_ext = zext i16 %a to i32
379; CHECK-NEXT:   ret i32 %a_ext
380; CHECK-NEXT: }
381
382define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) {
383entry:
384  %ptr = inttoptr i32 %iptr to i32*
385  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %v, i32 6)
386  ret i32 %a
387}
388
389; CHECK-NEXT: define internal i32 @test_atomic_rmw_and_32(i32 %iptr, i32 %v) {
390; CHECK-NEXT: entry:
391; CHECK-NEXT:   %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32 %iptr, i32 %v, i32 6)
392; CHECK-NEXT:   ret i32 %a
393; CHECK-NEXT: }
394
395define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) {
396entry:
397  %ptr = inttoptr i32 %iptr to i64*
398  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 4, i64* %ptr, i64 %v, i32 6)
399  ret i64 %a
400}
401
402; CHECK-NEXT: define internal i64 @test_atomic_rmw_and_64(i32 %iptr, i64 %v) {
403; CHECK-NEXT: entry:
404; CHECK-NEXT:   %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 4, i32 %iptr, i64 %v, i32 6)
405; CHECK-NEXT:   ret i64 %a
406; CHECK-NEXT: }
407
408;; xor
409
410define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) {
411entry:
412  %trunc = trunc i32 %v to i8
413  %ptr = inttoptr i32 %iptr to i8*
414  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 5, i8* %ptr, i8 %trunc, i32 6)
415  %a_ext = zext i8 %a to i32
416  ret i32 %a_ext
417}
418
419; CHECK-NEXT: define internal i32 @test_atomic_rmw_xor_8(i32 %iptr, i32 %v) {
420; CHECK-NEXT: entry:
421; CHECK-NEXT:   %trunc = trunc i32 %v to i8
422; CHECK-NEXT:   %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 5, i32 %iptr, i8 %trunc, i32 6)
423; CHECK-NEXT:   %a_ext = zext i8 %a to i32
424; CHECK-NEXT:   ret i32 %a_ext
425; CHECK-NEXT: }
426
427define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) {
428entry:
429  %trunc = trunc i32 %v to i16
430  %ptr = inttoptr i32 %iptr to i16*
431  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 5, i16* %ptr, i16 %trunc, i32 6)
432  %a_ext = zext i16 %a to i32
433  ret i32 %a_ext
434}
435
436; CHECK-NEXT: define internal i32 @test_atomic_rmw_xor_16(i32 %iptr, i32 %v) {
437; CHECK-NEXT: entry:
438; CHECK-NEXT:   %trunc = trunc i32 %v to i16
439; CHECK-NEXT:   %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 5, i32 %iptr, i16 %trunc, i32 6)
440; CHECK-NEXT:   %a_ext = zext i16 %a to i32
441; CHECK-NEXT:   ret i32 %a_ext
442; CHECK-NEXT: }
443
444define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) {
445entry:
446  %ptr = inttoptr i32 %iptr to i32*
447  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %v, i32 6)
448  ret i32 %a
449}
450
451; CHECK-NEXT: define internal i32 @test_atomic_rmw_xor_32(i32 %iptr, i32 %v) {
452; CHECK-NEXT: entry:
453; CHECK-NEXT:   %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32 %iptr, i32 %v, i32 6)
454; CHECK-NEXT:   ret i32 %a
455; CHECK-NEXT: }
456
457define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) {
458entry:
459  %ptr = inttoptr i32 %iptr to i64*
460  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 5, i64* %ptr, i64 %v, i32 6)
461  ret i64 %a
462}
463
464; CHECK-NEXT: define internal i64 @test_atomic_rmw_xor_64(i32 %iptr, i64 %v) {
465; CHECK-NEXT: entry:
466; CHECK-NEXT:   %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 5, i32 %iptr, i64 %v, i32 6)
467; CHECK-NEXT:   ret i64 %a
468; CHECK-NEXT: }
469
470;; exchange
471
472define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) {
473entry:
474  %trunc = trunc i32 %v to i8
475  %ptr = inttoptr i32 %iptr to i8*
476  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 6, i8* %ptr, i8 %trunc, i32 6)
477  %a_ext = zext i8 %a to i32
478  ret i32 %a_ext
479}
480
481; CHECK-NEXT: define internal i32 @test_atomic_rmw_xchg_8(i32 %iptr, i32 %v) {
482; CHECK-NEXT: entry:
483; CHECK-NEXT:   %trunc = trunc i32 %v to i8
484; CHECK-NEXT:   %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 6, i32 %iptr, i8 %trunc, i32 6)
485; CHECK-NEXT:   %a_ext = zext i8 %a to i32
486; CHECK-NEXT:   ret i32 %a_ext
487; CHECK-NEXT: }
488
489define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) {
490entry:
491  %trunc = trunc i32 %v to i16
492  %ptr = inttoptr i32 %iptr to i16*
493  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 6, i16* %ptr, i16 %trunc, i32 6)
494  %a_ext = zext i16 %a to i32
495  ret i32 %a_ext
496}
497
498; CHECK-NEXT: define internal i32 @test_atomic_rmw_xchg_16(i32 %iptr, i32 %v) {
499; CHECK-NEXT: entry:
500; CHECK-NEXT:   %trunc = trunc i32 %v to i16
501; CHECK-NEXT:   %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 6, i32 %iptr, i16 %trunc, i32 6)
502; CHECK-NEXT:   %a_ext = zext i16 %a to i32
503; CHECK-NEXT:   ret i32 %a_ext
504; CHECK-NEXT: }
505
506define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) {
507entry:
508  %ptr = inttoptr i32 %iptr to i32*
509  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %v, i32 6)
510  ret i32 %a
511}
512
513; CHECK-NEXT: define internal i32 @test_atomic_rmw_xchg_32(i32 %iptr, i32 %v) {
514; CHECK-NEXT: entry:
515; CHECK-NEXT:   %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32 %iptr, i32 %v, i32 6)
516; CHECK-NEXT:   ret i32 %a
517; CHECK-NEXT: }
518
519define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) {
520entry:
521  %ptr = inttoptr i32 %iptr to i64*
522  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 6, i64* %ptr, i64 %v, i32 6)
523  ret i64 %a
524}
525
526; CHECK-NEXT: define internal i64 @test_atomic_rmw_xchg_64(i32 %iptr, i64 %v) {
527; CHECK-NEXT: entry:
528; CHECK-NEXT:   %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 6, i32 %iptr, i64 %v, i32 6)
529; CHECK-NEXT:   ret i64 %a
530; CHECK-NEXT: }
531
532;;;; Cmpxchg
533
534define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) {
535entry:
536  %trunc_exp = trunc i32 %expected to i8
537  %trunc_des = trunc i32 %desired to i8
538  %ptr = inttoptr i32 %iptr to i8*
539  %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i8* %ptr, i8 %trunc_exp,
540                                              i8 %trunc_des, i32 6, i32 6)
541  %old_ext = zext i8 %old to i32
542  ret i32 %old_ext
543}
544
545; CHECK-NEXT: define internal i32 @test_atomic_cmpxchg_8(i32 %iptr, i32 %expected, i32 %desired) {
546; CHECK-NEXT: entry:
547; CHECK-NEXT:   %trunc_exp = trunc i32 %expected to i8
548; CHECK-NEXT:   %trunc_des = trunc i32 %desired to i8
549; CHECK-NEXT:   %old = call i8 @llvm.nacl.atomic.cmpxchg.i8(i32 %iptr, i8 %trunc_exp, i8 %trunc_des, i32 6, i32 6)
550; CHECK-NEXT:   %old_ext = zext i8 %old to i32
551; CHECK-NEXT:   ret i32 %old_ext
552; CHECK-NEXT: }
553
554define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) {
555entry:
556  %trunc_exp = trunc i32 %expected to i16
557  %trunc_des = trunc i32 %desired to i16
558  %ptr = inttoptr i32 %iptr to i16*
559  %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp,
560                                               i16 %trunc_des, i32 6, i32 6)
561  %old_ext = zext i16 %old to i32
562  ret i32 %old_ext
563}
564
565; CHECK-NEXT: define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, i32 %desired) {
566; CHECK-NEXT: entry:
567; CHECK-NEXT:   %trunc_exp = trunc i32 %expected to i16
568; CHECK-NEXT:   %trunc_des = trunc i32 %desired to i16
569; CHECK-NEXT:   %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i32 %iptr, i16 %trunc_exp, i16 %trunc_des, i32 6, i32 6)
570; CHECK-NEXT:   %old_ext = zext i16 %old to i32
571; CHECK-NEXT:   ret i32 %old_ext
572; CHECK-NEXT: }
573
574define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) {
575entry:
576  %ptr = inttoptr i32 %iptr to i32*
577  %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
578                                               i32 %desired, i32 6, i32 6)
579  ret i32 %old
580}
581
582; CHECK-NEXT: define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, i32 %desired) {
583; CHECK-NEXT: entry:
584; CHECK-NEXT:   %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32 %iptr, i32 %expected, i32 %desired, i32 6, i32 6)
585; CHECK-NEXT:   ret i32 %old
586; CHECK-NEXT: }
587
588define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) {
589entry:
590  %ptr = inttoptr i32 %iptr to i64*
591  %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
592                                               i64 %desired, i32 6, i32 6)
593  ret i64 %old
594}
595
596; CHECK-NEXT: define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, i64 %desired) {
597; CHECK-NEXT: entry:
598; CHECK-NEXT:   %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i32 %iptr, i64 %expected, i64 %desired, i32 6, i32 6)
599; CHECK-NEXT:   ret i64 %old
600; CHECK-NEXT: }
601
602;;;; Fence and is-lock-free.
603
604define internal void @test_atomic_fence() {
605entry:
606  call void @llvm.nacl.atomic.fence(i32 6)
607  ret void
608}
609
610; CHECK-NEXT: define internal void @test_atomic_fence() {
611; CHECK-NEXT: entry:
612; CHECK-NEXT:   call void @llvm.nacl.atomic.fence(i32 6)
613; CHECK-NEXT:   ret void
614; CHECK-NEXT: }
615
616define internal void @test_atomic_fence_all() {
617entry:
618  call void @llvm.nacl.atomic.fence.all()
619  ret void
620}
621
622; CHECK-NEXT: define internal void @test_atomic_fence_all() {
623; CHECK-NEXT: entry:
624; CHECK-NEXT:   call void @llvm.nacl.atomic.fence.all()
625; CHECK-NEXT:   ret void
626; CHECK-NEXT: }
627
628define internal i32 @test_atomic_is_lock_free(i32 %iptr) {
629entry:
630  %ptr = inttoptr i32 %iptr to i8*
631  %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr)
632  %r = zext i1 %i to i32
633  ret i32 %r
634}
635
636; CHECK-NEXT: define internal i32 @test_atomic_is_lock_free(i32 %iptr) {
637; CHECK-NEXT: entry:
638; CHECK-NEXT:   %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i32 %iptr)
639; CHECK-NEXT:   %r = zext i1 %i to i32
640; CHECK-NEXT:   ret i32 %r
641; CHECK-NEXT: }
642
643; NOIR: Total across all functions
644