1 ; RUN: opt -enable-new-pm=1 -function-attrs --disable-nofree-inference=false -S < %s | FileCheck %s --check-prefix=FNATTR
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 ; Test cases specifically designed for the "nofree" function attribute.
6 ; We use FIXME's to indicate problems and missing attributes.
9 declare void @free(i8* nocapture) local_unnamed_addr #1
10 declare noalias i8* @realloc(i8* nocapture, i64) local_unnamed_addr #0
11 declare void @_ZdaPv(i8*) local_unnamed_addr #2
14 ; TEST 1 (positive case)
15 ; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone uwtable
16 ; FNATTR-NEXT: define void @only_return()
17 define void @only_return() #0 {
22 ; TEST 2 (negative case)
24 ; void only_free(char* p) {
28 ; FNATTR: Function Attrs: noinline nounwind uwtable
29 ; FNATTR-NEXT: define void @only_free(i8* nocapture %0) local_unnamed_addr
30 define void @only_free(i8* nocapture %0) local_unnamed_addr #0 {
31 tail call void @free(i8* %0) #1
36 ; TEST 3 (negative case)
37 ; Free occurs in same scc.
38 ; void free_in_scc1(char*p){
41 ; void free_in_scc2(char*p){
47 ; FNATTR: Function Attrs: noinline nounwind uwtable
48 ; FNATTR-NEXT: define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr
49 define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 {
50 tail call void @free_in_scc2(i8* %0) #1
55 ; FNATTR: Function Attrs: noinline nounwind uwtable
56 ; FNATTR-NEXT: define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr
57 define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr #0 {
58 %cmp = icmp eq i8* %0, null
59 br i1 %cmp, label %rec, label %call
61 tail call void @free(i8* %0) #1
64 tail call void @free_in_scc1(i8* %0)
71 ; TEST 4 (positive case)
73 ; void mutual_recursion1(){
74 ; mutual_recursion2();
76 ; void mutual_recursion2(){
77 ; mutual_recursion1();
81 ; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
82 ; FNATTR-NEXT: define void @mutual_recursion1()
83 define void @mutual_recursion1() #0 {
84 call void @mutual_recursion2()
88 ; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
89 ; FNATTR-NEXT: define void @mutual_recursion2()
90 define void @mutual_recursion2() #0 {
91 call void @mutual_recursion1()
97 ; C++ delete operation (negative case)
98 ; void delete_op (char p[]){
102 ; FNATTR: Function Attrs: noinline nounwind uwtable
103 ; FNATTR-NEXT: define void @_Z9delete_opPc(i8* %0) local_unnamed_addr
104 define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 {
105 %2 = icmp eq i8* %0, null
106 br i1 %2, label %4, label %3
108 ; <label>:3: ; preds = %1
109 tail call void @_ZdaPv(i8* nonnull %0) #2
112 ; <label>:4: ; preds = %3, %1
117 ; TEST 6 (negative case)
119 ; FNATTR: Function Attrs: noinline nounwind uwtable
120 ; FNATTR-NEXT: define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr
121 define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0 {
122 %ret = tail call i8* @realloc(i8* %0, i64 %1) #2
127 ; TEST 7 (positive case)
128 ; Call function declaration with "nofree"
131 ; FNATTR: Function Attrs: nofree noinline nounwind readnone uwtable
132 ; FNATTR-NEXT: declare void @nofree_function()
133 declare void @nofree_function() nofree readnone #0
135 ; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
136 ; FNATTR-NEXT: define void @call_nofree_function()
137 define void @call_nofree_function() #0 {
138 tail call void @nofree_function()
142 ; TEST 8 (negative case)
143 ; Call function declaration without "nofree"
146 declare void @maybe_free() #0
149 ; FNATTR: Function Attrs: noinline nounwind uwtable
150 ; FNATTR: define void @call_maybe_free()
151 define void @call_maybe_free() #0 {
152 tail call void @maybe_free()
157 ; TEST 9 (negative case)
158 ; Call both of above functions
160 ; FNATTR: Function Attrs: noinline nounwind uwtable
161 ; FNATTR-NEXT: define void @call_both()
162 define void @call_both() #0 {
163 tail call void @maybe_free()
164 tail call void @nofree_function()
169 ; TEST 10 (positive case)
170 ; Call intrinsic function
171 ; FNATTRS: Function Attrs: nofree noinline nosync readnone speculatable
172 ; FNATTRS-NEXT: declare float @llvm.floor.f32(float %0)
173 declare float @llvm.floor.f32(float)
175 ; FNATTRS: Function Attrs: noinline nounwind uwtable
176 ; FNATTRS-NEXT: define void @call_floor(float %a)
177 ; FIXME: missing nofree
179 define void @call_floor(float %a) #0 {
180 tail call float @llvm.floor.f32(float %a)
184 ; TEST 11 (positive case)
187 ; FNATTRS: Function Attrs: noinline nounwind uwtable
188 ; FNATTRS-NEXT: define void @f1()
189 define void @f1() #0 {
190 tail call void @nofree_function()
194 ; FNATTRS: Function Attrs: noinline nounwind uwtable
195 ; FNATTRS-NEXT: define void @f2()
196 define void @f2() #0 {
202 declare noalias i8* @malloc(i64)
204 attributes #0 = { nounwind uwtable noinline }
205 attributes #1 = { nounwind }
206 attributes #2 = { nobuiltin nounwind }