1; Test that some errors trigger when the usage of NaCl atomic
2; intrinsics does not match the required ABI.
3; REQUIRES: allow_dump
4
5; RUN: %p2i -i %s --args --verbose none --exit-success -threads=0 2>&1 \
6; RUN:   | FileCheck %s
7
8declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
9declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
10declare i64 @llvm.nacl.atomic.load.i64(i64*, i32)
11declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32)
12declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32)
13declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32)
14declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32)
15declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32)
16declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32)
17declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32)
18declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32)
19declare void @llvm.nacl.atomic.fence(i32)
20declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*)
21
22;;; Load
23;;; Check unexpected memory order parameter (release=4 and acq_rel=5
24;;; are disallowed).
25
26define internal i32 @error_atomic_load_8(i32 %iptr) {
27entry:
28  %ptr = inttoptr i32 %iptr to i8*
29  %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 0)
30  %r = zext i8 %i to i32
31  ret i32 %r
32}
33; CHECK: Unexpected memory ordering for AtomicLoad
34
35define internal i32 @error_atomic_load_16(i32 %iptr) {
36entry:
37  %ptr = inttoptr i32 %iptr to i16*
38  %i = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 4)
39  %r = zext i16 %i to i32
40  ret i32 %r
41}
42; CHECK: Unexpected memory ordering for AtomicLoad
43
44define internal i64 @error_atomic_load_64(i32 %iptr) {
45entry:
46  %ptr = inttoptr i32 %iptr to i64*
47  %r = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 5)
48  ret i64 %r
49}
50; CHECK: Unexpected memory ordering for AtomicLoad
51
52
53;;; Store
54;;; consume=2, acquire=3, acq_rel=5 are disallowed
55
56define internal void @error_atomic_store_32(i32 %iptr, i32 %v) {
57entry:
58  %ptr = inttoptr i32 %iptr to i32*
59  call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 2)
60  ret void
61}
62; CHECK: Unexpected memory ordering for AtomicStore
63
64define internal void @error_atomic_store_64(i32 %iptr, i64 %v) {
65entry:
66  %ptr = inttoptr i32 %iptr to i64*
67  call void @llvm.nacl.atomic.store.i64(i64 %v, i64* %ptr, i32 3)
68  ret void
69}
70; CHECK: Unexpected memory ordering for AtomicStore
71
72define internal void @error_atomic_store_64_const(i32 %iptr) {
73entry:
74  %ptr = inttoptr i32 %iptr to i64*
75  call void @llvm.nacl.atomic.store.i64(i64 12345678901234, i64* %ptr, i32 5)
76  ret void
77}
78; CHECK: Unexpected memory ordering for AtomicStore
79
80;;; RMW
81;;; Test atomic memory order and operation.
82;;; Modes 3:6 allowed.
83
84define internal i32 @error_atomic_rmw_add_8(i32 %iptr, i32 %v) {
85entry:
86  %trunc = trunc i32 %v to i8
87  %ptr = inttoptr i32 %iptr to i8*
88  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 1)
89  %a_ext = zext i8 %a to i32
90  ret i32 %a_ext
91}
92; CHECK: Unexpected memory ordering for AtomicRMW
93
94define internal i64 @error_atomic_rmw_add_64(i32 %iptr, i64 %v) {
95entry:
96  %ptr = inttoptr i32 %iptr to i64*
97  %a = call i64 @llvm.nacl.atomic.rmw.i64(i32 1, i64* %ptr, i64 %v, i32 7)
98  ret i64 %a
99}
100; CHECK: Unexpected memory ordering for AtomicRMW
101
102define internal i32 @error_atomic_rmw_add_16(i32 %iptr, i32 %v) {
103entry:
104  %trunc = trunc i32 %v to i16
105  %ptr = inttoptr i32 %iptr to i16*
106  %a = call i16 @llvm.nacl.atomic.rmw.i16(i32 0, i16* %ptr, i16 %trunc, i32 6)
107  %a_ext = zext i16 %a to i32
108  ret i32 %a_ext
109}
110; CHECK: Unknown AtomicRMW operation
111
112define internal i32 @error_atomic_rmw_add_32(i32 %iptr, i32 %v) {
113entry:
114  %ptr = inttoptr i32 %iptr to i32*
115  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 7, i32* %ptr, i32 %v, i32 6)
116  ret i32 %a
117}
118; CHECK: Unknown AtomicRMW operation
119
120define internal i32 @error_atomic_rmw_add_32_max(i32 %iptr, i32 %v) {
121entry:
122  %ptr = inttoptr i32 %iptr to i32*
123  %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 4294967295, i32* %ptr, i32 %v, i32 6)
124  ret i32 %a
125}
126; CHECK: Unknown AtomicRMW operation
127
128;;; Cmpxchg
129
130define internal i32 @error_atomic_cmpxchg_32_success(i32 %iptr, i32 %expected,
131                                                     i32 %desired) {
132entry:
133  %ptr = inttoptr i32 %iptr to i32*
134  %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
135                                               i32 %desired, i32 0, i32 6)
136  ret i32 %old
137}
138; CHECK: Unexpected memory ordering for AtomicCmpxchg
139
140define internal i32 @error_atomic_cmpxchg_32_failure(i32 %iptr, i32 %expected,
141                                                     i32 %desired) {
142entry:
143  %ptr = inttoptr i32 %iptr to i32*
144  %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
145                                               i32 %desired, i32 6, i32 0)
146  ret i32 %old
147}
148; CHECK: Unexpected memory ordering for AtomicCmpxchg
149
150define internal i64 @error_atomic_cmpxchg_64_failure(i32 %iptr, i64 %expected,
151                                                     i64 %desired) {
152entry:
153  %ptr = inttoptr i32 %iptr to i64*
154  %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected,
155                                               i64 %desired, i32 4, i32 1)
156  ret i64 %old
157}
158; CHECK: Unexpected memory ordering for AtomicCmpxchg
159
160;;; Fence and is-lock-free.
161
162define internal void @error_atomic_fence() {
163entry:
164  call void @llvm.nacl.atomic.fence(i32 0)
165  ret void
166}
167; CHECK: Unexpected memory ordering for AtomicFence
168
169define internal i32 @error_atomic_is_lock_free_var(i32 %iptr, i32 %bs) {
170entry:
171  %ptr = inttoptr i32 %iptr to i8*
172  %i = call i1 @llvm.nacl.atomic.is.lock.free(i32 %bs, i8* %ptr)
173  %r = zext i1 %i to i32
174  ret i32 %r
175}
176; CHECK: AtomicIsLockFree byte size should be compile-time const
177
178
179;;; Test bad non-constant memory ordering values.
180
181define internal i32 @error_atomic_load_8_nonconst(i32 %iptr) {
182entry:
183  %ptr = inttoptr i32 %iptr to i8*
184  %i = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 %iptr)
185  %r = zext i8 %i to i32
186  ret i32 %r
187}
188; CHECK: Unexpected memory ordering for AtomicLoad
189
190define internal void @error_atomic_store_32_nonconst(i32 %iptr, i32 %v) {
191entry:
192  %ptr = inttoptr i32 %iptr to i32*
193  call void @llvm.nacl.atomic.store.i32(i32 %v, i32* %ptr, i32 %v)
194  ret void
195}
196; CHECK: Unexpected memory ordering for AtomicStore
197
198define internal i32 @error_atomic_rmw_add_8_nonconst(i32 %iptr, i32 %v) {
199entry:
200  %trunc = trunc i32 %v to i8
201  %ptr = inttoptr i32 %iptr to i8*
202  %a = call i8 @llvm.nacl.atomic.rmw.i8(i32 1, i8* %ptr, i8 %trunc, i32 %iptr)
203  %a_ext = zext i8 %a to i32
204  ret i32 %a_ext
205}
206; CHECK: Unexpected memory ordering for AtomicRMW
207
208define internal i32 @error_atomic_cmpxchg_32_success_nonconst_1(i32 %iptr, i32 %expected,
209                                                                i32 %desired) {
210entry:
211  %ptr = inttoptr i32 %iptr to i32*
212  %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
213                                               i32 %desired, i32 %iptr, i32 6)
214  ret i32 %old
215}
216; CHECK: Unexpected memory ordering for AtomicCmpxchg
217
218define internal i32 @error_atomic_cmpxchg_32_success_nonconst_2(i32 %iptr, i32 %expected,
219                                                                i32 %desired) {
220entry:
221  %ptr = inttoptr i32 %iptr to i32*
222  %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected,
223                                               i32 %desired, i32 6, i32 %iptr)
224  ret i32 %old
225}
226; CHECK: Unexpected memory ordering for AtomicCmpxchg
227
228define internal void @error_atomic_fence_nonconst(i32 %v) {
229entry:
230  call void @llvm.nacl.atomic.fence(i32 %v)
231  ret void
232}
233; CHECK: Unexpected memory ordering for AtomicFence
234