1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -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 -attributor-manifest-internal -attributor-disable=false -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-disable=false -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
6
7declare noalias i8* @malloc(i64)
8
9declare void @nocapture_func_frees_pointer(i8* nocapture)
10
11declare void @func_throws(...)
12
13declare void @sync_func(i8* %p)
14
15declare void @sync_will_return(i8* %p) willreturn nounwind
16
17declare void @no_sync_func(i8* nocapture %p) nofree nosync willreturn
18
19declare void @nofree_func(i8* nocapture %p) nofree  nosync willreturn
20
21declare void @foo(i32* %p)
22
23declare void @foo_nounw(i32* %p) nounwind nofree
24
25declare i32 @no_return_call() noreturn
26
27declare void @free(i8* nocapture)
28
29declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
30
31define void @nofree_arg_only(i8* %p1, i8* %p2) {
32; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only
33; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture [[P2:%.*]])
34; CHECK-NEXT:    tail call void @free(i8* nocapture [[P2]])
35; CHECK-NEXT:    tail call void @nofree_func(i8* nocapture nofree [[P1]])
36; CHECK-NEXT:    ret void
37;
38  tail call void @free(i8* %p2)
39  tail call void @nofree_func(i8* %p1)
40  ret void
41}
42
43; TEST 1 - negative, pointer freed in another function.
44
45define void @test1() {
46; IS________OPM-LABEL: define {{[^@]+}}@test1()
47; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
48; IS________OPM-NEXT:    tail call void @nocapture_func_frees_pointer(i8* noalias [[TMP1]])
49; IS________OPM-NEXT:    tail call void (...) @func_throws()
50; IS________OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
51; IS________OPM-NEXT:    ret void
52;
53; IS________NPM-LABEL: define {{[^@]+}}@test1()
54; IS________NPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
55; IS________NPM-NEXT:    tail call void @nocapture_func_frees_pointer(i8* noalias nocapture [[TMP1]])
56; IS________NPM-NEXT:    tail call void (...) @func_throws()
57; IS________NPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
58; IS________NPM-NEXT:    ret void
59;
60  %1 = tail call noalias i8* @malloc(i64 4)
61  tail call void @nocapture_func_frees_pointer(i8* %1)
62  tail call void (...) @func_throws()
63  tail call void @free(i8* %1)
64  ret void
65}
66
67; TEST 2 - negative, call to a sync function.
68
69define void @test2() {
70; CHECK-LABEL: define {{[^@]+}}@test2()
71; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
72; CHECK-NEXT:    tail call void @sync_func(i8* [[TMP1]])
73; CHECK-NEXT:    tail call void @free(i8* [[TMP1]])
74; CHECK-NEXT:    ret void
75;
76  %1 = tail call noalias i8* @malloc(i64 4)
77  tail call void @sync_func(i8* %1)
78  tail call void @free(i8* %1)
79  ret void
80}
81
82; TEST 3 - 1 malloc, 1 free
83
84define void @test3() {
85; IS________OPM-LABEL: define {{[^@]+}}@test3()
86; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
87; IS________OPM-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
88; IS________OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
89; IS________OPM-NEXT:    ret void
90;
91; IS________NPM-LABEL: define {{[^@]+}}@test3()
92; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
93; IS________NPM-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
94; IS________NPM-NEXT:    ret void
95;
96  %1 = tail call noalias i8* @malloc(i64 4)
97  tail call void @no_sync_func(i8* %1)
98  tail call void @free(i8* %1)
99  ret void
100}
101
102define void @test3a(i8* %p) {
103; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3a
104; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]])
105; IS__TUNIT_OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
106; IS__TUNIT_OPM-NEXT:    tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]])
107; IS__TUNIT_OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
108; IS__TUNIT_OPM-NEXT:    ret void
109;
110; IS________NPM-LABEL: define {{[^@]+}}@test3a
111; IS________NPM-SAME: (i8* nocapture [[P:%.*]])
112; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
113; IS________NPM-NEXT:    tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]])
114; IS________NPM-NEXT:    ret void
115;
116; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3a
117; IS__CGSCC_OPM-SAME: (i8* nocapture [[P:%.*]])
118; IS__CGSCC_OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
119; IS__CGSCC_OPM-NEXT:    tail call void @nofree_arg_only(i8* nofree [[TMP1]], i8* nocapture [[P]])
120; IS__CGSCC_OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
121; IS__CGSCC_OPM-NEXT:    ret void
122;
123  %1 = tail call noalias i8* @malloc(i64 4)
124  tail call void @nofree_arg_only(i8* %1, i8* %p)
125  tail call void @free(i8* %1)
126  ret void
127}
128
129declare noalias i8* @aligned_alloc(i64, i64)
130
131define void @test3b(i8* %p) {
132; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3b
133; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]])
134; IS__TUNIT_OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 128)
135; IS__TUNIT_OPM-NEXT:    tail call void @nofree_arg_only(i8* nocapture nofree [[TMP1]], i8* nocapture [[P]])
136; IS__TUNIT_OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
137; IS__TUNIT_OPM-NEXT:    ret void
138;
139; IS________NPM-LABEL: define {{[^@]+}}@test3b
140; IS________NPM-SAME: (i8* nocapture [[P:%.*]])
141; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 128, align 32
142; IS________NPM-NEXT:    tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP1]], i8* nocapture [[P]])
143; IS________NPM-NEXT:    ret void
144;
145; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3b
146; IS__CGSCC_OPM-SAME: (i8* nocapture [[P:%.*]])
147; IS__CGSCC_OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 128)
148; IS__CGSCC_OPM-NEXT:    tail call void @nofree_arg_only(i8* nofree [[TMP1]], i8* nocapture [[P]])
149; IS__CGSCC_OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
150; IS__CGSCC_OPM-NEXT:    ret void
151;
152  %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128)
153  tail call void @nofree_arg_only(i8* %1, i8* %p)
154  tail call void @free(i8* %1)
155  ret void
156}
157
158; leave alone non-constant alignments.
159define void @test3c(i64 %alignment) {
160; CHECK-LABEL: define {{[^@]+}}@test3c
161; CHECK-SAME: (i64 [[ALIGNMENT:%.*]])
162; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 [[ALIGNMENT]], i64 128)
163; CHECK-NEXT:    tail call void @free(i8* noalias [[TMP1]])
164; CHECK-NEXT:    ret void
165;
166  %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128)
167  tail call void @free(i8* %1)
168  ret void
169}
170
171declare noalias i8* @calloc(i64, i64)
172
173define void @test0() {
174; IS________OPM-LABEL: define {{[^@]+}}@test0()
175; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 2, i64 4)
176; IS________OPM-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
177; IS________OPM-NEXT:    tail call void @free(i8* noalias [[TMP1]])
178; IS________OPM-NEXT:    ret void
179;
180; IS________NPM-LABEL: define {{[^@]+}}@test0()
181; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 8
182; IS________NPM-NEXT:    [[CALLOC_BC:%.*]] = bitcast i8* [[TMP1]] to i8*
183; IS________NPM-NEXT:    call void @llvm.memset.p0i8.i64(i8* [[CALLOC_BC]], i8 0, i64 8, i1 false)
184; IS________NPM-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
185; IS________NPM-NEXT:    ret void
186;
187  %1 = tail call noalias i8* @calloc(i64 2, i64 4)
188  tail call void @no_sync_func(i8* %1)
189  tail call void @free(i8* %1)
190  ret void
191}
192
193; TEST 4
194define void @test4() {
195; IS________OPM-LABEL: define {{[^@]+}}@test4()
196; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
197; IS________OPM-NEXT:    tail call void @nofree_func(i8* noalias nofree [[TMP1]])
198; IS________OPM-NEXT:    ret void
199;
200; IS________NPM-LABEL: define {{[^@]+}}@test4()
201; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
202; IS________NPM-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP1]])
203; IS________NPM-NEXT:    ret void
204;
205  %1 = tail call noalias i8* @malloc(i64 4)
206  tail call void @nofree_func(i8* %1)
207  ret void
208}
209
210; TEST 5 - not all exit paths have a call to free, but all uses of malloc
211; are in nofree functions and are not captured
212
213define void @test5(i32, i8* %p) {
214; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test5
215; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]])
216; IS__TUNIT_OPM-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4)
217; IS__TUNIT_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
218; IS__TUNIT_OPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
219; IS__TUNIT_OPM:       4:
220; IS__TUNIT_OPM-NEXT:    tail call void @nofree_func(i8* noalias nofree [[TMP2]])
221; IS__TUNIT_OPM-NEXT:    br label [[TMP6:%.*]]
222; IS__TUNIT_OPM:       5:
223; IS__TUNIT_OPM-NEXT:    tail call void @nofree_arg_only(i8* nocapture nofree [[TMP2]], i8* nocapture [[P]])
224; IS__TUNIT_OPM-NEXT:    tail call void @free(i8* noalias [[TMP2]])
225; IS__TUNIT_OPM-NEXT:    br label [[TMP6]]
226; IS__TUNIT_OPM:       6:
227; IS__TUNIT_OPM-NEXT:    ret void
228;
229; IS________NPM-LABEL: define {{[^@]+}}@test5
230; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]])
231; IS________NPM-NEXT:    [[TMP2:%.*]] = alloca i8, i64 4
232; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
233; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
234; IS________NPM:       4:
235; IS________NPM-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]])
236; IS________NPM-NEXT:    br label [[TMP6:%.*]]
237; IS________NPM:       5:
238; IS________NPM-NEXT:    tail call void @nofree_arg_only(i8* noalias nocapture nofree [[TMP2]], i8* nocapture [[P]])
239; IS________NPM-NEXT:    br label [[TMP6]]
240; IS________NPM:       6:
241; IS________NPM-NEXT:    ret void
242;
243; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5
244; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]])
245; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4)
246; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
247; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
248; IS__CGSCC_OPM:       4:
249; IS__CGSCC_OPM-NEXT:    tail call void @nofree_func(i8* noalias nofree [[TMP2]])
250; IS__CGSCC_OPM-NEXT:    br label [[TMP6:%.*]]
251; IS__CGSCC_OPM:       5:
252; IS__CGSCC_OPM-NEXT:    tail call void @nofree_arg_only(i8* nofree [[TMP2]], i8* nocapture [[P]])
253; IS__CGSCC_OPM-NEXT:    tail call void @free(i8* noalias [[TMP2]])
254; IS__CGSCC_OPM-NEXT:    br label [[TMP6]]
255; IS__CGSCC_OPM:       6:
256; IS__CGSCC_OPM-NEXT:    ret void
257;
258  %2 = tail call noalias i8* @malloc(i64 4)
259  %3 = icmp eq i32 %0, 0
260  br i1 %3, label %5, label %4
261
2624:                                                ; preds = %1
263  tail call void @nofree_func(i8* %2)
264  br label %6
265
2665:                                                ; preds = %1
267  tail call void @nofree_arg_only(i8* %2, i8* %p)
268  tail call void @free(i8* %2)
269  br label %6
270
2716:                                                ; preds = %5, %4
272  ret void
273}
274
275; TEST 6 - all exit paths have a call to free
276
277define void @test6(i32) {
278; IS________OPM-LABEL: define {{[^@]+}}@test6
279; IS________OPM-SAME: (i32 [[TMP0:%.*]])
280; IS________OPM-NEXT:    [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4)
281; IS________OPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
282; IS________OPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
283; IS________OPM:       4:
284; IS________OPM-NEXT:    tail call void @nofree_func(i8* noalias nofree [[TMP2]])
285; IS________OPM-NEXT:    tail call void @free(i8* noalias [[TMP2]])
286; IS________OPM-NEXT:    br label [[TMP6:%.*]]
287; IS________OPM:       5:
288; IS________OPM-NEXT:    tail call void @free(i8* noalias [[TMP2]])
289; IS________OPM-NEXT:    br label [[TMP6]]
290; IS________OPM:       6:
291; IS________OPM-NEXT:    ret void
292;
293; IS________NPM-LABEL: define {{[^@]+}}@test6
294; IS________NPM-SAME: (i32 [[TMP0:%.*]])
295; IS________NPM-NEXT:    [[TMP2:%.*]] = alloca i8, i64 4
296; IS________NPM-NEXT:    [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
297; IS________NPM-NEXT:    br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
298; IS________NPM:       4:
299; IS________NPM-NEXT:    tail call void @nofree_func(i8* noalias nocapture nofree [[TMP2]])
300; IS________NPM-NEXT:    br label [[TMP6:%.*]]
301; IS________NPM:       5:
302; IS________NPM-NEXT:    br label [[TMP6]]
303; IS________NPM:       6:
304; IS________NPM-NEXT:    ret void
305;
306  %2 = tail call noalias i8* @malloc(i64 4)
307  %3 = icmp eq i32 %0, 0
308  br i1 %3, label %5, label %4
309
3104:                                                ; preds = %1
311  tail call void @nofree_func(i8* %2)
312  tail call void @free(i8* %2)
313  br label %6
314
3155:                                                ; preds = %1
316  tail call void @free(i8* %2)
317  br label %6
318
3196:                                                ; preds = %5, %4
320  ret void
321}
322
323; TEST 7 - free is dead.
324
325define void @test7() {
326; IS________OPM-LABEL: define {{[^@]+}}@test7()
327; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
328; IS________OPM-NEXT:    [[TMP2:%.*]] = tail call i32 @no_return_call()
329; IS________OPM-NEXT:    unreachable
330;
331; IS________NPM-LABEL: define {{[^@]+}}@test7()
332; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
333; IS________NPM-NEXT:    [[TMP2:%.*]] = tail call i32 @no_return_call()
334; IS________NPM-NEXT:    unreachable
335;
336  %1 = tail call noalias i8* @malloc(i64 4)
337  tail call i32 @no_return_call()
338  tail call void @free(i8* %1)
339  ret void
340}
341
342; TEST 8 - Negative: bitcast pointer used in capture function
343
344define void @test8() {
345; CHECK-LABEL: define {{[^@]+}}@test8()
346; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
347; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
348; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
349; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
350; CHECK-NEXT:    tail call void @foo(i32* align 4 [[TMP2]])
351; CHECK-NEXT:    tail call void @free(i8* nonnull align 4 dereferenceable(4) [[TMP1]])
352; CHECK-NEXT:    ret void
353;
354  %1 = tail call noalias i8* @malloc(i64 4)
355  tail call void @no_sync_func(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 @foo(i32* %2)
360  tail call void @free(i8* %1)
361  ret void
362}
363
364; TEST 9 - FIXME: malloc should be converted.
365define void @test9() {
366; CHECK-LABEL: define {{[^@]+}}@test9()
367; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
368; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
369; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
370; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
371; CHECK-NEXT:    tail call void @foo_nounw(i32* nofree align 4 [[TMP2]])
372; CHECK-NEXT:    tail call void @free(i8* nonnull align 4 dereferenceable(4) [[TMP1]])
373; CHECK-NEXT:    ret void
374;
375  %1 = tail call noalias i8* @malloc(i64 4)
376  tail call void @no_sync_func(i8* %1)
377  %2 = bitcast i8* %1 to i32*
378  store i32 10, i32* %2
379  %3 = load i32, i32* %2
380  tail call void @foo_nounw(i32* %2)
381  tail call void @free(i8* %1)
382  ret void
383}
384
385; TEST 10 - 1 malloc, 1 free
386
387define i32 @test10() {
388; IS________OPM-LABEL: define {{[^@]+}}@test10()
389; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
390; IS________OPM-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
391; IS________OPM-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
392; IS________OPM-NEXT:    store i32 10, i32* [[TMP2]], align 4
393; IS________OPM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
394; IS________OPM-NEXT:    tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
395; IS________OPM-NEXT:    ret i32 [[TMP3]]
396;
397; IS________NPM-LABEL: define {{[^@]+}}@test10()
398; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
399; IS________NPM-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
400; IS________NPM-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
401; IS________NPM-NEXT:    store i32 10, i32* [[TMP2]], align 4
402; IS________NPM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
403; IS________NPM-NEXT:    ret i32 [[TMP3]]
404;
405  %1 = tail call noalias i8* @malloc(i64 4)
406  tail call void @no_sync_func(i8* %1)
407  %2 = bitcast i8* %1 to i32*
408  store i32 10, i32* %2
409  %3 = load i32, i32* %2
410  tail call void @free(i8* %1)
411  ret i32 %3
412}
413
414define i32 @test_lifetime() {
415; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime()
416; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
417; IS________OPM-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
418; IS________OPM-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
419; IS________OPM-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
420; IS________OPM-NEXT:    store i32 10, i32* [[TMP2]], align 4
421; IS________OPM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
422; IS________OPM-NEXT:    tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
423; IS________OPM-NEXT:    ret i32 [[TMP3]]
424;
425; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime()
426; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
427; IS________NPM-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree [[TMP1]])
428; IS________NPM-NEXT:    call void @llvm.lifetime.start.p0i8(i64 4, i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
429; IS________NPM-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
430; IS________NPM-NEXT:    store i32 10, i32* [[TMP2]], align 4
431; IS________NPM-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
432; IS________NPM-NEXT:    ret i32 [[TMP3]]
433;
434  %1 = tail call noalias i8* @malloc(i64 4)
435  tail call void @no_sync_func(i8* %1)
436  call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
437  %2 = bitcast i8* %1 to i32*
438  store i32 10, i32* %2
439  %3 = load i32, i32* %2
440  tail call void @free(i8* %1)
441  ret i32 %3
442}
443
444; TEST 11
445
446define void @test11() {
447; IS________OPM-LABEL: define {{[^@]+}}@test11()
448; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
449; IS________OPM-NEXT:    tail call void @sync_will_return(i8* [[TMP1]])
450; IS________OPM-NEXT:    tail call void @free(i8* [[TMP1]])
451; IS________OPM-NEXT:    ret void
452;
453; IS________NPM-LABEL: define {{[^@]+}}@test11()
454; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
455; IS________NPM-NEXT:    tail call void @sync_will_return(i8* [[TMP1]])
456; IS________NPM-NEXT:    ret void
457;
458  %1 = tail call noalias i8* @malloc(i64 4)
459  tail call void @sync_will_return(i8* %1)
460  tail call void @free(i8* %1)
461  ret void
462}
463
464; TEST 12
465define i32 @irreducible_cfg(i32 %0) {
466; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg
467; IS________OPM-SAME: (i32 [[TMP0:%.*]])
468; IS________OPM-NEXT:    [[TMP2:%.*]] = call noalias i8* @malloc(i64 4)
469; IS________OPM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
470; IS________OPM-NEXT:    store i32 10, i32* [[TMP3]], align 4
471; IS________OPM-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
472; IS________OPM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
473; IS________OPM:       5:
474; IS________OPM-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
475; IS________OPM-NEXT:    br label [[TMP13:%.*]]
476; IS________OPM:       7:
477; IS________OPM-NEXT:    br label [[TMP8:%.*]]
478; IS________OPM:       8:
479; IS________OPM-NEXT:    [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
480; IS________OPM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
481; IS________OPM-NEXT:    [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
482; IS________OPM-NEXT:    store i32 [[TMP10]], i32* [[TMP3]], align 4
483; IS________OPM-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
484; IS________OPM-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
485; IS________OPM:       12:
486; IS________OPM-NEXT:    br label [[TMP13]]
487; IS________OPM:       13:
488; IS________OPM-NEXT:    [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
489; IS________OPM-NEXT:    [[TMP14]] = add nsw i32 [[DOT1]], 1
490; IS________OPM-NEXT:    br label [[TMP8]]
491; IS________OPM:       15:
492; IS________OPM-NEXT:    [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8*
493; IS________OPM-NEXT:    call void @free(i8* [[TMP16]])
494; IS________OPM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
495; IS________OPM-NEXT:    ret i32 [[TMP17]]
496;
497; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg
498; IS________NPM-SAME: (i32 [[TMP0:%.*]])
499; IS________NPM-NEXT:    [[TMP2:%.*]] = alloca i8, i64 4
500; IS________NPM-NEXT:    [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
501; IS________NPM-NEXT:    store i32 10, i32* [[TMP3]], align 4
502; IS________NPM-NEXT:    [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
503; IS________NPM-NEXT:    br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
504; IS________NPM:       5:
505; IS________NPM-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
506; IS________NPM-NEXT:    br label [[TMP13:%.*]]
507; IS________NPM:       7:
508; IS________NPM-NEXT:    br label [[TMP8:%.*]]
509; IS________NPM:       8:
510; IS________NPM-NEXT:    [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
511; IS________NPM-NEXT:    [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
512; IS________NPM-NEXT:    [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
513; IS________NPM-NEXT:    store i32 [[TMP10]], i32* [[TMP3]], align 4
514; IS________NPM-NEXT:    [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
515; IS________NPM-NEXT:    br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
516; IS________NPM:       12:
517; IS________NPM-NEXT:    br label [[TMP13]]
518; IS________NPM:       13:
519; IS________NPM-NEXT:    [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
520; IS________NPM-NEXT:    [[TMP14]] = add nsw i32 [[DOT1]], 1
521; IS________NPM-NEXT:    br label [[TMP8]]
522; IS________NPM:       15:
523; IS________NPM-NEXT:    [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8*
524; IS________NPM-NEXT:    [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
525; IS________NPM-NEXT:    ret i32 [[TMP17]]
526;
527  %2 = call noalias i8* @malloc(i64 4)
528  %3 = bitcast i8* %2 to i32*
529  store i32 10, i32* %3, align 4
530  %4 = icmp eq i32 %0, 1
531  br i1 %4, label %5, label %7
532
5335:                                                ; preds = %1
534  %6 = add nsw i32 %0, 5
535  br label %13
536
5377:                                                ; preds = %1
538  br label %8
539
5408:                                                ; preds = %13, %7
541  %.0 = phi i32 [ %14, %13 ], [ 1, %7 ]
542  %9 = load i32, i32* %3, align 4
543  %10 = add nsw i32 %9, -1
544  store i32 %10, i32* %3, align 4
545  %11 = icmp ne i32 %9, 0
546  br i1 %11, label %12, label %15
547
54812:                                               ; preds = %8
549  br label %13
550
55113:                                               ; preds = %12, %5
552  %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ]
553  %14 = add nsw i32 %.1, 1
554  br label %8
555
55615:                                               ; preds = %8
557  %16 = load i32, i32* %3, align 4
558  %17 = bitcast i32* %3 to i8*
559  call void @free(i8* %17)
560  %18 = load i32, i32* %3, align 4
561  ret i32 %18
562}
563
564
565define i32 @malloc_in_loop(i32 %0) {
566; IS________OPM-LABEL: define {{[^@]+}}@malloc_in_loop
567; IS________OPM-SAME: (i32 [[TMP0:%.*]])
568; IS________OPM-NEXT:    [[TMP2:%.*]] = alloca i32, align 4
569; IS________OPM-NEXT:    [[TMP3:%.*]] = alloca i32*, align 8
570; IS________OPM-NEXT:    store i32 [[TMP0]], i32* [[TMP2]], align 4
571; IS________OPM-NEXT:    br label [[TMP4:%.*]]
572; IS________OPM:       4:
573; IS________OPM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4
574; IS________OPM-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1
575; IS________OPM-NEXT:    store i32 [[TMP6]], i32* [[TMP2]], align 4
576; IS________OPM-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0
577; IS________OPM-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]]
578; IS________OPM:       8:
579; IS________OPM-NEXT:    [[TMP9:%.*]] = call noalias i8* @malloc(i64 4)
580; IS________OPM-NEXT:    [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
581; IS________OPM-NEXT:    store i32 1, i32* [[TMP10]], align 8
582; IS________OPM-NEXT:    br label [[TMP4]]
583; IS________OPM:       11:
584; IS________OPM-NEXT:    ret i32 5
585;
586; IS________NPM-LABEL: define {{[^@]+}}@malloc_in_loop
587; IS________NPM-SAME: (i32 [[TMP0:%.*]])
588; IS________NPM-NEXT:    [[TMP2:%.*]] = alloca i32, align 4
589; IS________NPM-NEXT:    [[TMP3:%.*]] = alloca i32*, align 8
590; IS________NPM-NEXT:    store i32 [[TMP0]], i32* [[TMP2]], align 4
591; IS________NPM-NEXT:    br label [[TMP4:%.*]]
592; IS________NPM:       4:
593; IS________NPM-NEXT:    [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4
594; IS________NPM-NEXT:    [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1
595; IS________NPM-NEXT:    store i32 [[TMP6]], i32* [[TMP2]], align 4
596; IS________NPM-NEXT:    [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0
597; IS________NPM-NEXT:    br i1 [[TMP7]], label [[TMP8:%.*]], label [[TMP11:%.*]]
598; IS________NPM:       8:
599; IS________NPM-NEXT:    [[TMP9:%.*]] = alloca i8, i64 4
600; IS________NPM-NEXT:    [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
601; IS________NPM-NEXT:    store i32 1, i32* [[TMP10]], align 8
602; IS________NPM-NEXT:    br label [[TMP4]]
603; IS________NPM:       11:
604; IS________NPM-NEXT:    ret i32 5
605;
606  %2 = alloca i32, align 4
607  %3 = alloca i32*, align 8
608  store i32 %0, i32* %2, align 4
609  br label %4
610
6114:                                                ; preds = %8, %1
612  %5 = load i32, i32* %2, align 4
613  %6 = add nsw i32 %5, -1
614  store i32 %6, i32* %2, align 4
615  %7 = icmp sgt i32 %6, 0
616  br i1 %7, label %8, label %11
617
6188:                                                ; preds = %4
619  %9 = call noalias i8* @malloc(i64 4)
620  %10 = bitcast i8* %9 to i32*
621  store i32 1, i32* %10, align 8
622  br label %4
623
62411:                                               ; preds = %4
625  ret i32 5
626}
627
628; Malloc/Calloc too large
629define i32 @test13() {
630; CHECK-LABEL: define {{[^@]+}}@test13()
631; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 256)
632; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
633; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
634; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
635; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
636; CHECK-NEXT:    tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
637; CHECK-NEXT:    ret i32 [[TMP3]]
638;
639  %1 = tail call noalias i8* @malloc(i64 256)
640  tail call void @no_sync_func(i8* %1)
641  %2 = bitcast i8* %1 to i32*
642  store i32 10, i32* %2
643  %3 = load i32, i32* %2
644  tail call void @free(i8* %1)
645  ret i32 %3
646}
647
648define i32 @test_sle() {
649; CHECK-LABEL: define {{[^@]+}}@test_sle()
650; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 -1)
651; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
652; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
653; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
654; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
655; CHECK-NEXT:    tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
656; CHECK-NEXT:    ret i32 [[TMP3]]
657;
658  %1 = tail call noalias i8* @malloc(i64 -1)
659  tail call void @no_sync_func(i8* %1)
660  %2 = bitcast i8* %1 to i32*
661  store i32 10, i32* %2
662  %3 = load i32, i32* %2
663  tail call void @free(i8* %1)
664  ret i32 %3
665}
666
667define i32 @test_overflow() {
668; CHECK-LABEL: define {{[^@]+}}@test_overflow()
669; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 65537, i64 65537)
670; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
671; CHECK-NEXT:    [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
672; CHECK-NEXT:    store i32 10, i32* [[TMP2]], align 4
673; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
674; CHECK-NEXT:    tail call void @free(i8* noalias nonnull align 4 dereferenceable(4) [[TMP1]])
675; CHECK-NEXT:    ret i32 [[TMP3]]
676;
677  %1 = tail call noalias i8* @calloc(i64 65537, i64 65537)
678  tail call void @no_sync_func(i8* %1)
679  %2 = bitcast i8* %1 to i32*
680  store i32 10, i32* %2
681  %3 = load i32, i32* %2
682  tail call void @free(i8* %1)
683  ret i32 %3
684}
685
686define void @test14() {
687; CHECK-LABEL: define {{[^@]+}}@test14()
688; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 64, i64 4)
689; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
690; CHECK-NEXT:    tail call void @free(i8* noalias [[TMP1]])
691; CHECK-NEXT:    ret void
692;
693  %1 = tail call noalias i8* @calloc(i64 64, i64 4)
694  tail call void @no_sync_func(i8* %1)
695  tail call void @free(i8* %1)
696  ret void
697}
698
699define void @test15(i64 %S) {
700; CHECK-LABEL: define {{[^@]+}}@test15
701; CHECK-SAME: (i64 [[S:%.*]])
702; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]])
703; CHECK-NEXT:    tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
704; CHECK-NEXT:    tail call void @free(i8* noalias [[TMP1]])
705; CHECK-NEXT:    ret void
706;
707  %1 = tail call noalias i8* @malloc(i64 %S)
708  tail call void @no_sync_func(i8* %1)
709  tail call void @free(i8* %1)
710  ret void
711}
712
713define void @test16a(i8 %v, i8** %P) {
714; IS________OPM-LABEL: define {{[^@]+}}@test16a
715; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]])
716; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
717; IS________OPM-NEXT:    store i8 [[V]], i8* [[TMP1]]
718; IS________OPM-NEXT:    tail call void @no_sync_func(i8* noalias nofree nonnull dereferenceable(1) [[TMP1]])
719; IS________OPM-NEXT:    tail call void @free(i8* noalias nonnull dereferenceable(1) [[TMP1]])
720; IS________OPM-NEXT:    ret void
721;
722; IS________NPM-LABEL: define {{[^@]+}}@test16a
723; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone [[P:%.*]])
724; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
725; IS________NPM-NEXT:    store i8 [[V]], i8* [[TMP1]]
726; IS________NPM-NEXT:    tail call void @no_sync_func(i8* noalias nocapture nofree nonnull dereferenceable(1) [[TMP1]])
727; IS________NPM-NEXT:    ret void
728;
729  %1 = tail call noalias i8* @malloc(i64 4)
730  store i8 %v, i8* %1
731  tail call void @no_sync_func(i8* %1)
732  tail call void @free(i8* nonnull dereferenceable(1) %1)
733  ret void
734}
735
736define void @test16b(i8 %v, i8** %P) {
737; IS________OPM-LABEL: define {{[^@]+}}@test16b
738; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
739; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
740; IS________OPM-NEXT:    store i8* [[TMP1]], i8** [[P]]
741; IS________OPM-NEXT:    tail call void @no_sync_func(i8* nofree [[TMP1]])
742; IS________OPM-NEXT:    tail call void @free(i8* [[TMP1]])
743; IS________OPM-NEXT:    ret void
744;
745; IS________NPM-LABEL: define {{[^@]+}}@test16b
746; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
747; IS________NPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
748; IS________NPM-NEXT:    store i8* [[TMP1]], i8** [[P]]
749; IS________NPM-NEXT:    tail call void @no_sync_func(i8* nocapture nofree [[TMP1]])
750; IS________NPM-NEXT:    tail call void @free(i8* [[TMP1]])
751; IS________NPM-NEXT:    ret void
752;
753  %1 = tail call noalias i8* @malloc(i64 4)
754  store i8* %1, i8** %P
755  tail call void @no_sync_func(i8* %1)
756  tail call void @free(i8* %1)
757  ret void
758}
759
760define void @test16c(i8 %v, i8** %P) {
761; IS________OPM-LABEL: define {{[^@]+}}@test16c
762; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
763; IS________OPM-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
764; IS________OPM-NEXT:    store i8* [[TMP1]], i8** [[P]]
765; IS________OPM-NEXT:    tail call void @no_sync_func(i8* nofree [[TMP1]])
766; IS________OPM-NEXT:    tail call void @free(i8* [[TMP1]])
767; IS________OPM-NEXT:    ret void
768;
769; IS________NPM-LABEL: define {{[^@]+}}@test16c
770; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
771; IS________NPM-NEXT:    [[TMP1:%.*]] = alloca i8, i64 4
772; IS________NPM-NEXT:    store i8* [[TMP1]], i8** [[P]]
773; IS________NPM-NEXT:    tail call void @no_sync_func(i8* nocapture nofree [[TMP1]])
774; IS________NPM-NEXT:    ret void
775;
776  %1 = tail call noalias i8* @malloc(i64 4)
777  store i8* %1, i8** %P
778  tail call void @no_sync_func(i8* %1) nounwind
779  tail call void @free(i8* %1)
780  ret void
781}
782
783define void @test16d(i8 %v, i8** %P) {
784; CHECK-LABEL: define {{[^@]+}}@test16d
785; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
786; CHECK-NEXT:    [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
787; CHECK-NEXT:    store i8* [[TMP1]], i8** [[P]]
788; CHECK-NEXT:    ret void
789;
790  %1 = tail call noalias i8* @malloc(i64 4)
791  store i8* %1, i8** %P
792  ret void
793}
794