[llvm-readobj] - Simplify stack-sizes.test test case.
[llvm-complete.git] / test / Transforms / FunctionAttrs / heap_to_stack.ll
blob26a778be841ab453af0d90cfb780bbdb9c6686cf
1 ; RUN: opt -passes=attributor --attributor-disable=false -S < %s | FileCheck %s
3 declare noalias i8* @malloc(i64)
5 declare void @nocapture_func_frees_pointer(i8* nocapture)
7 declare void @func_throws(...)
9 declare void @sync_func(i8* %p)
11 declare void @sync_will_return(i8* %p) willreturn
13 declare void @no_sync_func(i8* nocapture %p) nofree nosync willreturn
15 declare void @nofree_func(i8* nocapture %p) nofree  nosync willreturn
17 declare void @foo(i32* %p)
19 declare void @foo_nounw(i32* %p) nounwind nofree
21 declare i32 @no_return_call() noreturn
23 declare void @free(i8* nocapture)
25 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
27 ; TEST 1 - negative, pointer freed in another function.
29 define void @test1() {
30   %1 = tail call noalias i8* @malloc(i64 4)
31   ; CHECK: @malloc(i64 4)
32   ; CHECK-NEXT: @nocapture_func_frees_pointer(i8* noalias nocapture %1)
33   tail call void @nocapture_func_frees_pointer(i8* %1)
34   tail call void (...) @func_throws()
35   tail call void @free(i8* %1)
36   ret void
39 ; TEST 2 - negative, call to a sync function.
41 define void @test2() {
42   %1 = tail call noalias i8* @malloc(i64 4)
43   ; CHECK: @malloc(i64 4)
44   ; CHECK-NEXT: @sync_func(i8* %1)
45   tail call void @sync_func(i8* %1)
46   tail call void @free(i8* %1)
47   ret void
50 ; TEST 3 - 1 malloc, 1 free
52 define void @test3() {
53   %1 = tail call noalias i8* @malloc(i64 4)
54   ; CHECK: %1 = alloca i8, i64 4
55   ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture %1)
56   tail call void @no_sync_func(i8* %1)
57   ; CHECK-NOT: @free(i8* %1)
58   tail call void @free(i8* %1)
59   ret void
62 declare noalias i8* @calloc(i64, i64)
64 define void @test0() {
65   %1 = tail call noalias i8* @calloc(i64 2, i64 4)
66   ; CHECK: %1 = alloca i8, i64 8
67   ; CHECK-NEXT: %calloc_bc = bitcast i8* %1 to i8*
68   ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %calloc_bc, i8 0, i64 8, i1 false)
69   ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture %1)
70   tail call void @no_sync_func(i8* %1)
71   ; CHECK-NOT: @free(i8* %1)
72   tail call void @free(i8* %1)
73   ret void
76 ; TEST 4 
77 define void @test4() {
78   %1 = tail call noalias i8* @malloc(i64 4)
79   ; CHECK: %1 = alloca i8, i64 4
80   ; CHECK-NEXT: @nofree_func(i8* noalias nocapture %1)
81   tail call void @nofree_func(i8* %1)
82   ret void
85 ; TEST 5 - not all exit paths have a call to free, but all uses of malloc
86 ; are in nofree functions and are not captured
88 define void @test5(i32) {
89   %2 = tail call noalias i8* @malloc(i64 4)
90   ; CHECK: %2 = alloca i8, i64 4
91   ; CHECK-NEXT: icmp eq i32 %0, 0
92   %3 = icmp eq i32 %0, 0
93   br i1 %3, label %5, label %4
95 4:                                                ; preds = %1
96   tail call void @nofree_func(i8* %2)
97   br label %6
99 5:                                                ; preds = %1
100   tail call void @free(i8* %2)
101   ; CHECK-NOT: @free(i8* %2)
102   br label %6
104 6:                                                ; preds = %5, %4
105   ret void
108 ; TEST 6 - all exit paths have a call to free
110 define void @test6(i32) {
111   %2 = tail call noalias i8* @malloc(i64 4)
112   ; CHECK: %2 = alloca i8, i64 4
113   ; CHECK-NEXT: icmp eq i32 %0, 0
114   %3 = icmp eq i32 %0, 0
115   br i1 %3, label %5, label %4
117 4:                                                ; preds = %1
118   tail call void @nofree_func(i8* %2)
119   tail call void @free(i8* %2)
120   ; CHECK-NOT: @free(i8* %2)
121   br label %6
123 5:                                                ; preds = %1
124   tail call void @free(i8* %2)
125   ; CHECK-NOT: @free(i8* %2)
126   br label %6
128 6:                                                ; preds = %5, %4
129   ret void
132 ; TEST 7 - free is dead.
134 define void @test7() {
135   %1 = tail call noalias i8* @malloc(i64 4)
136   ; CHECK: alloca i8, i64 4
137   ; CHECK-NEXT: tail call i32 @no_return_call()
138   tail call i32 @no_return_call()
139   ; CHECK-NOT: @free(i8* %1)
140   tail call void @free(i8* %1)
141   ret void
144 ; TEST 8 - Negative: bitcast pointer used in capture function
146 define void @test8() {
147   %1 = tail call noalias i8* @malloc(i64 4)
148   ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
149   ; CHECK-NEXT: @no_sync_func(i8* nocapture %1)
150   tail call void @no_sync_func(i8* %1)
151   %2 = bitcast i8* %1 to i32*
152   store i32 10, i32* %2
153   %3 = load i32, i32* %2
154   tail call void @foo(i32* %2)
155   ; CHECK: @free(i8* %1)
156   tail call void @free(i8* %1)
157   ret void
160 ; TEST 9 - FIXME: malloc should be converted.
161 define void @test9() {
162   %1 = tail call noalias i8* @malloc(i64 4)
163   ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
164   ; CHECK-NEXT: @no_sync_func(i8* nocapture %1)
165   tail call void @no_sync_func(i8* %1)
166   %2 = bitcast i8* %1 to i32*
167   store i32 10, i32* %2
168   %3 = load i32, i32* %2
169   tail call void @foo_nounw(i32* %2)
170   ; CHECK: @free(i8* %1)
171   tail call void @free(i8* %1)
172   ret void
175 ; TEST 10 - 1 malloc, 1 free
177 define i32 @test10() {
178   %1 = tail call noalias i8* @malloc(i64 4)
179   ; CHECK: %1 = alloca i8, i64 4
180   ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture %1)
181   tail call void @no_sync_func(i8* %1)
182   %2 = bitcast i8* %1 to i32*
183   store i32 10, i32* %2
184   %3 = load i32, i32* %2
185   ; CHECK-NOT: @free(i8* %1)
186   tail call void @free(i8* %1)
187   ret i32 %3
190 define i32 @test_lifetime() {
191   %1 = tail call noalias i8* @malloc(i64 4)
192   ; CHECK: %1 = alloca i8, i64 4
193   ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture %1)
194   tail call void @no_sync_func(i8* %1)
195   call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
196   %2 = bitcast i8* %1 to i32*
197   store i32 10, i32* %2
198   %3 = load i32, i32* %2
199   ; CHECK-NOT: @free(i8* %1)
200   tail call void @free(i8* %1)
201   ret i32 %3
204 ; TEST 11 
205 ; FIXME: should be ok
207 define void @test11() {
208   %1 = tail call noalias i8* @malloc(i64 4)
209   ; CHECK: @malloc(i64 4)
210   ; CHECK-NEXT: @sync_will_return(i8* %1)
211   tail call void @sync_will_return(i8* %1)
212   tail call void @free(i8* %1)
213   ret void
216 ; TEST 12
217 define i32 @irreducible_cfg(i32 %0) {
218   %2 = alloca i32, align 4
219   %3 = alloca i32*, align 8
220   %4 = alloca i32, align 4
221   store i32 %0, i32* %2, align 4
222   %5 = call noalias i8* @malloc(i64 4) #2
223   ; CHECK: alloca i8, i64 4
224   ; CHECK-NEXT: %6 = bitcast
225   %6 = bitcast i8* %5 to i32*
226   store i32* %6, i32** %3, align 8
227   %7 = load i32*, i32** %3, align 8
228   store i32 10, i32* %7, align 4
229   %8 = load i32, i32* %2, align 4
230   %9 = icmp eq i32 %8, 1
231   br i1 %9, label %10, label %13
233 10:                                               ; preds = %1
234   %11 = load i32, i32* %2, align 4
235   %12 = add nsw i32 %11, 5
236   store i32 %12, i32* %2, align 4
237   br label %20
239 13:                                               ; preds = %1
240   store i32 1, i32* %2, align 4
241   br label %14
243 14:                                               ; preds = %20, %13
244   %15 = load i32*, i32** %3, align 8
245   %16 = load i32, i32* %15, align 4
246   %17 = add nsw i32 %16, -1
247   store i32 %17, i32* %15, align 4
248   %18 = icmp ne i32 %16, 0
249   br i1 %18, label %19, label %23
251 19:                                               ; preds = %14
252   br label %20
254 20:                                               ; preds = %19, %10
255   %21 = load i32, i32* %2, align 4
256   %22 = add nsw i32 %21, 1
257   store i32 %22, i32* %2, align 4
258   br label %14
260 23:                                               ; preds = %14
261   %24 = load i32*, i32** %3, align 8
262   %25 = load i32, i32* %24, align 4
263   store i32 %25, i32* %4, align 4
264   %26 = load i32*, i32** %3, align 8
265   %27 = bitcast i32* %26 to i8*
266   call void @free(i8* %27) #2
267   %28 = load i32*, i32** %3, align 8
268   %29 = load i32, i32* %28, align 4
269   ret i32 %29
272 define i32 @malloc_in_loop(i32 %0) {
273   %2 = alloca i32, align 4
274   %3 = alloca i32*, align 8
275   store i32 %0, i32* %2, align 4
276   br label %4
278 4:                                                ; preds = %8, %1
279   %5 = load i32, i32* %2, align 4
280   %6 = add nsw i32 %5, -1
281   store i32 %6, i32* %2, align 4
282   %7 = icmp sgt i32 %6, 0
283   br i1 %7, label %8, label %11
285 8:                                                ; preds = %4
286   %9 = call noalias i8* @malloc(i64 4)
287   ; CHECK: alloca i8, i64 4
288   %10 = bitcast i8* %9 to i32*
289   store i32* %10, i32** %3, align 8
290   br label %4
292 11:                                               ; preds = %4
293   ret i32 5
296 ; Malloc/Calloc too large
297 define i32 @test13() {
298   %1 = tail call noalias i8* @malloc(i64 256)
299   ; CHECK: %1 = tail call noalias i8* @malloc(i64 256)
300   ; CHECK-NEXT: @no_sync_func(i8* noalias %1)
301   tail call void @no_sync_func(i8* %1)
302   %2 = bitcast i8* %1 to i32*
303   store i32 10, i32* %2
304   %3 = load i32, i32* %2
305   tail call void @free(i8* %1)
306   ; CHECK: tail call void @free(i8* noalias %1)
307   ret i32 %3
310 define void @test14() {
311   %1 = tail call noalias i8* @calloc(i64 64, i64 4)
312   ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4)
313   ; CHECK-NEXT: @no_sync_func(i8* noalias %1)
314   tail call void @no_sync_func(i8* %1)
315   tail call void @free(i8* %1)
316   ; CHECK: tail call void @free(i8* noalias %1)
317   ret void