[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / Transforms / FunctionAttrs / heap_to_stack.ll
blob876760a8051581117073eadf7b051f0ccfb3e5df
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   ; CHECK: alloca i8, i64 4
219   ; CHECK-NEXT: %3 = bitcast
220   %2 = call noalias i8* @malloc(i64 4)
221   %3 = bitcast i8* %2 to i32*
222   store i32 10, i32* %3, align 4
223   %4 = icmp eq i32 %0, 1
224   br i1 %4, label %5, label %7
226 5:                                                ; preds = %1
227   %6 = add nsw i32 %0, 5
228   br label %13
230 7:                                                ; preds = %1
231   br label %8
233 8:                                                ; preds = %13, %7
234   %.0 = phi i32 [ %14, %13 ], [ 1, %7 ]
235   %9 = load i32, i32* %3, align 4
236   %10 = add nsw i32 %9, -1
237   store i32 %10, i32* %3, align 4
238   %11 = icmp ne i32 %9, 0
239   br i1 %11, label %12, label %15
241 12:                                               ; preds = %8
242   br label %13
244 13:                                               ; preds = %12, %5
245   %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ]
246   %14 = add nsw i32 %.1, 1
247   br label %8
249 15:                                               ; preds = %8
250   %16 = load i32, i32* %3, align 4
251   %17 = bitcast i32* %3 to i8*
252   call void @free(i8* %17)
253   %18 = load i32, i32* %3, align 4
254   ret i32 %18
258 define i32 @malloc_in_loop(i32 %0) {
259   %2 = alloca i32, align 4
260   %3 = alloca i32*, align 8
261   store i32 %0, i32* %2, align 4
262   br label %4
264 4:                                                ; preds = %8, %1
265   %5 = load i32, i32* %2, align 4
266   %6 = add nsw i32 %5, -1
267   store i32 %6, i32* %2, align 4
268   %7 = icmp sgt i32 %6, 0
269   br i1 %7, label %8, label %11
271 8:                                                ; preds = %4
272   %9 = call noalias i8* @malloc(i64 4)
273   ; CHECK: alloca i8, i64 4
274   %10 = bitcast i8* %9 to i32*
275   store i32 1, i32* %10, align 8
276   br label %4
278 11:                                               ; preds = %4
279   ret i32 5
282 ; Malloc/Calloc too large
283 define i32 @test13() {
284   %1 = tail call noalias i8* @malloc(i64 256)
285   ; CHECK: %1 = tail call noalias i8* @malloc(i64 256)
286   ; CHECK-NEXT: @no_sync_func(i8* noalias %1)
287   tail call void @no_sync_func(i8* %1)
288   %2 = bitcast i8* %1 to i32*
289   store i32 10, i32* %2
290   %3 = load i32, i32* %2
291   tail call void @free(i8* %1)
292   ; CHECK: tail call void @free(i8* noalias %1)
293   ret i32 %3
296 define void @test14() {
297   %1 = tail call noalias i8* @calloc(i64 64, i64 4)
298   ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4)
299   ; CHECK-NEXT: @no_sync_func(i8* noalias %1)
300   tail call void @no_sync_func(i8* %1)
301   tail call void @free(i8* %1)
302   ; CHECK: tail call void @free(i8* noalias %1)
303   ret void
306 define void @test15(i64 %S) {
307   ; CHECK: %1 = tail call noalias i8* @malloc(i64 %S)
308   %1 = tail call noalias i8* @malloc(i64 %S)
309   ; CHECK-NEXT: @no_sync_func(i8* noalias %1)
310   tail call void @no_sync_func(i8* %1)
311   ; CHECK-NEXT: @free(i8* noalias %1)
312   tail call void @free(i8* %1)
313   ret void
316 define void @test16a(i8 %v, i8** %P) {
317   ; CHECK: %1 = alloca
318   %1 = tail call noalias i8* @malloc(i64 4)
319   ; CHECK-NEXT: store i8 %v, i8* %1
320   store i8 %v, i8* %1
321   ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture %1)
322   tail call void @no_sync_func(i8* %1)
323   ; CHECK-NOT: @free(i8* %1)
324   tail call void @free(i8* %1)
325   ret void
328 define void @test16b(i8 %v, i8** %P) {
329   ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
330   %1 = tail call noalias i8* @malloc(i64 4)
331   ; CHECK-NEXT: store i8* %1, i8** %P
332   store i8* %1, i8** %P
333   ; CHECK-NEXT: @no_sync_func(i8* %1)
334   tail call void @no_sync_func(i8* %1)
335   ; CHECK-NEXT: @free(i8* %1)
336   tail call void @free(i8* %1)
337   ret void