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

Side by Side Diff: test/Transforms/NaCl/resolve-pnacl-intrinsics.ll

Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 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
OLDNEW
(Empty)
1 ; RUN: opt < %s -resolve-pnacl-intrinsics -S | FileCheck %s \
2 ; RUN: -check-prefix=CLEANED
3 ; RUN: opt < %s -resolve-pnacl-intrinsics -S | FileCheck %s
4
5 ; CLEANED-NOT: call i32 @llvm.nacl.setjmp
6 ; CLEANED-NOT: call void @llvm.nacl.longjmp
7 ; CLEANED-NOT: call {{.*}} @llvm.nacl.atomic
8
9 declare i32 @llvm.nacl.setjmp(i8*)
10 declare void @llvm.nacl.longjmp(i8*, i32)
11
12 ; Intrinsic name mangling is based on overloaded parameters only,
13 ; including return type. Note that all pointers parameters are
14 ; overloaded on type-pointed-to in Intrinsics.td, and are therefore
15 ; mangled on the type-pointed-to only.
16 declare i8 @llvm.nacl.atomic.load.i8(i8*, i32)
17 declare i16 @llvm.nacl.atomic.load.i16(i16*, i32)
18 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32)
19 declare i64 @llvm.nacl.atomic.load.i64(i64*, i32)
20 declare void @llvm.nacl.atomic.store.i8(i8, i8*, i32)
21 declare void @llvm.nacl.atomic.store.i16(i16, i16*, i32)
22 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32)
23 declare void @llvm.nacl.atomic.store.i64(i64, i64*, i32)
24 declare i8 @llvm.nacl.atomic.rmw.i8(i32, i8*, i8, i32)
25 declare i16 @llvm.nacl.atomic.rmw.i16(i32, i16*, i16, i32)
26 declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32)
27 declare i64 @llvm.nacl.atomic.rmw.i64(i32, i64*, i64, i32)
28 declare i8 @llvm.nacl.atomic.cmpxchg.i8(i8*, i8, i8, i32, i32)
29 declare i16 @llvm.nacl.atomic.cmpxchg.i16(i16*, i16, i16, i32, i32)
30 declare i32 @llvm.nacl.atomic.cmpxchg.i32(i32*, i32, i32, i32, i32)
31 declare i64 @llvm.nacl.atomic.cmpxchg.i64(i64*, i64, i64, i32, i32)
32 declare void @llvm.nacl.atomic.fence(i32)
33 declare void @llvm.nacl.atomic.fence.all()
34 declare i1 @llvm.nacl.atomic.is.lock.free(i32, i8*)
35
36 ; These declarations must be here because the function pass expects
37 ; to find them. In real life they're inserted by the translator
38 ; before the function pass runs.
39 declare i32 @setjmp(i8*)
40 declare void @longjmp(i8*, i32)
41
42 ; For correctness, the resulting call must get the "returns_twice" attribute.
43 define i32 @call_setjmp(i8* %arg) {
44 %val = call i32 @llvm.nacl.setjmp(i8* %arg)
45 ; CHECK: %val = call i32 @setjmp(i8* %arg) [[RETURNS_TWICE:#[0-9]+]]
46 ret i32 %val
47 }
48
49 define void @call_longjmp(i8* %arg, i32 %num) {
50 call void @llvm.nacl.longjmp(i8* %arg, i32 %num)
51 ; CHECK: call void @longjmp(i8* %arg, i32 %num){{$}}
52 ret void
53 }
54
55 ; atomics.
56
57 ; CHECK-LABEL: @test_atomic_acquire
58 define i32 @test_atomic_acquire(i32* %ptr) {
59 ; CHECK: %1 = load atomic i32* %ptr acquire, align 4
60 %1 = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 3)
61 ret i32 %1
62 }
63
64 ; CHECK-LABEL: @test_atomic_release
65 define void @test_atomic_release(i32* %ptr, i32 %value) {
66 ; CHECK: store atomic i32 %value, i32* %ptr release, align 4
67 call void @llvm.nacl.atomic.store.i32(i32 %value, i32* %ptr, i32 4)
68 ret void
69 }
70
71 ; CHECK-LABEL: @test_atomic_acquire_release
72 define i32 @test_atomic_acquire_release(i32* %ptr, i32 %value) {
73 ; CHECK: %1 = atomicrmw add i32* %ptr, i32 %value acq_rel
74 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %value, i32 5)
75 ret i32 %1
76 }
77
78 ; CHECK-LABEL: @test_fetch_and_add_i32
79 define i32 @test_fetch_and_add_i32(i32* %ptr, i32 %value) {
80 ; CHECK: %1 = atomicrmw add i32* %ptr, i32 %value seq_cst
81 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 1, i32* %ptr, i32 %value, i32 6)
82 ret i32 %1
83 }
84
85 ; CHECK-LABEL: @test_fetch_and_sub_i32
86 define i32 @test_fetch_and_sub_i32(i32* %ptr, i32 %value) {
87 ; CHECK: %1 = atomicrmw sub i32* %ptr, i32 %value seq_cst
88 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 2, i32* %ptr, i32 %value, i32 6)
89 ret i32 %1
90 }
91
92 ; CHECK-LABEL: @test_fetch_and_or_i32
93 define i32 @test_fetch_and_or_i32(i32* %ptr, i32 %value) {
94 ; CHECK: %1 = atomicrmw or i32* %ptr, i32 %value seq_cst
95 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 3, i32* %ptr, i32 %value, i32 6)
96 ret i32 %1
97 }
98
99 ; CHECK-LABEL: @test_fetch_and_and_i32
100 define i32 @test_fetch_and_and_i32(i32* %ptr, i32 %value) {
101 ; CHECK: %1 = atomicrmw and i32* %ptr, i32 %value seq_cst
102 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 4, i32* %ptr, i32 %value, i32 6)
103 ret i32 %1
104 }
105
106 ; CHECK-LABEL: @test_fetch_and_xor_i32
107 define i32 @test_fetch_and_xor_i32(i32* %ptr, i32 %value) {
108 ; CHECK: %1 = atomicrmw xor i32* %ptr, i32 %value seq_cst
109 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %value, i32 6)
110 ret i32 %1
111 }
112
113 ; Test different compare-and-swap patterns that commonly occur and are a bit
114 ; tricky because the PNaCl intrinsic only returns the value whereas the LLVM
115 ; intrinsic also returns the success flag (equivalent to comparing the oldval
116 ; with what was just loaded).
117
118 ; CHECK-LABEL: @test_val_compare_and_swap_i32
119 define i32 @test_val_compare_and_swap_i32(i32* %ptr, i32 %oldval, i32 %newval) {
120 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
121 ; CHECK-NEXT: %2 = extractvalue { i32, i1 } %1, 0
122 ; CHECK-NEXT: ret i32 %2
123 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 6, i32 6)
124 ret i32 %1
125 }
126
127 ; CHECK-LABEL: @test_val_compare_and_swap_i32_new
128 define i32 @test_val_compare_and_swap_i32_new(i32* %ptr, i32 %oldval, i32 %newva l) {
129 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
130 ; CHECK-NEXT: %res2 = extractvalue { i32, i1 } %1, 0
131 ; CHECK-NEXT: ret i32 %res2
132 %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %new val, i32 6, i32 6)
133 %success = icmp eq i32 %res, %oldval
134 %res.insert.value = insertvalue { i32, i1 } undef, i32 %res, 0
135 %res.insert.success = insertvalue { i32, i1 } %res.insert.value, i1 %success, 1
136 %val = extractvalue { i32, i1 } %res.insert.success, 0
137 ret i32 %val
138 }
139
140 ; CHECK-LABEL: @test_bool_compare_and_swap_i32
141 define i1 @test_bool_compare_and_swap_i32(i32* %ptr, i32 %oldval, i32 %newval) {
142 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
143 ; CHECK-NEXT: %success = extractvalue { i32, i1 } %1, 1
144 ; CHECK-NEXT: ret i1 %success
145 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 6, i32 6)
146 %2 = icmp eq i32 %1, %oldval
147 ret i1 %2
148 }
149
150 ; CHECK-LABEL: @test_bool_compare_and_swap_i32_new
151 define i1 @test_bool_compare_and_swap_i32_new(i32* %ptr, i32 %oldval, i32 %newva l) {
152 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
153 ; CHECK-NEXT: %suc = extractvalue { i32, i1 } %1, 1
154 ; CHECK-NEXT: ret i1 %suc
155 %res = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %new val, i32 6, i32 6)
156 %success = icmp eq i32 %res, %oldval
157 %res.insert.value = insertvalue { i32, i1 } undef, i32 %res, 0
158 %res.insert.success = insertvalue { i32, i1 } %res.insert.value, i1 %success, 1
159 %suc = extractvalue { i32, i1 } %res.insert.success, 1
160 ret i1 %suc
161 }
162
163 ; CHECK-LABEL: @test_bool_compare_and_swap_i32_reordered
164 define i1 @test_bool_compare_and_swap_i32_reordered(i32* %ptr, i32 %oldval, i32 %newval) {
165 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
166 ; CHECK-NEXT: %success = extractvalue { i32, i1 } %1, 1
167 ; CHECK-NEXT: ret i1 %success
168 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 6, i32 6)
169 %2 = icmp eq i32 %oldval, %1 ; Note operands are swapped from above.
170 ret i1 %2
171 }
172
173 ; CHECK-LABEL: @test_struct_compare_and_swap_i32
174 define { i32, i1 } @test_struct_compare_and_swap_i32(i32* %ptr, i32 %oldval, i32 %newval) {
175 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
176 ; CHECK-NEXT: ret { i32, i1 } %1
177 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 6, i32 6)
178 %2 = icmp eq i32 %1, %oldval
179 %3 = insertvalue { i32, i1 } undef, i32 %1, 0
180 %4 = insertvalue { i32, i1 } %3, i1 %2, 1
181 ret { i32, i1 } %4
182 }
183
184 ; Test all allowed cmpxchg success/failure memory orderings.
185
186 ; CHECK-LABEL: @test_cmpxchg_seqcst_seqcst
187 define i32 @test_cmpxchg_seqcst_seqcst(i32* %ptr, i32 %oldval, i32 %newval) {
188 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst seq_cst
189 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 6, i32 6)
190 ret i32 %1
191 }
192
193 ; CHECK-LABEL: @test_cmpxchg_seqcst_acquire
194 define i32 @test_cmpxchg_seqcst_acquire(i32* %ptr, i32 %oldval, i32 %newval) {
195 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval seq_cst acquire
196 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 6, i32 3)
197 ret i32 %1
198 }
199
200 ; CHECK-LABEL: @test_cmpxchg_acquire_acquire
201 define i32 @test_cmpxchg_acquire_acquire(i32* %ptr, i32 %oldval, i32 %newval) {
202 ; CHECK: %1 = cmpxchg i32* %ptr, i32 %oldval, i32 %newval acquire acquire
203 %1 = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %oldval, i32 %newva l, i32 3, i32 3)
204 ret i32 %1
205 }
206
207 ; CHECK-LABEL: @test_c11_fence
208 define void @test_c11_fence() {
209 ; CHECK: fence seq_cst
210 call void @llvm.nacl.atomic.fence(i32 6)
211 ret void
212 }
213
214 ; CHECK-LABEL: @test_synchronize
215 define void @test_synchronize() {
216 ; CHECK: call void asm sideeffect "", "~{memory}"()
217 ; CHECK: fence seq_cst
218 ; CHECK: call void asm sideeffect "", "~{memory}"()
219 call void @llvm.nacl.atomic.fence.all()
220 ret void
221 }
222
223 ; CHECK-LABEL: @test_is_lock_free_1
224 define i1 @test_is_lock_free_1(i8* %ptr) {
225 ; CHECK: ret i1 {{true|false}}
226 %res = call i1 @llvm.nacl.atomic.is.lock.free(i32 1, i8* %ptr)
227 ret i1 %res
228 }
229
230 ; CHECK-LABEL: @test_is_lock_free_2
231 define i1 @test_is_lock_free_2(i16* %ptr) {
232 ; CHECK: ret i1 {{true|false}}
233 %ptr2 = bitcast i16* %ptr to i8*
234 %res = call i1 @llvm.nacl.atomic.is.lock.free(i32 2, i8* %ptr2)
235 ret i1 %res
236 }
237
238 ; CHECK-LABEL: @test_is_lock_free_4
239 define i1 @test_is_lock_free_4(i32* %ptr) {
240 ; CHECK: ret i1 {{true|false}}
241 %ptr2 = bitcast i32* %ptr to i8*
242 %res = call i1 @llvm.nacl.atomic.is.lock.free(i32 4, i8* %ptr2)
243 ret i1 %res
244 }
245
246 ; CHECK-LABEL: @test_is_lock_free_8
247 define i1 @test_is_lock_free_8(i64* %ptr) {
248 ; CHECK: ret i1 {{true|false}}
249 %ptr2 = bitcast i64* %ptr to i8*
250 %res = call i1 @llvm.nacl.atomic.is.lock.free(i32 8, i8* %ptr2)
251 ret i1 %res
252 }
253
254 ; CHECK-LABEL: @test_lock_test_and_set_i32
255 define i32 @test_lock_test_and_set_i32(i32* %ptr, i32 %value) {
256 ; CHECK: %1 = atomicrmw xchg i32* %ptr, i32 %value seq_cst
257 %1 = call i32 @llvm.nacl.atomic.rmw.i32(i32 6, i32* %ptr, i32 %value, i32 6)
258 ret i32 %1
259 }
260
261 ; CHECK-LABEL: @test_lock_release_i32
262 define void @test_lock_release_i32(i32* %ptr) {
263 ; Note that the 'release' was changed to a 'seq_cst'.
264 ; CHECK: store atomic i32 0, i32* %ptr seq_cst, align 4
265 call void @llvm.nacl.atomic.store.i32(i32 0, i32* %ptr, i32 6)
266 ret void
267 }
268
269 ; CHECK-LABEL: @test_atomic_load_i8
270 define zeroext i8 @test_atomic_load_i8(i8* %ptr) {
271 ; CHECK: %1 = load atomic i8* %ptr seq_cst, align 1
272 %1 = call i8 @llvm.nacl.atomic.load.i8(i8* %ptr, i32 6)
273 ret i8 %1
274 }
275
276 ; CHECK-LABEL: @test_atomic_store_i8
277 define void @test_atomic_store_i8(i8* %ptr, i8 zeroext %value) {
278 ; CHECK: store atomic i8 %value, i8* %ptr seq_cst, align 1
279 call void @llvm.nacl.atomic.store.i8(i8 %value, i8* %ptr, i32 6)
280 ret void
281 }
282
283 ; CHECK-LABEL: @test_atomic_load_i16
284 define zeroext i16 @test_atomic_load_i16(i16* %ptr) {
285 ; CHECK: %1 = load atomic i16* %ptr seq_cst, align 2
286 %1 = call i16 @llvm.nacl.atomic.load.i16(i16* %ptr, i32 6)
287 ret i16 %1
288 }
289
290 ; CHECK-LABEL: @test_atomic_store_i16
291 define void @test_atomic_store_i16(i16* %ptr, i16 zeroext %value) {
292 ; CHECK: store atomic i16 %value, i16* %ptr seq_cst, align 2
293 call void @llvm.nacl.atomic.store.i16(i16 %value, i16* %ptr, i32 6)
294 ret void
295 }
296
297 ; CHECK-LABEL: @test_atomic_load_i32
298 define i32 @test_atomic_load_i32(i32* %ptr) {
299 ; CHECK: %1 = load atomic i32* %ptr seq_cst, align 4
300 %1 = call i32 @llvm.nacl.atomic.load.i32(i32* %ptr, i32 6)
301 ret i32 %1
302 }
303
304 ; CHECK-LABEL: @test_atomic_store_i32
305 define void @test_atomic_store_i32(i32* %ptr, i32 %value) {
306 ; CHECK: store atomic i32 %value, i32* %ptr seq_cst, align 4
307 call void @llvm.nacl.atomic.store.i32(i32 %value, i32* %ptr, i32 6)
308 ret void
309 }
310
311 ; CHECK-LABEL: @test_atomic_load_i64
312 define i64 @test_atomic_load_i64(i64* %ptr) {
313 ; CHECK: %1 = load atomic i64* %ptr seq_cst, align 8
314 %1 = call i64 @llvm.nacl.atomic.load.i64(i64* %ptr, i32 6)
315 ret i64 %1
316 }
317
318 ; CHECK-LABEL: @test_atomic_store_i64
319 define void @test_atomic_store_i64(i64* %ptr, i64 %value) {
320 ; CHECK: store atomic i64 %value, i64* %ptr seq_cst, align 8
321 call void @llvm.nacl.atomic.store.i64(i64 %value, i64* %ptr, i32 6)
322 ret void
323 }
324
325 ; CHECK: attributes [[RETURNS_TWICE]] = { returns_twice }
OLDNEW
« no previous file with comments | « test/Transforms/NaCl/resolve-aliases.ll ('k') | test/Transforms/NaCl/rewrite-call-with-libfunc-argument.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698