brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 5a0b6ef Raw
269 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes2; RUN: opt -passes=function-attrs --aa-pipeline=basic-aa --disable-nofree-inference=false -S < %s | FileCheck %s --check-prefix=FNATTR3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"5 6; Test cases specifically designed for the "nofree" function attribute.7; We use FIXME's to indicate problems and missing attributes.8 9; Free functions10declare void @free(ptr nocapture) local_unnamed_addr #111declare noalias ptr @realloc(ptr nocapture, i64) local_unnamed_addr #012declare void @_ZdaPv(ptr) local_unnamed_addr #213 14 15; TEST 1 (positive case)16define void @only_return() #0 {17; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable18; FNATTR-LABEL: define {{[^@]+}}@only_return19; FNATTR-SAME: () #[[ATTR3:[0-9]+]] {20; FNATTR-NEXT:    ret void21;22  ret void23}24 25 26; TEST 2 (negative case)27; Only free28; void only_free(char* p) {29;    free(p);30; }31 32define void @only_free(ptr nocapture %0) local_unnamed_addr #0 {33; FNATTR: Function Attrs: noinline nounwind uwtable34; FNATTR-LABEL: define {{[^@]+}}@only_free35; FNATTR-SAME: (ptr captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {36; FNATTR-NEXT:    tail call void @free(ptr [[TMP0]]) #[[ATTR0:[0-9]+]]37; FNATTR-NEXT:    ret void38;39  tail call void @free(ptr %0) #140  ret void41}42 43 44; TEST 3 (negative case)45; Free occurs in same scc.46; void free_in_scc1(char*p){47;    free_in_scc2(p);48; }49; void free_in_scc2(char*p){50;    free_in_scc1(p);51;    free(p);52; }53 54define void @free_in_scc1(ptr nocapture %0) local_unnamed_addr #0 {55; FNATTR: Function Attrs: noinline nounwind uwtable56; FNATTR-LABEL: define {{[^@]+}}@free_in_scc157; FNATTR-SAME: (ptr captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] {58; FNATTR-NEXT:    tail call void @free_in_scc2(ptr [[TMP0]]) #[[ATTR0]]59; FNATTR-NEXT:    ret void60;61  tail call void @free_in_scc2(ptr %0) #162  ret void63}64 65define void @free_in_scc2(ptr nocapture %0) local_unnamed_addr #0 {66; FNATTR: Function Attrs: noinline nounwind uwtable67; FNATTR-LABEL: define {{[^@]+}}@free_in_scc268; FNATTR-SAME: (ptr captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] {69; FNATTR-NEXT:    [[CMP:%.*]] = icmp eq ptr [[TMP0]], null70; FNATTR-NEXT:    br i1 [[CMP]], label [[REC:%.*]], label [[CALL:%.*]]71; FNATTR:       call:72; FNATTR-NEXT:    tail call void @free(ptr [[TMP0]]) #[[ATTR0]]73; FNATTR-NEXT:    br label [[END:%.*]]74; FNATTR:       rec:75; FNATTR-NEXT:    tail call void @free_in_scc1(ptr [[TMP0]])76; FNATTR-NEXT:    br label [[END]]77; FNATTR:       end:78; FNATTR-NEXT:    ret void79;80  %cmp = icmp eq ptr %0, null81  br i1 %cmp, label %rec, label %call82call:83  tail call void @free(ptr %0) #184  br label %end85rec:86  tail call void @free_in_scc1(ptr %0)87  br label %end88end:89  ret void90}91 92 93; TEST 4 (positive case)94; Free doesn't occur.95; void mutual_recursion1(){96;    mutual_recursion2();97; }98; void mutual_recursion2(){99;     mutual_recursion1();100; }101 102 103define void @mutual_recursion1() #0 {104; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable105; FNATTR-LABEL: define {{[^@]+}}@mutual_recursion1106; FNATTR-SAME: () #[[ATTR4:[0-9]+]] {107; FNATTR-NEXT:    call void @mutual_recursion2()108; FNATTR-NEXT:    ret void109;110  call void @mutual_recursion2()111  ret void112}113 114define void @mutual_recursion2() #0 {115; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable116; FNATTR-LABEL: define {{[^@]+}}@mutual_recursion2117; FNATTR-SAME: () #[[ATTR4]] {118; FNATTR-NEXT:    call void @mutual_recursion1()119; FNATTR-NEXT:    ret void120;121  call void @mutual_recursion1()122  ret void123}124 125 126; TEST 5127; C++ delete operation (negative case)128; void delete_op (char p[]){129;     delete [] p;130; }131 132define void @_Z9delete_opPc(ptr %0) local_unnamed_addr #0 {133; FNATTR: Function Attrs: noinline nounwind uwtable134; FNATTR-LABEL: define {{[^@]+}}@_Z9delete_opPc135; FNATTR-SAME: (ptr [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] {136; FNATTR-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[TMP0]], null137; FNATTR-NEXT:    br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]138; FNATTR:       3:139; FNATTR-NEXT:    tail call void @_ZdaPv(ptr nonnull [[TMP0]]) #[[ATTR2:[0-9]+]]140; FNATTR-NEXT:    br label [[TMP4]]141; FNATTR:       4:142; FNATTR-NEXT:    ret void143;144  %2 = icmp eq ptr %0, null145  br i1 %2, label %4, label %3146 147; <label>:3:                                      ; preds = %1148  tail call void @_ZdaPv(ptr nonnull %0) #2149  br label %4150 151; <label>:4:                                      ; preds = %3, %1152  ret void153}154 155 156; TEST 6 (negative case)157; Call realloc158define noalias ptr @call_realloc(ptr nocapture %0, i64 %1) local_unnamed_addr #0 {159; FNATTR: Function Attrs: noinline nounwind uwtable160; FNATTR-LABEL: define {{[^@]+}}@call_realloc161; FNATTR-SAME: (ptr captures(none) [[TMP0:%.*]], i64 [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] {162; FNATTR-NEXT:    [[RET:%.*]] = tail call ptr @realloc(ptr [[TMP0]], i64 [[TMP1]]) #[[ATTR2]]163; FNATTR-NEXT:    ret ptr [[RET]]164;165  %ret = tail call ptr @realloc(ptr %0, i64 %1) #2166  ret ptr %ret167}168 169 170; TEST 7 (positive case)171; Call function declaration with "nofree"172 173 174declare void @nofree_function() nofree readnone #0175 176define void @call_nofree_function() #0 {177; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable178; FNATTR-LABEL: define {{[^@]+}}@call_nofree_function179; FNATTR-SAME: () #[[ATTR4]] {180; FNATTR-NEXT:    tail call void @nofree_function()181; FNATTR-NEXT:    ret void182;183  tail call void @nofree_function()184  ret void185}186 187; TEST 8 (negative case)188; Call function declaration without "nofree"189 190 191declare void @maybe_free() #0192 193 194define void @call_maybe_free() #0 {195; FNATTR: Function Attrs: noinline nounwind uwtable196; FNATTR-LABEL: define {{[^@]+}}@call_maybe_free197; FNATTR-SAME: () #[[ATTR1]] {198; FNATTR-NEXT:    tail call void @maybe_free()199; FNATTR-NEXT:    ret void200;201  tail call void @maybe_free()202  ret void203}204 205 206; TEST 9 (negative case)207; Call both of above functions208 209define void @call_both() #0 {210; FNATTR: Function Attrs: noinline nounwind uwtable211; FNATTR-LABEL: define {{[^@]+}}@call_both212; FNATTR-SAME: () #[[ATTR1]] {213; FNATTR-NEXT:    tail call void @maybe_free()214; FNATTR-NEXT:    tail call void @nofree_function()215; FNATTR-NEXT:    ret void216;217  tail call void @maybe_free()218  tail call void @nofree_function()219  ret void220}221 222 223; TEST 10 (positive case)224; Call intrinsic function225declare float @llvm.floor.f32(float)226 227define void @call_floor(float %a) #0 {228; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(none) uwtable229; FNATTR-LABEL: define {{[^@]+}}@call_floor230; FNATTR-SAME: (float [[A:%.*]]) #[[ATTR3]] {231; FNATTR-NEXT:    [[TMP1:%.*]] = tail call float @llvm.floor.f32(float [[A]])232; FNATTR-NEXT:    ret void233;234  tail call float @llvm.floor.f32(float %a)235  ret void236}237 238; TEST 11 (positive case)239; Check propagation.240 241define void @f1() #0 {242; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable243; FNATTR-LABEL: define {{[^@]+}}@f1244; FNATTR-SAME: () #[[ATTR4]] {245; FNATTR-NEXT:    tail call void @nofree_function()246; FNATTR-NEXT:    ret void247;248  tail call void @nofree_function()249  ret void250}251 252define void @f2() #0 {253; FNATTR: Function Attrs: nofree noinline nosync nounwind memory(none) uwtable254; FNATTR-LABEL: define {{[^@]+}}@f2255; FNATTR-SAME: () #[[ATTR4]] {256; FNATTR-NEXT:    tail call void @f1()257; FNATTR-NEXT:    ret void258;259  tail call void @f1()260  ret void261}262 263 264declare noalias ptr @malloc(i64)265 266attributes #0 = { nounwind uwtable noinline }267attributes #1 = { nounwind }268attributes #2 = { nobuiltin nounwind }269