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

Side by Side Diff: test/Transforms/NaCl/replace-ptrs-with-ints.ll

Issue 14262011: PNaCl: Add ReplacePtrsWithInts pass for stripping out pointer types (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Add test for ConstantPointerNull Created 7 years, 7 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 -replace-ptrs-with-ints -S | FileCheck %s
2
3 target datalayout = "p:32:32:32"
4
5
6 declare %struct* @addr_taken_func(%struct*)
7
8 @addr_of_func = global %struct* (%struct*)* @addr_taken_func
9 ; CHECK: @addr_of_func = global %struct* (%struct*)* bitcast (i32 (i32)* @addr_t aken_func to %struct* (%struct*)*)
10
11 @blockaddr = global i8* blockaddress(@indirectbr, %l1)
12 ; CHECK: @blockaddr = global i8* blockaddress(@indirectbr, %l1)
13
14
15 define i8* @pointer_arg(i8* %ptr, i64 %non_ptr) {
16 ret i8* %ptr
17 }
18 ; CHECK: define i32 @pointer_arg(i32 %ptr, i64 %non_ptr) {
19 ; CHECK-NEXT: ret i32 %ptr
20 ; CHECK-NEXT: }
21
22
23 declare i8* @declared_func(i8*, i64)
24 ; CHECK: declare i32 @declared_func(i32, i64)
25
26
27 define void @return_void() {
eliben 2013/05/15 22:11:21 What is this for?
Mark Seaborn 2013/05/16 02:08:40 This was just checking that the pass doesn't barf
28 ret void
29 }
30
31
32 define void @self_reference(i8* %ptr) {
33 entry:
34 br label %loop
35 loop:
36 %x = phi i8* [ %x, %loop ], [ %ptr, %entry ]
37 br label %loop
38 }
39 ; CHECK: define void @self_reference(i32 %ptr) {
40 ; CHECK: %x = phi i32 [ %x, %loop ], [ %ptr, %entry ]
41
42 define i8* @phi_multiple_entry(i1 %arg, i8* %ptr) {
43 entry:
44 br i1 %arg, label %done, label %done
45 done:
46 %result = phi i8* [ %ptr, %entry ], [ %ptr, %entry ]
47 ret i8* %result
48 }
49 ; CHECK: define i32 @phi_multiple_entry(i1 %arg, i32 %ptr) {
50 ; CHECK: %result = phi i32 [ %ptr, %entry ], [ %ptr, %entry ]
51
52
53 define i8* @select(i1 %cond, i8* %val1, i8* %val2) {
54 %r = select i1 %cond, i8* %val1, i8* %val2
55 ret i8* %r
56 }
57 ; CHECK: define i32 @select(i1 %cond, i32 %val1, i32 %val2) {
58 ; CHECK-NEXT: %r = select i1 %cond, i32 %val1, i32 %val2
59
60
61 define i32* @ptrtoint_same_size(i32* %ptr) {
62 %a = ptrtoint i32* %ptr to i32
63 %b = add i32 %a, 4
64 %c = inttoptr i32 %b to i32*
65 ret i32* %c
66 }
67 ; CHECK: define i32 @ptrtoint_same_size(i32 %ptr) {
68 ; CHECK-NEXT: %b = add i32 %ptr, 4
69 ; CHECK-NEXT: ret i32 %b
70
71
72 define i32* @ptrtoint_different_size(i32* %ptr) {
73 %a = ptrtoint i32* %ptr to i64
74 %b = add i64 %a, 4
75 %c = inttoptr i64 %b to i32*
76 ret i32* %c
77 }
78 ; CHECK: define i32 @ptrtoint_different_size(i32 %ptr) {
79 ; CHECK-NEXT: %a = zext i32 %ptr to i64
80 ; CHECK-NEXT: %b = add i64 %a, 4
81 ; CHECK-NEXT: %c = trunc i64 %b to i32
82 ; CHECK-NEXT: ret i32 %c
83
84
85 define i32* @pointer_bitcast(i64* %ptr) {
86 %cast = bitcast i64* %ptr to i32*
87 ret i32* %cast
88 }
89 ; CHECK: define i32 @pointer_bitcast(i32 %ptr) {
90 ; CHECK-NEXT: ret i32 %ptr
91
92 ; Same-type non-pointer bitcasts happen to be left alone by this pass.
93 define i32 @no_op_bitcast(i32 %val) {
94 %val2 = bitcast i32 %val to i32
95 ret i32 %val2
96 }
97 ; CHECK: define i32 @no_op_bitcast(i32 %val) {
98 ; CHECK-NEXT: %val2 = bitcast i32 %val to i32
99
100 define i64 @kept_bitcast(double %d) {
101 %i = bitcast double %d to i64
102 ret i64 %i
103 }
104 ; CHECK: define i64 @kept_bitcast(double %d) {
105 ; CHECK-NEXT: %i = bitcast double %d to i64
106
107
108 define i32 @constant_pointer_null() {
109 %val = ptrtoint i32* null to i32
110 ret i32 %val
111 }
112 ; CHECK: define i32 @constant_pointer_null() {
113 ; CHECK-NEXT: ret i32 0
114
115 define i32 @constant_pointer_undef() {
116 %val = ptrtoint i32* undef to i32
117 ret i32 %val
118 }
119 ; CHECK: define i32 @constant_pointer_undef() {
120 ; CHECK-NEXT: ret i32 undef
121
122 define i16* @constant_pointer_null_load() {
123 %val = load i16** null
124 ret i16* %val
125 }
126 ; CHECK: define i32 @constant_pointer_null_load() {
127 ; CHECK-NEXT: %.asptr = inttoptr i32 0 to i32*
128 ; CHECK-NEXT: %val = load i32* %.asptr
129
130
131 define i8 @load(i8* %ptr) {
132 %x = load i8* %ptr
133 ret i8 %x
134 }
135 ; CHECK: define i8 @load(i32 %ptr) {
136 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8*
137 ; CHECK-NEXT: %x = load i8* %ptr.asptr
138
139 define void @store(i8* %ptr, i8 %val) {
140 store i8 %val, i8* %ptr
141 ret void
142 }
143 ; CHECK: define void @store(i32 %ptr, i8 %val) {
144 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8*
145 ; CHECK-NEXT: store i8 %val, i8* %ptr.asptr
146
147
148 define i8* @load_ptr(i8** %ptr) {
149 %x = load i8** %ptr
150 ret i8* %x
151 }
152 ; CHECK: define i32 @load_ptr(i32 %ptr) {
153 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32*
154 ; CHECK-NEXT: %x = load i32* %ptr.asptr
155
156 define void @store_ptr(i8** %ptr, i8* %val) {
157 store i8* %val, i8** %ptr
158 ret void
159 }
160 ; CHECK: define void @store_ptr(i32 %ptr, i32 %val) {
161 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32*
162 ; CHECK-NEXT: store i32 %val, i32* %ptr.asptr
163
164
165 define i8 @load_attrs(i8* %ptr) {
166 %x = load atomic volatile i8* %ptr seq_cst, align 128
167 ret i8 %x
168 }
169 ; CHECK: define i8 @load_attrs(i32 %ptr) {
170 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8*
171 ; CHECK-NEXT: %x = load atomic volatile i8* %ptr.asptr seq_cst, align 128
172
173 define void @store_attrs(i8* %ptr, i8 %val) {
174 store atomic volatile i8 %val, i8* %ptr singlethread release, align 256
175 ret void
176 }
177 ; CHECK: define void @store_attrs(i32 %ptr, i8 %val) {
178 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8*
179 ; CHECK-NEXT: store atomic volatile i8 %val, i8* %ptr.asptr singlethread release , align 256
180
181
182 define i32 @cmpxchg(i32* %ptr, i32 %a, i32 %b) {
183 %r = cmpxchg i32* %ptr, i32 %a, i32 %b seq_cst
184 ret i32 %r
185 }
186 ; CHECK: define i32 @cmpxchg(i32 %ptr, i32 %a, i32 %b) {
187 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32*
188 ; CHECK-NEXT: %r = cmpxchg i32* %ptr.asptr, i32 %a, i32 %b seq_cst
189
190 define i32 @atomicrmw(i32* %ptr, i32 %x) {
191 %r = atomicrmw add i32* %ptr, i32 %x seq_cst
192 ret i32 %r
193 }
194 ; CHECK: define i32 @atomicrmw(i32 %ptr, i32 %x) {
195 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32*
196 ; CHECK-NEXT: %r = atomicrmw add i32* %ptr.asptr, i32 %x seq_cst
197
198
199 define i8* @indirect_call(i8* (i8*)* %func, i8* %arg) {
200 %result = call i8* %func(i8* %arg)
201 ret i8* %result
202 }
203 ; CHECK: define i32 @indirect_call(i32 %func, i32 %arg) {
204 ; CHECK-NEXT: %func.asfuncptr = inttoptr i32 %func to i32 (i32)*
205 ; CHECK-NEXT: %result = call i32 %func.asfuncptr(i32 %arg)
206 ; CHECK-NEXT: ret i32 %result
207
208
209 ; Test forwards reference
210 define i8* @direct_call1(i8* %arg) {
211 %result = call i8* @direct_call2(i8* %arg)
212 ret i8* %result
213 }
214 ; CHECK: define i32 @direct_call1(i32 %arg) {
215 ; CHECK-NEXT: %result = call i32 @direct_call2(i32 %arg)
216 ; CHECK-NEXT: ret i32 %result
217
218 ; Test backwards reference
219 define i8* @direct_call2(i8* %arg) {
220 %result = call i8* @direct_call1(i8* %arg)
221 ret i8* %result
222 }
223 ; CHECK: define i32 @direct_call2(i32 %arg) {
224 ; CHECK-NEXT: %result = call i32 @direct_call1(i32 %arg)
225 ; CHECK-NEXT: ret i32 %result
226
227
228 @var = global i32 0
229
230 define i32* @get_addr_of_global() {
231 ret i32* @var
232 }
233 ; CHECK: define i32 @get_addr_of_global() {
234 ; CHECK-NEXT: %expanded = ptrtoint i32* @var to i32
235 ; CHECK-NEXT: ret i32 %expanded
236
237 define %struct* (%struct*)* @get_addr_of_func() {
238 ret %struct* (%struct*)* @addr_taken_func
239 }
240 ; CHECK: define i32 @get_addr_of_func() {
241 ; CHECK-NEXT: %expanded = ptrtoint i32 (i32)* @addr_taken_func to i32
242 ; CEHCK-NEXT: ret i32 %expanded
243
244
245 define i32 @load_global() {
246 %val = load i32* @var
247 ret i32 %val
248 }
249 ; CHECK: define i32 @load_global() {
250 ; CHECK-NEXT: %val = load i32* @var
251 ; CHECK-NEXT: ret i32 %val
252
253 define i16 @load_global_bitcast() {
254 %ptr = bitcast i32* @var to i16*
255 %val = load i16* %ptr
256 ret i16 %val
257 }
258 ; CHECK: define i16 @load_global_bitcast() {
259 ; CHECK-NEXT: %var.bc = bitcast i32* @var to i16*
260 ; CHECK-NEXT: %val = load i16* %var.bc
261 ; CHECK-NEXT: ret i16 %val
262
263
264 %struct = type { i32, i32 }
265
266 declare void @receive_alloca(%struct* %ptr)
267
268 define void @alloca_fixed() {
269 %buf = alloca %struct, align 128
270 call void @receive_alloca(%struct* %buf)
271 ret void
272 }
273 ; CHECK: define void @alloca_fixed() {
274 ; CHECK-NEXT: %buf = alloca [8 x i8], align 128
275 ; CHECK-NEXT: %buf.asint = ptrtoint [8 x i8]* %buf to i32
276 ; CHECK-NEXT: call void @receive_alloca(i32 %buf.asint)
277
278 define void @alloca_variable(i32 %size) {
279 %buf = alloca %struct, i32 %size
280 call void @receive_alloca(%struct* %buf)
281 ret void
282 }
283 ; CHECK: define void @alloca_variable(i32 %size) {
284 ; CHECK-NEXT: %buf = alloca [8 x i8], i32 %size
285 ; CHECK-NEXT: %buf.asint = ptrtoint [8 x i8]* %buf to i32
286 ; CHECK-NEXT: call void @receive_alloca(i32 %buf.asint)
287
288
289 define i1 @compare(i8* %ptr1, i8* %ptr2) {
290 %cmp = icmp ult i8* %ptr1, %ptr2
291 ret i1 %cmp
292 }
293 ; CHECK: define i1 @compare(i32 %ptr1, i32 %ptr2) {
294 ; CHECK-NEXT: %cmp = icmp ult i32 %ptr1, %ptr2
295
296
297 declare i8* @llvm.some.intrinsic(i8* %ptr)
298
299 define i8* @preserve_intrinsic_type(i8* %ptr) {
300 %result = call i8* @llvm.some.intrinsic(i8* %ptr)
301 ret i8* %result
302 }
303 ; CHECK: define i32 @preserve_intrinsic_type(i32 %ptr) {
304 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8*
305 ; CHECK-NEXT: %result = call i8* @llvm.some.intrinsic(i8* %ptr.asptr)
306 ; CHECK-NEXT: %result.asint = ptrtoint i8* %result to i32
307 ; CHECK-NEXT: ret i32 %result.asint
308
309
310 define i16* @inline_asm1(i8* %ptr) {
311 %val = call i16* asm "foo", "=r,r"(i8* %ptr)
312 ret i16* %val
313 }
314
315 define i16** @inline_asm2(i8** %ptr) {
316 %val = call i16** asm "foo", "=r,r"(i8** %ptr)
317 ret i16** %val
318 }
319
320
321 declare void @llvm.dbg.declare(metadata, metadata)
322 declare void @llvm.dbg.value(metadata, i64, metadata)
323
324 define void @debug_declare(i32 %val) {
325 ; We normally expect llvm.dbg.declare to be used on an alloca.
326 %var = alloca i32
327 tail call void @llvm.dbg.declare(metadata !{i32* %var}, metadata !{})
328 tail call void @llvm.dbg.declare(metadata !{i32 %val}, metadata !{})
329 ret void
330 }
331 ; CHECK: define void @debug_declare(i32 %val) {
332 ; CHECK-NEXT: %var = alloca [4 x i8]
333 ; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{[4 x i8]* %var}, metadata ! 0)
334 ; This case is currently not converted.
335 ; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{null}, metadata !0)
336 ; CHECK-NEXT: ret void
337
338 ; For now, debugging info for values is lost. replaceAllUsesWith()
339 ; does not work for metadata references -- it converts them to nulls.
340 ; This makes dbg.value too tricky to handle for now.
341 define void @debug_value(i32 %val, i8* %ptr) {
342 tail call void @llvm.dbg.value(metadata !{i32 %val}, i64 1, metadata !{})
343 tail call void @llvm.dbg.value(metadata !{i8* %ptr}, i64 2, metadata !{})
344 ret void
345 }
346 ; CHECK: define void @debug_value(i32 %val, i32 %ptr) {
347 ; CHECK-NEXT: call void @llvm.dbg.value(metadata !{null}, i64 1, metadata !0)
348 ; CHECK-NEXT: call void @llvm.dbg.value(metadata !{null}, i64 2, metadata !0)
349 ; CHECK-NEXT: ret void
350
351
352 declare void @llvm.lifetime.start(i64 %size, i8* %ptr)
353
354 define void @alloca_lifetime() {
355 %buf = alloca i8
356 call void @llvm.lifetime.start(i64 1, i8* %buf)
357 ret void
358 }
359 ; For lifetime.start to have an effect, it must be given a bitcast of
360 ; the alloca (or the alloca itself). It doesn't work on
361 ; ptrtoint+inttoptr.
362 ; CHECK: define void @alloca_lifetime() {
363 ; CHECK-NEXT: %buf = alloca [1 x i8]
364 ; CHECK-NEXT: %buf.bc = bitcast [1 x i8]* %buf to i8*
365 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* %buf.bc)
366
367 define void @alloca_lifetime_via_bitcast() {
368 %buf = alloca i32
369 %buf_cast = bitcast i32* %buf to i8*
370 call void @llvm.lifetime.start(i64 1, i8* %buf_cast)
371 ret void
372 }
373 ; CHECK: define void @alloca_lifetime_via_bitcast() {
374 ; CHECK-NEXT: %buf = alloca [4 x i8]
375 ; CHECK-NEXT: %buf.bc = bitcast [4 x i8]* %buf to i8*
376 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* %buf.bc)
377
378
379 ; "nocapture" and "noalias" only apply to pointers, so must be stripped.
380 define void @nocapture_attr(i8* nocapture noalias %ptr) {
381 ret void
382 }
383 ; CHECK: define void @nocapture_attr(i32 %ptr) {
384
385 ; "nounwind" should be preserved.
386 define void @nounwind_func_attr() nounwind {
387 ret void
388 }
389 ; CHECK: define void @nounwind_func_attr() [[NOUNWIND:#[0-9]+]] {
390
391 define void @nounwind_call_attr() {
392 call void @nounwind_func_attr() nounwind
393 ret void
394 }
395 ; CHECK: define void @nounwind_call_attr() {
396 ; CHECK: call void @nounwind_func_attr() {{.*}}[[NOUNWIND]]
397
398 define fastcc void @fastcc_func() {
399 ret void
400 }
401 ; CHECK: define fastcc void @fastcc_func() {
402
403 define void @fastcc_call() {
404 call fastcc void @fastcc_func()
405 ret void
406 }
407 ; CHECK: define void @fastcc_call() {
408 ; CHECK-NEXT: call fastcc void @fastcc_func()
409
410
411 define i8* @getelementptr(i8* %ptr) {
eliben 2013/05/15 22:11:21 What is this for?
Mark Seaborn 2013/05/16 02:08:40 This just checks that the pass doesn't barf on get
412 %gep = getelementptr i8* %ptr, i32 10
413 ret i8* %gep
414 }
415
416 define i32* @va_arg(i8* %valist) {
eliben 2013/05/15 22:11:21 Ditto
Mark Seaborn 2013/05/16 02:08:40 Ditto.
417 %r = va_arg i8* %valist, i32*
418 ret i32* %r
419 }
420
421
422 define void @indirectbr(i8* %addr) {
423 indirectbr i8* %addr, [ label %l1, label %l2 ]
424 l1:
425 ret void
426 l2:
427 ret void
428 }
429 ; CHECK: define void @indirectbr(i32 %addr) {
430 ; CHECK-NEXT: %addr.asptr = inttoptr i32 %addr to i8*
431 ; CHECK-NEXT: indirectbr i8* %addr.asptr, [label %l1, label %l2]
432
433
434 define i8* @invoke(i8* %val) {
435 %result = invoke i8* @direct_call1(i8* %val)
436 to label %cont unwind label %lpad
437 cont:
438 ret i8* %result
439 lpad:
440 %lp = landingpad { i8*, i32 } personality void (i8*)* @personality_func cleanu p
441 %p = extractvalue { i8*, i32 } %lp, 0
442 %s = insertvalue { i8*, i32 } %lp, i8* %val, 0
443 ret i8* %p
444 }
445 ; CHECK: define i32 @invoke(i32 %val) {
446 ; CHECK-NEXT: %result = invoke i32 @direct_call1(i32 %val)
447 ; CHECK-NEXT: to label %cont unwind label %lpad
448 ; CHECK: %lp = landingpad { i8*, i32 } personality void (i8*)* bitcast (void (i3 2)* @personality_func to void (i8*)*)
449 ; CHECK: %p = extractvalue { i8*, i32 } %lp, 0
450 ; CHECK-NEXT: %p.asint = ptrtoint i8* %p to i32
451 ; CHECK-NEXT: %val.asptr = inttoptr i32 %val to i8*
452 ; CHECK-NEXT: %s = insertvalue { i8*, i32 } %lp, i8* %val.asptr, 0
453 ; CHECK-NEXT: ret i32 %p.asint
454
455 define void @personality_func(i8* %arg) {
456 ret void
457 }
458
459
460 declare i32 @llvm.eh.typeid.for(i8*)
461
462 @typeid = global i32 0
463
464 ; The argument here must be left as a bitcast, otherwise the backend
465 ; rejects it.
466 define void @typeid_for() {
467 %bc = bitcast i32* @typeid to i8*
468 call i32 @llvm.eh.typeid.for(i8* %bc)
469 ret void
470 }
471 ; CHECK: define void @typeid_for() {
472 ; CHECK-NEXT: %typeid.bc = bitcast i32* @typeid to i8*
473 ; CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* %typeid.bc)
474
475
476 ; CHECK: attributes {{.*}}[[NOUNWIND]] = { nounwind }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698