[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / Attributor / heap_to_stack_gpu.ll
blob52e01dd525f06215e9b5cf5c61a22b81e7adb029
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4 ; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
7 target triple = "amdgcn-amd-amdhsa"
9 declare noalias i8* @malloc(i64)
11 declare void @nocapture_func_frees_pointer(i8* nocapture)
13 declare void @func_throws(...)
15 declare void @sync_func(i8* %p)
17 declare void @sync_will_return(i8* %p) willreturn nounwind
19 declare void @no_sync_func(i8* nocapture %p) nofree nosync willreturn
21 declare void @nofree_func(i8* nocapture %p) nofree  nosync willreturn
23 declare void @foo(i32* %p)
25 declare void @foo_nounw(i32* %p) nounwind nofree
27 declare i32 @no_return_call() noreturn
29 declare void @free(i8* nocapture)
31 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
33 define void @nofree_arg_only(i8* %p1, i8* %p2) {
34 ; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only
35 ; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture [[P2:%.*]]) {
36 ; CHECK-NEXT:    tail call void @free(i8* nocapture [[P2]])
37 ; CHECK-NEXT:    tail call void @nofree_func(i8* nocapture nofree [[P1]])
38 ; CHECK-NEXT:    ret void
40   tail call void @free(i8* %p2)
41   tail call void @nofree_func(i8* %p1)
42   ret void
45 ; TEST 1 - negative, pointer freed in another function.
47 define void @test1() {
48 ; CHECK-LABEL: define {{[^@]+}}@test1() {
49 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
50 ; CHECK-NEXT:    tail call void @nocapture_func_frees_pointer(i8* noalias nocapture [[TMP1]])
51 ; CHECK-NEXT:    tail call void (...) @func_throws()
52 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
53 ; CHECK-NEXT:    ret void
55   %1 = tail call noalias i8* @malloc(i64 4)
56   tail call void @nocapture_func_frees_pointer(i8* %1)
57   tail call void (...) @func_throws()
58   tail call void @free(i8* %1)
59   ret void
62 ; TEST 2 - negative, call to a sync function.
64 define void @test2() {
65 ; CHECK-LABEL: define {{[^@]+}}@test2() {
66 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
67 ; CHECK-NEXT:    tail call void @sync_func(i8* [[TMP1]])
68 ; CHECK-NEXT:    tail call void @free(i8* nocapture [[TMP1]])
69 ; CHECK-NEXT:    ret void
71   %1 = tail call noalias i8* @malloc(i64 4)
72   tail call void @sync_func(i8* %1)
73   tail call void @free(i8* %1)
74   ret void
77 ; TEST 3 - 1 malloc, 1 free
79 define void @test3() {
80 ; CHECK-LABEL: define {{[^@]+}}@test3() {
81 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
82 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
83 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
84 ; CHECK-NEXT:    ret void
86   %1 = tail call noalias i8* @malloc(i64 4)
87   tail call void @no_sync_func(i8* %1)
88   tail call void @free(i8* %1)
89   ret void
92 define void @test3a(i8* %p) {
93 ; IS________OPM-LABEL: define {{[^@]+}}@test3a
94 ; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) {
95 ; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
96 ; IS________OPM-NEXT:    tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]])
97 ; IS________OPM-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
98 ; IS________OPM-NEXT:    ret void
100 ; IS________NPM-LABEL: define {{[^@]+}}@test3a
101 ; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) {
102 ; IS________NPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
103 ; IS________NPM-NEXT:    tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]])
104 ; IS________NPM-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
105 ; IS________NPM-NEXT:    ret void
107   %1 = tail call noalias i8* @malloc(i64 4)
108   tail call void @nofree_arg_only(i8* %1, i8* %p)
109   tail call void @free(i8* %1)
110   ret void
113 declare noalias i8* @aligned_alloc(i64, i64)
115 define void @test3b(i8* %p) {
116 ; IS________OPM-LABEL: define {{[^@]+}}@test3b
117 ; IS________OPM-SAME: (i8* nocapture [[P:%.*]]) {
118 ; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 32, i64 noundef 128)
119 ; IS________OPM-NEXT:    tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]])
120 ; IS________OPM-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
121 ; IS________OPM-NEXT:    ret void
123 ; IS________NPM-LABEL: define {{[^@]+}}@test3b
124 ; IS________NPM-SAME: (i8* nocapture [[P:%.*]]) {
125 ; IS________NPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 noundef 32, i64 noundef 128)
126 ; IS________NPM-NEXT:    tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]])
127 ; IS________NPM-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
128 ; IS________NPM-NEXT:    ret void
130   %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128)
131   tail call void @nofree_arg_only(i8* %1, i8* %p)
132   tail call void @free(i8* %1)
133   ret void
136 ; leave alone non-constant alignments.
137 define void @test3c(i64 %alignment) {
138 ; CHECK-LABEL: define {{[^@]+}}@test3c
139 ; CHECK-SAME: (i64 [[ALIGNMENT:%.*]]) {
140 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 [[ALIGNMENT]], i64 noundef 128)
141 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
142 ; CHECK-NEXT:    ret void
144   %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128)
145   tail call void @free(i8* %1)
146   ret void
149 declare noalias i8* @calloc(i64, i64)
151 define void @test0() {
152 ; CHECK-LABEL: define {{[^@]+}}@test0() {
153 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 2, i64 noundef 4)
154 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
155 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
156 ; CHECK-NEXT:    ret void
158   %1 = tail call noalias i8* @calloc(i64 2, i64 4)
159   tail call void @no_sync_func(i8* %1)
160   tail call void @free(i8* %1)
161   ret void
164 ; TEST 4
165 define void @test4() {
166 ; CHECK-LABEL: define {{[^@]+}}@test4() {
167 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
168 ; CHECK-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP1]])
169 ; CHECK-NEXT:    ret void
171   %1 = tail call noalias i8* @malloc(i64 4)
172   tail call void @nofree_func(i8* %1)
173   ret void
176 ; TEST 5 - not all exit paths have a call to free, but all uses of malloc
177 ; are in nofree functions and are not captured
179 define void @test5(i32, i8* %p) {
180 ; IS________OPM-LABEL: define {{[^@]+}}@test5
181 ; IS________OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) {
182 ; IS________OPM-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
183 ; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
184 ; IS________OPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
185 ; IS________OPM:       4:
186 ; IS________OPM-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]])
187 ; IS________OPM-NEXT:    br label [[TMP6:%.*]]
188 ; IS________OPM:       5:
189 ; IS________OPM-NEXT:    tail call void @nofree_arg_only(i8* nocapture nofree [[TMP2]], i8* nocapture [[P]])
190 ; IS________OPM-NEXT:    tail call void @free(i8* noalias nocapture [[TMP2]])
191 ; IS________OPM-NEXT:    br label [[TMP6]]
192 ; IS________OPM:       6:
193 ; IS________OPM-NEXT:    ret void
195 ; IS________NPM-LABEL: define {{[^@]+}}@test5
196 ; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]]) {
197 ; IS________NPM-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
198 ; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
199 ; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
200 ; IS________NPM:       4:
201 ; IS________NPM-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]])
202 ; IS________NPM-NEXT:    br label [[TMP6:%.*]]
203 ; IS________NPM:       5:
204 ; IS________NPM-NEXT:    tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP2]], i8* nocapture [[P]])
205 ; IS________NPM-NEXT:    tail call void @free(i8* noalias nocapture [[TMP2]])
206 ; IS________NPM-NEXT:    br label [[TMP6]]
207 ; IS________NPM:       6:
208 ; IS________NPM-NEXT:    ret void
210   %2 = tail call noalias i8* @malloc(i64 4)
211   %3 = icmp eq i32 %0, 0
212   br i1 %3, label %5, label %4
214 4:                                                ; preds = %1
215   tail call void @nofree_func(i8* %2)
216   br label %6
218 5:                                                ; preds = %1
219   tail call void @nofree_arg_only(i8* %2, i8* %p)
220   tail call void @free(i8* %2)
221   br label %6
223 6:                                                ; preds = %5, %4
224   ret void
227 ; TEST 6 - all exit paths have a call to free
229 define void @test6(i32) {
230 ; CHECK-LABEL: define {{[^@]+}}@test6
231 ; CHECK-SAME: (i32 [[TMP0:%.*]]) {
232 ; CHECK-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
233 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
234 ; CHECK-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
235 ; CHECK:       4:
236 ; CHECK-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]])
237 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP2]])
238 ; CHECK-NEXT:    br label [[TMP6:%.*]]
239 ; CHECK:       5:
240 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP2]])
241 ; CHECK-NEXT:    br label [[TMP6]]
242 ; CHECK:       6:
243 ; CHECK-NEXT:    ret void
245   %2 = tail call noalias i8* @malloc(i64 4)
246   %3 = icmp eq i32 %0, 0
247   br i1 %3, label %5, label %4
249 4:                                                ; preds = %1
250   tail call void @nofree_func(i8* %2)
251   tail call void @free(i8* %2)
252   br label %6
254 5:                                                ; preds = %1
255   tail call void @free(i8* %2)
256   br label %6
258 6:                                                ; preds = %5, %4
259   ret void
262 ; TEST 7 - free is dead.
264 define void @test7() {
265 ; CHECK: Function Attrs: noreturn
266 ; CHECK-LABEL: define {{[^@]+}}@test7
267 ; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
268 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
269 ; CHECK-NEXT:    [[TMP2:%.*]] = tail call i32 @no_return_call() #[[ATTR3]]
270 ; CHECK-NEXT:    unreachable
272   %1 = tail call noalias i8* @malloc(i64 4)
273   tail call i32 @no_return_call()
274   tail call void @free(i8* %1)
275   ret void
278 ; TEST 8 - Negative: bitcast pointer used in capture function
280 define void @test8() {
281 ; CHECK-LABEL: define {{[^@]+}}@test8() {
282 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
283 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
284 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
285 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
286 ; CHECK-NEXT:    tail call void @foo(i32* noundef align 4 [[TMP2]])
287 ; CHECK-NEXT:    tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
288 ; CHECK-NEXT:    ret void
290   %1 = tail call noalias i8* @malloc(i64 4)
291   tail call void @no_sync_func(i8* %1)
292   %2 = bitcast i8* %1 to i32*
293   store i32 10, i32* %2
294   %3 = load i32, i32* %2
295   tail call void @foo(i32* %2)
296   tail call void @free(i8* %1)
297   ret void
300 ; TEST 9 - FIXME: malloc should be converted.
301 define void @test9() {
302 ; CHECK-LABEL: define {{[^@]+}}@test9() {
303 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
304 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
305 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
306 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
307 ; CHECK-NEXT:    tail call void @foo_nounw(i32* nofree noundef align 4 [[TMP2]]) #[[ATTR5:[0-9]+]]
308 ; CHECK-NEXT:    tail call void @free(i8* nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
309 ; CHECK-NEXT:    ret void
311   %1 = tail call noalias i8* @malloc(i64 4)
312   tail call void @no_sync_func(i8* %1)
313   %2 = bitcast i8* %1 to i32*
314   store i32 10, i32* %2
315   %3 = load i32, i32* %2
316   tail call void @foo_nounw(i32* %2)
317   tail call void @free(i8* %1)
318   ret void
321 ; TEST 10 - 1 malloc, 1 free
323 define i32 @test10() {
324 ; CHECK-LABEL: define {{[^@]+}}@test10() {
325 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
326 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
327 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
328 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
329 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
330 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
331 ; CHECK-NEXT:    ret i32 [[TMP3]]
333   %1 = tail call noalias i8* @malloc(i64 4)
334   tail call void @no_sync_func(i8* %1)
335   %2 = bitcast i8* %1 to i32*
336   store i32 10, i32* %2
337   %3 = load i32, i32* %2
338   tail call void @free(i8* %1)
339   ret i32 %3
342 define i32 @test_lifetime() {
343 ; CHECK-LABEL: define {{[^@]+}}@test_lifetime() {
344 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
345 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
346 ; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8* noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[TMP1]])
347 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
348 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
349 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
350 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
351 ; CHECK-NEXT:    ret i32 [[TMP3]]
353   %1 = tail call noalias i8* @malloc(i64 4)
354   tail call void @no_sync_func(i8* %1)
355   call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
356   %2 = bitcast i8* %1 to i32*
357   store i32 10, i32* %2
358   %3 = load i32, i32* %2
359   tail call void @free(i8* %1)
360   ret i32 %3
363 ; TEST 11
365 define void @test11() {
366 ; CHECK-LABEL: define {{[^@]+}}@test11() {
367 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
368 ; CHECK-NEXT:    tail call void @sync_will_return(i8* [[TMP1]]) #[[ATTR5]]
369 ; CHECK-NEXT:    tail call void @free(i8* nocapture [[TMP1]])
370 ; CHECK-NEXT:    ret void
372   %1 = tail call noalias i8* @malloc(i64 4)
373   tail call void @sync_will_return(i8* %1)
374   tail call void @free(i8* %1)
375   ret void
378 ; TEST 12
379 define i32 @irreducible_cfg(i32 %0) {
380 ; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg
381 ; IS________OPM-SAME: (i32 [[TMP0:%.*]]) {
382 ; IS________OPM-NEXT:    [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4)
383 ; IS________OPM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
384 ; IS________OPM-NEXT:    store i32 10, i32* [[TMP3]], align 4
385 ; IS________OPM-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
386 ; IS________OPM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
387 ; IS________OPM:       5:
388 ; IS________OPM-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
389 ; IS________OPM-NEXT:    br label [[TMP13:%.*]]
390 ; IS________OPM:       7:
391 ; IS________OPM-NEXT:    br label [[TMP8:%.*]]
392 ; IS________OPM:       8:
393 ; IS________OPM-NEXT:    [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
394 ; IS________OPM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
395 ; IS________OPM-NEXT:    [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
396 ; IS________OPM-NEXT:    store i32 [[TMP10]], i32* [[TMP3]], align 4
397 ; IS________OPM-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
398 ; IS________OPM-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
399 ; IS________OPM:       12:
400 ; IS________OPM-NEXT:    br label [[TMP13]]
401 ; IS________OPM:       13:
402 ; IS________OPM-NEXT:    [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
403 ; IS________OPM-NEXT:    [[TMP14]] = add nsw i32 [[DOT1]], 1
404 ; IS________OPM-NEXT:    br label [[TMP8]]
405 ; IS________OPM:       15:
406 ; IS________OPM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
407 ; IS________OPM-NEXT:    [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8*
408 ; IS________OPM-NEXT:    call void @free(i8* nocapture noundef [[TMP17]])
409 ; IS________OPM-NEXT:    [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4
410 ; IS________OPM-NEXT:    ret i32 [[TMP18]]
412 ; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg
413 ; IS________NPM-SAME: (i32 [[TMP0:%.*]]) {
414 ; IS________NPM-NEXT:    [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4)
415 ; IS________NPM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
416 ; IS________NPM-NEXT:    store i32 10, i32* [[TMP3]], align 4
417 ; IS________NPM-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
418 ; IS________NPM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
419 ; IS________NPM:       5:
420 ; IS________NPM-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
421 ; IS________NPM-NEXT:    br label [[TMP13:%.*]]
422 ; IS________NPM:       7:
423 ; IS________NPM-NEXT:    br label [[TMP8:%.*]]
424 ; IS________NPM:       8:
425 ; IS________NPM-NEXT:    [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
426 ; IS________NPM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
427 ; IS________NPM-NEXT:    [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
428 ; IS________NPM-NEXT:    store i32 [[TMP10]], i32* [[TMP3]], align 4
429 ; IS________NPM-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
430 ; IS________NPM-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
431 ; IS________NPM:       12:
432 ; IS________NPM-NEXT:    br label [[TMP13]]
433 ; IS________NPM:       13:
434 ; IS________NPM-NEXT:    [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
435 ; IS________NPM-NEXT:    [[TMP14]] = add nsw i32 [[DOT1]], 1
436 ; IS________NPM-NEXT:    br label [[TMP8]]
437 ; IS________NPM:       15:
438 ; IS________NPM-NEXT:    [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
439 ; IS________NPM-NEXT:    call void @free(i8* nocapture noundef [[TMP2]])
440 ; IS________NPM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
441 ; IS________NPM-NEXT:    ret i32 [[TMP17]]
443   %2 = call noalias i8* @malloc(i64 4)
444   %3 = bitcast i8* %2 to i32*
445   store i32 10, i32* %3, align 4
446   %4 = icmp eq i32 %0, 1
447   br i1 %4, label %5, label %7
449 5:                                                ; preds = %1
450   %6 = add nsw i32 %0, 5
451   br label %13
453 7:                                                ; preds = %1
454   br label %8
456 8:                                                ; preds = %13, %7
457   %.0 = phi i32 [ %14, %13 ], [ 1, %7 ]
458   %9 = load i32, i32* %3, align 4
459   %10 = add nsw i32 %9, -1
460   store i32 %10, i32* %3, align 4
461   %11 = icmp ne i32 %9, 0
462   br i1 %11, label %12, label %15
464 12:                                               ; preds = %8
465   br label %13
467 13:                                               ; preds = %12, %5
468   %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ]
469   %14 = add nsw i32 %.1, 1
470   br label %8
472 15:                                               ; preds = %8
473   %16 = load i32, i32* %3, align 4
474   %17 = bitcast i32* %3 to i8*
475   call void @free(i8* %17)
476   %18 = load i32, i32* %3, align 4
477   ret i32 %18
481 define i32 @malloc_in_loop(i32 %0) {
482 ; CHECK-LABEL: define {{[^@]+}}@malloc_in_loop
483 ; CHECK-SAME: (i32 [[TMP0:%.*]]) {
484 ; CHECK-NEXT:    [[TMP2:%.*]] = alloca i32, align 4
485 ; CHECK-NEXT:    [[TMP3:%.*]] = alloca i32*, align 8
486 ; CHECK-NEXT:    store i32 [[TMP0]], i32* [[TMP2]], align 4
487 ; CHECK-NEXT:    br label [[TMP4:%.*]]
488 ; CHECK:       4:
489 ; CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4
490 ; CHECK-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1
491 ; CHECK-NEXT:    store i32 [[TMP6]], i32* [[TMP2]], align 4
492 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0
493 ; CHECK-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]]
494 ; CHECK:       8:
495 ; CHECK-NEXT:    [[TMP9:%.*]] = call noalias i8* @malloc(i64 noundef 4)
496 ; CHECK-NEXT:    [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
497 ; CHECK-NEXT:    store i32 1, i32* [[TMP10]], align 8
498 ; CHECK-NEXT:    br label [[TMP4]]
499 ; CHECK:       11:
500 ; CHECK-NEXT:    ret i32 5
502   %2 = alloca i32, align 4
503   %3 = alloca i32*, align 8
504   store i32 %0, i32* %2, align 4
505   br label %4
507 4:                                                ; preds = %8, %1
508   %5 = load i32, i32* %2, align 4
509   %6 = add nsw i32 %5, -1
510   store i32 %6, i32* %2, align 4
511   %7 = icmp sgt i32 %6, 0
512   br i1 %7, label %8, label %11
514 8:                                                ; preds = %4
515   %9 = call noalias i8* @malloc(i64 4)
516   %10 = bitcast i8* %9 to i32*
517   store i32 1, i32* %10, align 8
518   br label %4
520 11:                                               ; preds = %4
521   ret i32 5
524 ; Malloc/Calloc too large
525 define i32 @test13() {
526 ; CHECK-LABEL: define {{[^@]+}}@test13() {
527 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 256)
528 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
529 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
530 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
531 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
532 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
533 ; CHECK-NEXT:    ret i32 [[TMP3]]
535   %1 = tail call noalias i8* @malloc(i64 256)
536   tail call void @no_sync_func(i8* %1)
537   %2 = bitcast i8* %1 to i32*
538   store i32 10, i32* %2
539   %3 = load i32, i32* %2
540   tail call void @free(i8* %1)
541   ret i32 %3
544 define i32 @test_sle() {
545 ; CHECK-LABEL: define {{[^@]+}}@test_sle() {
546 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef -1)
547 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
548 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
549 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
550 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
551 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
552 ; CHECK-NEXT:    ret i32 [[TMP3]]
554   %1 = tail call noalias i8* @malloc(i64 -1)
555   tail call void @no_sync_func(i8* %1)
556   %2 = bitcast i8* %1 to i32*
557   store i32 10, i32* %2
558   %3 = load i32, i32* %2
559   tail call void @free(i8* %1)
560   ret i32 %3
563 define i32 @test_overflow() {
564 ; CHECK-LABEL: define {{[^@]+}}@test_overflow() {
565 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 65537, i64 noundef 65537)
566 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
567 ; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
568 ; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
569 ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
570 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture noundef nonnull align 4 dereferenceable(4) [[TMP1]])
571 ; CHECK-NEXT:    ret i32 [[TMP3]]
573   %1 = tail call noalias i8* @calloc(i64 65537, i64 65537)
574   tail call void @no_sync_func(i8* %1)
575   %2 = bitcast i8* %1 to i32*
576   store i32 10, i32* %2
577   %3 = load i32, i32* %2
578   tail call void @free(i8* %1)
579   ret i32 %3
582 define void @test14() {
583 ; CHECK-LABEL: define {{[^@]+}}@test14() {
584 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 noundef 64, i64 noundef 4)
585 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
586 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
587 ; CHECK-NEXT:    ret void
589   %1 = tail call noalias i8* @calloc(i64 64, i64 4)
590   tail call void @no_sync_func(i8* %1)
591   tail call void @free(i8* %1)
592   ret void
595 define void @test15(i64 %S) {
596 ; CHECK-LABEL: define {{[^@]+}}@test15
597 ; CHECK-SAME: (i64 [[S:%.*]]) {
598 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]])
599 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
600 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture [[TMP1]])
601 ; CHECK-NEXT:    ret void
603   %1 = tail call noalias i8* @malloc(i64 %S)
604   tail call void @no_sync_func(i8* %1)
605   tail call void @free(i8* %1)
606   ret void
609 define void @test16a(i8 %v, i8** %P) {
610 ; CHECK-LABEL: define {{[^@]+}}@test16a
611 ; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]]) {
612 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
613 ; CHECK-NEXT:    store i8 [[V]], i8* [[TMP1]], align 1
614 ; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree noundef nonnull dereferenceable(1) [[TMP1]])
615 ; CHECK-NEXT:    tail call void @free(i8* noalias nocapture noundef nonnull dereferenceable(1) [[TMP1]])
616 ; CHECK-NEXT:    ret void
618   %1 = tail call noalias i8* @malloc(i64 4)
619   store i8 %v, i8* %1
620   tail call void @no_sync_func(i8* %1)
621   tail call void @free(i8* nonnull dereferenceable(1) %1)
622   ret void
625 define void @test16b(i8 %v, i8** %P) {
626 ; CHECK-LABEL: define {{[^@]+}}@test16b
627 ; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) {
628 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
629 ; CHECK-NEXT:    store i8* [[TMP1]], i8** [[P]], align 8
630 ; CHECK-NEXT:    tail call void @no_sync_func(i8* nocapture nofree [[TMP1]])
631 ; CHECK-NEXT:    tail call void @free(i8* nocapture [[TMP1]])
632 ; CHECK-NEXT:    ret void
634   %1 = tail call noalias i8* @malloc(i64 4)
635   store i8* %1, i8** %P
636   tail call void @no_sync_func(i8* %1)
637   tail call void @free(i8* %1)
638   ret void
641 define void @test16c(i8 %v, i8** %P) {
642 ; CHECK-LABEL: define {{[^@]+}}@test16c
643 ; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) {
644 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
645 ; CHECK-NEXT:    store i8* [[TMP1]], i8** [[P]], align 8
646 ; CHECK-NEXT:    tail call void @no_sync_func(i8* nocapture nofree [[TMP1]]) #[[ATTR5]]
647 ; CHECK-NEXT:    tail call void @free(i8* nocapture [[TMP1]])
648 ; CHECK-NEXT:    ret void
650   %1 = tail call noalias i8* @malloc(i64 4)
651   store i8* %1, i8** %P
652   tail call void @no_sync_func(i8* %1) nounwind
653   tail call void @free(i8* %1)
654   ret void
657 define void @test16d(i8 %v, i8** %P) {
658 ; CHECK-LABEL: define {{[^@]+}}@test16d
659 ; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture nofree writeonly [[P:%.*]]) {
660 ; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
661 ; CHECK-NEXT:    store i8* [[TMP1]], i8** [[P]], align 8
662 ; CHECK-NEXT:    ret void
664   %1 = tail call noalias i8* @malloc(i64 4)
665   store i8* %1, i8** %P
666   ret void
669 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nounwind willreturn }
670 ; CHECK: attributes #[[ATTR1:[0-9]+]] = { nofree nosync willreturn }
671 ; CHECK: attributes #[[ATTR2:[0-9]+]] = { nofree nounwind }
672 ; CHECK: attributes #[[ATTR3]] = { noreturn }
673 ; CHECK: attributes #[[ATTR4:[0-9]+]] = { argmemonly nofree nosync nounwind willreturn }
674 ; CHECK: attributes #[[ATTR5]] = { nounwind }