1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0)
7 declare void @nocapture_func_frees_pointer(ptr nocapture)
9 declare void @func_throws(...)
11 declare void @sync_func(ptr %p)
13 declare void @sync_will_return(ptr %p) willreturn nounwind
15 declare void @no_sync_func(ptr nocapture %p) nofree nosync willreturn
17 declare void @nofree_func(ptr nocapture %p) nofree nosync willreturn
19 declare void @foo(ptr %p)
21 declare void @foo_nounw(ptr %p) nounwind nofree
23 declare void @usei8(i8)
24 declare void @usei8p(ptr nocapture)
26 declare i32 @no_return_call() noreturn
28 declare void @free(ptr nocapture) allockind("free")
30 declare void @llvm.lifetime.start.p0(i64, ptr nocapture) nounwind
33 ; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = internal global ptr undef, align 4
35 define void @h2s_value_simplify_interaction(i1 %c, ptr %A) {
36 ; CHECK-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction
37 ; CHECK-SAME: (i1 [[C:%.*]], ptr nocapture nofree readnone [[A:%.*]]) {
39 ; CHECK-NEXT: [[ADD:%.*]] = add i64 2, 2
40 ; CHECK-NEXT: [[M:%.*]] = tail call noalias align 16 ptr @malloc(i64 noundef [[ADD]])
41 ; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
43 ; CHECK-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]]
45 ; CHECK-NEXT: br label [[J:%.*]]
47 ; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[M]], align 16
48 ; CHECK-NEXT: call void @usei8(i8 [[L]])
49 ; CHECK-NEXT: call void @no_sync_func(ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1) [[M]]) #[[ATTR11:[0-9]+]]
50 ; CHECK-NEXT: br label [[J]]
52 ; CHECK-NEXT: unreachable
54 ; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[M]], [[F]] ], [ null, [[F2]] ]
55 ; CHECK-NEXT: tail call void @no_sync_func(ptr nocapture nofree noundef align 16 [[PHI]]) #[[ATTR11]]
56 ; CHECK-NEXT: ret void
60 %m = tail call noalias align 16 ptr @malloc(i64 %add)
61 br i1 %c, label %t, label %f
64 br i1 false, label %dead, label %f2
70 %l = load i8, ptr %m, align 1
71 call void @usei8(i8 %l)
72 call void @no_sync_func(ptr noundef %m) nounwind
79 %phi = phi ptr [ %m, %f ], [ null, %f2 ], [ %A, %dead ]
80 tail call void @no_sync_func(ptr noundef %phi) nounwind
84 define void @nofree_arg_only(ptr %p1, ptr %p2) {
85 ; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only
86 ; CHECK-SAME: (ptr nocapture nofree [[P1:%.*]], ptr nocapture [[P2:%.*]]) {
88 ; CHECK-NEXT: tail call void @free(ptr nocapture [[P2]])
89 ; CHECK-NEXT: tail call void @nofree_func(ptr nocapture nofree [[P1]])
90 ; CHECK-NEXT: ret void
93 tail call void @free(ptr %p2)
94 tail call void @nofree_func(ptr %p1)
98 ; TEST 1 - negative, pointer freed in another function.
100 define void @test1() {
101 ; CHECK-LABEL: define {{[^@]+}}@test1() {
103 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
104 ; CHECK-NEXT: tail call void @nocapture_func_frees_pointer(ptr noalias nocapture [[I]])
105 ; CHECK-NEXT: tail call void (...) @func_throws()
106 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture [[I]])
107 ; CHECK-NEXT: ret void
110 %i = tail call noalias ptr @malloc(i64 4)
111 tail call void @nocapture_func_frees_pointer(ptr %i)
112 tail call void (...) @func_throws()
113 tail call void @free(ptr %i)
117 ; TEST 2 - negative, call to a sync function.
119 define void @test2() {
120 ; CHECK-LABEL: define {{[^@]+}}@test2() {
122 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
123 ; CHECK-NEXT: tail call void @sync_func(ptr [[I]])
124 ; CHECK-NEXT: tail call void @free(ptr nocapture [[I]])
125 ; CHECK-NEXT: ret void
128 %i = tail call noalias ptr @malloc(i64 4)
129 tail call void @sync_func(ptr %i)
130 tail call void @free(ptr %i)
134 ; TEST 3 - 1 malloc, 1 free
136 define void @test3() {
137 ; CHECK-LABEL: define {{[^@]+}}@test3() {
139 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
140 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I_H2S]])
141 ; CHECK-NEXT: ret void
144 %i = tail call noalias ptr @malloc(i64 4)
145 tail call void @no_sync_func(ptr %i)
146 tail call void @free(ptr %i)
150 define void @test3a(ptr %p) {
151 ; CHECK-LABEL: define {{[^@]+}}@test3a
152 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) {
154 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
155 ; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nocapture nofree [[I_H2S]], ptr nocapture [[P]])
156 ; CHECK-NEXT: ret void
159 %i = tail call noalias ptr @malloc(i64 4)
160 tail call void @nofree_arg_only(ptr %i, ptr %p)
161 tail call void @free(ptr %i)
165 declare noalias ptr @aligned_alloc(i64 allocalign, i64) allockind("alloc,uninitialized,aligned") allocsize(1)
167 define void @test3b(ptr %p) {
168 ; CHECK-LABEL: define {{[^@]+}}@test3b
169 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) {
171 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 128, align 32
172 ; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nocapture nofree [[I_H2S]], ptr nocapture [[P]])
173 ; CHECK-NEXT: ret void
176 %i = tail call noalias ptr @aligned_alloc(i64 32, i64 128)
177 tail call void @nofree_arg_only(ptr %i, ptr %p)
178 tail call void @free(ptr %i)
182 ; leave alone non-constant alignments.
183 define void @test3c(i64 %alignment) {
184 ; CHECK-LABEL: define {{[^@]+}}@test3c
185 ; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) {
187 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @aligned_alloc(i64 [[ALIGNMENT]], i64 noundef 128)
188 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture [[I]])
189 ; CHECK-NEXT: ret void
192 %i = tail call noalias ptr @aligned_alloc(i64 %alignment, i64 128)
193 tail call void @free(ptr %i)
197 ; leave alone a constant-but-invalid alignment
198 define void @test3d(ptr %p) {
199 ; CHECK-LABEL: define {{[^@]+}}@test3d
200 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) {
202 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @aligned_alloc(i64 noundef 33, i64 noundef 128)
203 ; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nocapture nofree [[I]], ptr nocapture [[P]])
204 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture [[I]])
205 ; CHECK-NEXT: ret void
208 %i = tail call noalias ptr @aligned_alloc(i64 33, i64 128)
209 tail call void @nofree_arg_only(ptr %i, ptr %p)
210 tail call void @free(ptr %i)
214 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1)
216 define void @test0() {
217 ; CHECK-LABEL: define {{[^@]+}}@test0() {
219 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 8, align 1
220 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[I_H2S]], i8 0, i64 8, i1 false)
221 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I_H2S]])
222 ; CHECK-NEXT: ret void
225 %i = tail call noalias ptr @calloc(i64 2, i64 4)
226 tail call void @no_sync_func(ptr %i)
227 tail call void @free(ptr %i)
232 define void @test4() {
233 ; CHECK-LABEL: define {{[^@]+}}@test4() {
235 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
236 ; CHECK-NEXT: tail call void @nofree_func(ptr noalias nocapture nofree [[I_H2S]])
237 ; CHECK-NEXT: ret void
240 %i = tail call noalias ptr @malloc(i64 4)
241 tail call void @nofree_func(ptr %i)
245 ; TEST 5 - not all exit paths have a call to free, but all uses of malloc
246 ; are in nofree functions and are not captured
248 define void @test5(i32 %arg, ptr %p) {
249 ; CHECK-LABEL: define {{[^@]+}}@test5
250 ; CHECK-SAME: (i32 [[ARG:%.*]], ptr nocapture [[P:%.*]]) {
252 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
253 ; CHECK-NEXT: [[I1:%.*]] = icmp eq i32 [[ARG]], 0
254 ; CHECK-NEXT: br i1 [[I1]], label [[BB3:%.*]], label [[BB2:%.*]]
256 ; CHECK-NEXT: tail call void @nofree_func(ptr noalias nocapture nofree [[I_H2S]])
257 ; CHECK-NEXT: br label [[BB4:%.*]]
259 ; CHECK-NEXT: tail call void @nofree_arg_only(ptr noalias nocapture nofree [[I_H2S]], ptr nocapture [[P]])
260 ; CHECK-NEXT: br label [[BB4]]
262 ; CHECK-NEXT: ret void
265 %i = tail call noalias ptr @malloc(i64 4)
266 %i1 = icmp eq i32 %arg, 0
267 br i1 %i1, label %bb3, label %bb2
270 tail call void @nofree_func(ptr %i)
274 tail call void @nofree_arg_only(ptr %i, ptr %p)
275 tail call void @free(ptr %i)
282 ; TEST 6 - all exit paths have a call to free
284 define void @test6(i32 %arg) {
285 ; CHECK-LABEL: define {{[^@]+}}@test6
286 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
288 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
289 ; CHECK-NEXT: [[I1:%.*]] = icmp eq i32 [[ARG]], 0
290 ; CHECK-NEXT: br i1 [[I1]], label [[BB3:%.*]], label [[BB2:%.*]]
292 ; CHECK-NEXT: tail call void @nofree_func(ptr noalias nocapture nofree [[I_H2S]])
293 ; CHECK-NEXT: br label [[BB4:%.*]]
295 ; CHECK-NEXT: br label [[BB4]]
297 ; CHECK-NEXT: ret void
300 %i = tail call noalias ptr @malloc(i64 4)
301 %i1 = icmp eq i32 %arg, 0
302 br i1 %i1, label %bb3, label %bb2
305 tail call void @nofree_func(ptr %i)
306 tail call void @free(ptr %i)
310 tail call void @free(ptr %i)
317 ; TEST 7 - free is dead.
319 define void @test7() {
320 ; CHECK-LABEL: define {{[^@]+}}@test7() {
322 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
323 ; CHECK-NEXT: [[I1:%.*]] = tail call i32 @no_return_call() #[[ATTR4:[0-9]+]]
324 ; CHECK-NEXT: unreachable
327 %i = tail call noalias ptr @malloc(i64 4)
328 %i1 = tail call i32 @no_return_call()
329 tail call void @free(ptr %i)
333 ; TEST 8 - Negative: bitcast pointer used in capture function
335 define void @test8() {
336 ; CHECK-LABEL: define {{[^@]+}}@test8() {
338 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
339 ; CHECK-NEXT: tail call void @no_sync_func(ptr nocapture nofree [[I]])
340 ; CHECK-NEXT: store i32 10, ptr [[I]], align 4
341 ; CHECK-NEXT: tail call void @foo(ptr nonnull align 4 dereferenceable(4) [[I]])
342 ; CHECK-NEXT: tail call void @free(ptr nocapture nonnull align 4 dereferenceable(4) [[I]])
343 ; CHECK-NEXT: ret void
346 %i = tail call noalias ptr @malloc(i64 4)
347 tail call void @no_sync_func(ptr %i)
348 store i32 10, ptr %i, align 4
349 %i2 = load i32, ptr %i, align 4
350 tail call void @foo(ptr %i)
351 tail call void @free(ptr %i)
355 ; TEST 9 - FIXME: malloc should be converted.
356 define void @test9() {
357 ; CHECK-LABEL: define {{[^@]+}}@test9() {
359 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
360 ; CHECK-NEXT: tail call void @no_sync_func(ptr nocapture nofree [[I]])
361 ; CHECK-NEXT: store i32 10, ptr [[I]], align 4
362 ; CHECK-NEXT: tail call void @foo_nounw(ptr nofree nonnull align 4 dereferenceable(4) [[I]]) #[[ATTR11]]
363 ; CHECK-NEXT: tail call void @free(ptr nocapture nonnull align 4 dereferenceable(4) [[I]])
364 ; CHECK-NEXT: ret void
367 %i = tail call noalias ptr @malloc(i64 4)
368 tail call void @no_sync_func(ptr %i)
369 store i32 10, ptr %i, align 4
370 %i2 = load i32, ptr %i, align 4
371 tail call void @foo_nounw(ptr %i)
372 tail call void @free(ptr %i)
376 ; TEST 10 - 1 malloc, 1 free
378 define i32 @test10() {
379 ; CHECK-LABEL: define {{[^@]+}}@test10() {
381 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
382 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I_H2S]])
383 ; CHECK-NEXT: store i32 10, ptr [[I_H2S]], align 4
384 ; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I_H2S]], align 4
385 ; CHECK-NEXT: ret i32 [[I2]]
388 %i = tail call noalias ptr @malloc(i64 4)
389 tail call void @no_sync_func(ptr %i)
390 store i32 10, ptr %i, align 4
391 %i2 = load i32, ptr %i, align 4
392 tail call void @free(ptr %i)
396 define i32 @test_lifetime() {
397 ; CHECK-LABEL: define {{[^@]+}}@test_lifetime() {
399 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
400 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I_H2S]])
401 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree nonnull align 4 dereferenceable(4) [[I_H2S]])
402 ; CHECK-NEXT: store i32 10, ptr [[I_H2S]], align 4
403 ; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I_H2S]], align 4
404 ; CHECK-NEXT: ret i32 [[I2]]
407 %i = tail call noalias ptr @malloc(i64 4)
408 tail call void @no_sync_func(ptr %i)
409 call void @llvm.lifetime.start.p0(i64 4, ptr %i)
410 store i32 10, ptr %i, align 4
411 %i2 = load i32, ptr %i, align 4
412 tail call void @free(ptr %i)
418 define void @test11() {
419 ; CHECK-LABEL: define {{[^@]+}}@test11() {
421 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
422 ; CHECK-NEXT: tail call void @sync_will_return(ptr [[I_H2S]]) #[[ATTR11]]
423 ; CHECK-NEXT: ret void
426 %i = tail call noalias ptr @malloc(i64 4)
427 tail call void @sync_will_return(ptr %i)
428 tail call void @free(ptr %i)
433 define i32 @irreducible_cfg(i32 %arg) {
434 ; CHECK-LABEL: define {{[^@]+}}@irreducible_cfg
435 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
437 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
438 ; CHECK-NEXT: store i32 10, ptr [[I_H2S]], align 4
439 ; CHECK-NEXT: [[I2:%.*]] = icmp eq i32 [[ARG]], 1
440 ; CHECK-NEXT: br i1 [[I2]], label [[BB3:%.*]], label [[BB5:%.*]]
442 ; CHECK-NEXT: [[I4:%.*]] = add nsw i32 [[ARG]], 5
443 ; CHECK-NEXT: br label [[BB11:%.*]]
445 ; CHECK-NEXT: br label [[BB6:%.*]]
447 ; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[I12:%.*]], [[BB11]] ], [ 1, [[BB5]] ]
448 ; CHECK-NEXT: [[I7:%.*]] = load i32, ptr [[I_H2S]], align 4
449 ; CHECK-NEXT: [[I8:%.*]] = add nsw i32 [[I7]], -1
450 ; CHECK-NEXT: store i32 [[I8]], ptr [[I_H2S]], align 4
451 ; CHECK-NEXT: [[I9:%.*]] = icmp ne i32 [[I7]], 0
452 ; CHECK-NEXT: br i1 [[I9]], label [[BB10:%.*]], label [[BB13:%.*]]
454 ; CHECK-NEXT: br label [[BB11]]
456 ; CHECK-NEXT: [[DOT1:%.*]] = phi i32 [ [[I4]], [[BB3]] ], [ [[DOT0]], [[BB10]] ]
457 ; CHECK-NEXT: [[I12]] = add nsw i32 [[DOT1]], 1
458 ; CHECK-NEXT: br label [[BB6]]
460 ; CHECK-NEXT: [[I16:%.*]] = load i32, ptr [[I_H2S]], align 4
461 ; CHECK-NEXT: ret i32 [[I16]]
464 %i = call noalias ptr @malloc(i64 4)
465 store i32 10, ptr %i, align 4
466 %i2 = icmp eq i32 %arg, 1
467 br i1 %i2, label %bb3, label %bb5
470 %i4 = add nsw i32 %arg, 5
477 %.0 = phi i32 [ %i12, %bb11 ], [ 1, %bb5 ]
478 %i7 = load i32, ptr %i, align 4
479 %i8 = add nsw i32 %i7, -1
480 store i32 %i8, ptr %i, align 4
481 %i9 = icmp ne i32 %i7, 0
482 br i1 %i9, label %bb10, label %bb13
488 %.1 = phi i32 [ %i4, %bb3 ], [ %.0, %bb10 ]
489 %i12 = add nsw i32 %.1, 1
493 %i14 = load i32, ptr %i, align 4
494 call void @free(ptr %i)
495 %i16 = load i32, ptr %i, align 4
500 define i32 @malloc_in_loop(i32 %arg) {
501 ; CHECK-LABEL: define {{[^@]+}}@malloc_in_loop
502 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
504 ; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
505 ; CHECK-NEXT: [[I1:%.*]] = alloca ptr, align 8
506 ; CHECK-NEXT: [[I11:%.*]] = alloca i8, i32 0, align 8
507 ; CHECK-NEXT: store i32 [[ARG]], ptr [[I]], align 4
508 ; CHECK-NEXT: br label [[BB2:%.*]]
510 ; CHECK-NEXT: [[I3:%.*]] = load i32, ptr [[I]], align 4
511 ; CHECK-NEXT: [[I4:%.*]] = add nsw i32 [[I3]], -1
512 ; CHECK-NEXT: store i32 [[I4]], ptr [[I]], align 4
513 ; CHECK-NEXT: [[I5:%.*]] = icmp sgt i32 [[I4]], 0
514 ; CHECK-NEXT: br i1 [[I5]], label [[BB6:%.*]], label [[BB9:%.*]]
516 ; CHECK-NEXT: [[I7_H2S:%.*]] = alloca i8, i64 4, align 1
517 ; CHECK-NEXT: br label [[BB2]]
519 ; CHECK-NEXT: ret i32 5
522 %i = alloca i32, align 4
523 %i1 = alloca ptr, align 8
524 store i32 %arg, ptr %i, align 4
528 %i3 = load i32, ptr %i, align 4
529 %i4 = add nsw i32 %i3, -1
530 store i32 %i4, ptr %i, align 4
531 %i5 = icmp sgt i32 %i4, 0
532 br i1 %i5, label %bb6, label %bb9
535 %i7 = call noalias ptr @malloc(i64 4)
536 store i32 1, ptr %i7, align 8
543 ; Malloc/Calloc too large
544 define i32 @test13() {
545 ; CHECK-LABEL: define {{[^@]+}}@test13() {
547 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 256)
548 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I]])
549 ; CHECK-NEXT: store i32 10, ptr [[I]], align 4
550 ; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I]], align 4
551 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture nonnull align 4 dereferenceable(4) [[I]])
552 ; CHECK-NEXT: ret i32 [[I2]]
555 %i = tail call noalias ptr @malloc(i64 256)
556 tail call void @no_sync_func(ptr %i)
557 store i32 10, ptr %i, align 4
558 %i2 = load i32, ptr %i, align 4
559 tail call void @free(ptr %i)
563 define i32 @test_sle() {
564 ; CHECK-LABEL: define {{[^@]+}}@test_sle() {
566 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef -1)
567 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I]])
568 ; CHECK-NEXT: store i32 10, ptr [[I]], align 4
569 ; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I]], align 4
570 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture nonnull align 4 dereferenceable(4) [[I]])
571 ; CHECK-NEXT: ret i32 [[I2]]
574 %i = tail call noalias ptr @malloc(i64 -1)
575 tail call void @no_sync_func(ptr %i)
576 store i32 10, ptr %i, align 4
577 %i2 = load i32, ptr %i, align 4
578 tail call void @free(ptr %i)
582 define i32 @test_overflow() {
583 ; CHECK-LABEL: define {{[^@]+}}@test_overflow() {
585 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @calloc(i64 noundef 65537, i64 noundef 65537)
586 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I]])
587 ; CHECK-NEXT: store i32 10, ptr [[I]], align 4
588 ; CHECK-NEXT: [[I2:%.*]] = load i32, ptr [[I]], align 4
589 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture nonnull align 4 dereferenceable(4) [[I]])
590 ; CHECK-NEXT: ret i32 [[I2]]
593 %i = tail call noalias ptr @calloc(i64 65537, i64 65537)
594 tail call void @no_sync_func(ptr %i)
595 store i32 10, ptr %i, align 4
596 %i2 = load i32, ptr %i, align 4
597 tail call void @free(ptr %i)
601 define void @test14() {
602 ; CHECK-LABEL: define {{[^@]+}}@test14() {
604 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @calloc(i64 noundef 64, i64 noundef 4)
605 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I]])
606 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture [[I]])
607 ; CHECK-NEXT: ret void
610 %i = tail call noalias ptr @calloc(i64 64, i64 4)
611 tail call void @no_sync_func(ptr %i)
612 tail call void @free(ptr %i)
616 define void @test15(i64 %S) {
617 ; CHECK-LABEL: define {{[^@]+}}@test15
618 ; CHECK-SAME: (i64 [[S:%.*]]) {
620 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 [[S]])
621 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree [[I]])
622 ; CHECK-NEXT: tail call void @free(ptr noalias nocapture [[I]])
623 ; CHECK-NEXT: ret void
626 %i = tail call noalias ptr @malloc(i64 %S)
627 tail call void @no_sync_func(ptr %i)
628 tail call void @free(ptr %i)
632 define void @test16a(i8 %v, ptr %P) {
633 ; CHECK-LABEL: define {{[^@]+}}@test16a
634 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree readnone [[P:%.*]]) {
636 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
637 ; CHECK-NEXT: store i8 [[V]], ptr [[I_H2S]], align 1
638 ; CHECK-NEXT: tail call void @no_sync_func(ptr noalias nocapture nofree noundef nonnull dereferenceable(1) [[I_H2S]])
639 ; CHECK-NEXT: ret void
642 %i = tail call noalias ptr @malloc(i64 4)
643 store i8 %v, ptr %i, align 1
644 tail call void @no_sync_func(ptr %i)
645 tail call void @free(ptr nonnull dereferenceable(1) %i)
649 define void @test16b(i8 %v, ptr %P) {
650 ; CHECK-LABEL: define {{[^@]+}}@test16b
651 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) {
653 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
654 ; CHECK-NEXT: store ptr [[I]], ptr [[P]], align 8
655 ; CHECK-NEXT: tail call void @no_sync_func(ptr nocapture nofree [[I]])
656 ; CHECK-NEXT: tail call void @free(ptr nocapture [[I]])
657 ; CHECK-NEXT: ret void
660 %i = tail call noalias ptr @malloc(i64 4)
661 store ptr %i, ptr %P, align 8
662 tail call void @no_sync_func(ptr %i)
663 tail call void @free(ptr %i)
667 define void @test16c(i8 %v, ptr %P) {
668 ; CHECK-LABEL: define {{[^@]+}}@test16c
669 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) {
671 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
672 ; CHECK-NEXT: store ptr [[I_H2S]], ptr [[P]], align 8
673 ; CHECK-NEXT: tail call void @no_sync_func(ptr nocapture nofree [[I_H2S]]) #[[ATTR11]]
674 ; CHECK-NEXT: ret void
677 %i = tail call noalias ptr @malloc(i64 4)
678 store ptr %i, ptr %P, align 8
679 tail call void @no_sync_func(ptr %i) nounwind
680 tail call void @free(ptr %i)
684 define void @test16d(i8 %v, ptr %P) {
685 ; CHECK-LABEL: define {{[^@]+}}@test16d
686 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) {
688 ; CHECK-NEXT: [[I:%.*]] = tail call noalias ptr @malloc(i64 noundef 4)
689 ; CHECK-NEXT: store ptr [[I]], ptr [[P]], align 8
690 ; CHECK-NEXT: ret void
693 %i = tail call noalias ptr @malloc(i64 4)
694 store ptr %i, ptr %P, align 8
698 @G = internal global ptr undef, align 4
699 define void @test16e(i8 %v) norecurse {
700 ; CHECK: Function Attrs: norecurse
701 ; CHECK-LABEL: define {{[^@]+}}@test16e
702 ; CHECK-SAME: (i8 [[V:%.*]]) #[[ATTR9:[0-9]+]] {
704 ; CHECK-NEXT: [[I_H2S:%.*]] = alloca i8, i64 4, align 1
705 ; CHECK-NEXT: store ptr [[I_H2S]], ptr @G, align 8
706 ; CHECK-NEXT: call void @usei8p(ptr nocapture nofree [[I_H2S]]) #[[ATTR12:[0-9]+]]
707 ; CHECK-NEXT: ret void
710 %i = tail call noalias ptr @malloc(i64 4)
711 store ptr %i, ptr @G, align 8
712 %i1 = load ptr, ptr @G, align 8
713 call void @usei8p(ptr nocapture nofree %i1) nocallback nosync nounwind willreturn
714 call void @free(ptr %i)
719 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) }
720 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind willreturn }
721 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nosync willreturn }
722 ; CHECK: attributes #[[ATTR3:[0-9]+]] = { nofree nounwind }
723 ; CHECK: attributes #[[ATTR4]] = { noreturn }
724 ; CHECK: attributes #[[ATTR5:[0-9]+]] = { allockind("free") }
725 ; CHECK: attributes #[[ATTR6:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
726 ; CHECK: attributes #[[ATTR7:[0-9]+]] = { allockind("alloc,uninitialized,aligned") allocsize(1) }
727 ; CHECK: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) }
728 ; CHECK: attributes #[[ATTR9]] = { norecurse }
729 ; CHECK: attributes #[[ATTR10:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
730 ; CHECK: attributes #[[ATTR11]] = { nounwind }
731 ; CHECK: attributes #[[ATTR12]] = { nocallback nosync nounwind willreturn }
733 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: