Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / Attributor / heap_to_stack.ll
blob4f267a7abe305eebf8b5f2453f7cd5c2cc50fb74
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:%.*]]) {
38 ; CHECK-NEXT:  entry:
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:%.*]]
42 ; CHECK:       t:
43 ; CHECK-NEXT:    br i1 false, label [[DEAD:%.*]], label [[F2:%.*]]
44 ; CHECK:       f:
45 ; CHECK-NEXT:    br label [[J:%.*]]
46 ; CHECK:       f2:
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]]
51 ; CHECK:       dead:
52 ; CHECK-NEXT:    unreachable
53 ; CHECK:       j:
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
58 entry:
59   %add = add i64 2, 2
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
67   br label %j
69 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
73   br label %j
75 dead:
76   br label %j
79   %phi = phi ptr [ %m, %f ], [ null, %f2 ], [ %A, %dead ]
80   tail call void @no_sync_func(ptr noundef %phi) nounwind
81   ret void
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:%.*]]) {
87 ; CHECK-NEXT:  bb:
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
92 bb:
93   tail call void @free(ptr %p2)
94   tail call void @nofree_func(ptr %p1)
95   ret void
98 ; TEST 1 - negative, pointer freed in another function.
100 define void @test1() {
101 ; CHECK-LABEL: define {{[^@]+}}@test1() {
102 ; CHECK-NEXT:  bb:
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)
114   ret void
117 ; TEST 2 - negative, call to a sync function.
119 define void @test2() {
120 ; CHECK-LABEL: define {{[^@]+}}@test2() {
121 ; CHECK-NEXT:  bb:
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)
131   ret void
134 ; TEST 3 - 1 malloc, 1 free
136 define void @test3() {
137 ; CHECK-LABEL: define {{[^@]+}}@test3() {
138 ; CHECK-NEXT:  bb:
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)
147   ret void
150 define void @test3a(ptr %p) {
151 ; CHECK-LABEL: define {{[^@]+}}@test3a
152 ; CHECK-SAME: (ptr nocapture [[P:%.*]]) {
153 ; CHECK-NEXT:  bb:
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)
162   ret void
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:%.*]]) {
170 ; CHECK-NEXT:  bb:
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)
179   ret void
182 ; leave alone non-constant alignments.
183 define void @test3c(i64 %alignment) {
184 ; CHECK-LABEL: define {{[^@]+}}@test3c
185 ; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) {
186 ; CHECK-NEXT:  bb:
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)
194   ret void
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:%.*]]) {
201 ; CHECK-NEXT:  bb:
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)
211   ret void
214 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1)
216 define void @test0() {
217 ; CHECK-LABEL: define {{[^@]+}}@test0() {
218 ; CHECK-NEXT:  bb:
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)
228   ret void
231 ; TEST 4
232 define void @test4() {
233 ; CHECK-LABEL: define {{[^@]+}}@test4() {
234 ; CHECK-NEXT:  bb:
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)
242   ret void
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:%.*]]) {
251 ; CHECK-NEXT:  bb:
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:%.*]]
255 ; CHECK:       bb2:
256 ; CHECK-NEXT:    tail call void @nofree_func(ptr noalias nocapture nofree [[I_H2S]])
257 ; CHECK-NEXT:    br label [[BB4:%.*]]
258 ; CHECK:       bb3:
259 ; CHECK-NEXT:    tail call void @nofree_arg_only(ptr noalias nocapture nofree [[I_H2S]], ptr nocapture [[P]])
260 ; CHECK-NEXT:    br label [[BB4]]
261 ; CHECK:       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
269 bb2:
270   tail call void @nofree_func(ptr %i)
271   br label %bb4
273 bb3:
274   tail call void @nofree_arg_only(ptr %i, ptr %p)
275   tail call void @free(ptr %i)
276   br label %bb4
278 bb4:
279   ret void
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:%.*]]) {
287 ; CHECK-NEXT:  bb:
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:%.*]]
291 ; CHECK:       bb2:
292 ; CHECK-NEXT:    tail call void @nofree_func(ptr noalias nocapture nofree [[I_H2S]])
293 ; CHECK-NEXT:    br label [[BB4:%.*]]
294 ; CHECK:       bb3:
295 ; CHECK-NEXT:    br label [[BB4]]
296 ; CHECK:       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
304 bb2:
305   tail call void @nofree_func(ptr %i)
306   tail call void @free(ptr %i)
307   br label %bb4
309 bb3:
310   tail call void @free(ptr %i)
311   br label %bb4
313 bb4:
314   ret void
317 ; TEST 7 - free is dead.
319 define void @test7() {
320 ; CHECK-LABEL: define {{[^@]+}}@test7() {
321 ; CHECK-NEXT:  bb:
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)
330   ret void
333 ; TEST 8 - Negative: bitcast pointer used in capture function
335 define void @test8() {
336 ; CHECK-LABEL: define {{[^@]+}}@test8() {
337 ; CHECK-NEXT:  bb:
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)
352   ret void
355 ; TEST 9 - FIXME: malloc should be converted.
356 define void @test9() {
357 ; CHECK-LABEL: define {{[^@]+}}@test9() {
358 ; CHECK-NEXT:  bb:
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)
373   ret void
376 ; TEST 10 - 1 malloc, 1 free
378 define i32 @test10() {
379 ; CHECK-LABEL: define {{[^@]+}}@test10() {
380 ; CHECK-NEXT:  bb:
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)
393   ret i32 %i2
396 define i32 @test_lifetime() {
397 ; CHECK-LABEL: define {{[^@]+}}@test_lifetime() {
398 ; CHECK-NEXT:  bb:
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)
413   ret i32 %i2
416 ; TEST 11
418 define void @test11() {
419 ; CHECK-LABEL: define {{[^@]+}}@test11() {
420 ; CHECK-NEXT:  bb:
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)
429   ret void
432 ; TEST 12
433 define i32 @irreducible_cfg(i32 %arg) {
434 ; CHECK-LABEL: define {{[^@]+}}@irreducible_cfg
435 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
436 ; CHECK-NEXT:  bb:
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:%.*]]
441 ; CHECK:       bb3:
442 ; CHECK-NEXT:    [[I4:%.*]] = add nsw i32 [[ARG]], 5
443 ; CHECK-NEXT:    br label [[BB11:%.*]]
444 ; CHECK:       bb5:
445 ; CHECK-NEXT:    br label [[BB6:%.*]]
446 ; CHECK:       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:%.*]]
453 ; CHECK:       bb10:
454 ; CHECK-NEXT:    br label [[BB11]]
455 ; CHECK:       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]]
459 ; CHECK:       bb13:
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
469 bb3:
470   %i4 = add nsw i32 %arg, 5
471   br label %bb11
473 bb5:
474   br label %bb6
476 bb6:
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
484 bb10:
485   br label %bb11
487 bb11:
488   %.1 = phi i32 [ %i4, %bb3 ], [ %.0, %bb10 ]
489   %i12 = add nsw i32 %.1, 1
490   br label %bb6
492 bb13:
493   %i14 = load i32, ptr %i, align 4
494   call void @free(ptr %i)
495   %i16 = load i32, ptr %i, align 4
496   ret i32 %i16
500 define i32 @malloc_in_loop(i32 %arg) {
501 ; CHECK-LABEL: define {{[^@]+}}@malloc_in_loop
502 ; CHECK-SAME: (i32 [[ARG:%.*]]) {
503 ; CHECK-NEXT:  bb:
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:%.*]]
509 ; CHECK:       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:%.*]]
515 ; CHECK:       bb6:
516 ; CHECK-NEXT:    [[I7_H2S:%.*]] = alloca i8, i64 4, align 1
517 ; CHECK-NEXT:    br label [[BB2]]
518 ; CHECK:       bb9:
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
525   br label %bb2
527 bb2:
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
534 bb6:
535   %i7 = call noalias ptr @malloc(i64 4)
536   store i32 1, ptr %i7, align 8
537   br label %bb2
539 bb9:
540   ret i32 5
543 ; Malloc/Calloc too large
544 define i32 @test13() {
545 ; CHECK-LABEL: define {{[^@]+}}@test13() {
546 ; CHECK-NEXT:  bb:
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)
560   ret i32 %i2
563 define i32 @test_sle() {
564 ; CHECK-LABEL: define {{[^@]+}}@test_sle() {
565 ; CHECK-NEXT:  bb:
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)
579   ret i32 %i2
582 define i32 @test_overflow() {
583 ; CHECK-LABEL: define {{[^@]+}}@test_overflow() {
584 ; CHECK-NEXT:  bb:
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)
598   ret i32 %i2
601 define void @test14() {
602 ; CHECK-LABEL: define {{[^@]+}}@test14() {
603 ; CHECK-NEXT:  bb:
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)
613   ret void
616 define void @test15(i64 %S) {
617 ; CHECK-LABEL: define {{[^@]+}}@test15
618 ; CHECK-SAME: (i64 [[S:%.*]]) {
619 ; CHECK-NEXT:  bb:
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)
629   ret void
632 define void @test16a(i8 %v, ptr %P) {
633 ; CHECK-LABEL: define {{[^@]+}}@test16a
634 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree readnone [[P:%.*]]) {
635 ; CHECK-NEXT:  bb:
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)
646   ret void
649 define void @test16b(i8 %v, ptr %P) {
650 ; CHECK-LABEL: define {{[^@]+}}@test16b
651 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) {
652 ; CHECK-NEXT:  bb:
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)
664   ret void
667 define void @test16c(i8 %v, ptr %P) {
668 ; CHECK-LABEL: define {{[^@]+}}@test16c
669 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) {
670 ; CHECK-NEXT:  bb:
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)
681   ret void
684 define void @test16d(i8 %v, ptr %P) {
685 ; CHECK-LABEL: define {{[^@]+}}@test16d
686 ; CHECK-SAME: (i8 [[V:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) {
687 ; CHECK-NEXT:  bb:
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
695   ret void
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]+]] {
703 ; CHECK-NEXT:  bb:
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)
715   ret void
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:
734 ; CGSCC: {{.*}}
735 ; TUNIT: {{.*}}