From 45e595880a7c596bd2756ae7c9ec8d16dd8be6d0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 13 Oct 2022 10:31:07 +0200 Subject: [PATCH] [FunctionAttrs] Regenerate test checks (NFC) --- llvm/test/Transforms/FunctionAttrs/convergent.ll | 116 ++++++++------ .../Transforms/FunctionAttrs/nofree-attributor.ll | 170 ++++++++++++++------- llvm/test/Transforms/FunctionAttrs/norecurse.ll | 145 +++++++++++------- 3 files changed, 277 insertions(+), 154 deletions(-) diff --git a/llvm/test/Transforms/FunctionAttrs/convergent.ll b/llvm/test/Transforms/FunctionAttrs/convergent.ll index 277b1de..e31a80b 100644 --- a/llvm/test/Transforms/FunctionAttrs/convergent.ll +++ b/llvm/test/Transforms/FunctionAttrs/convergent.ll @@ -1,107 +1,131 @@ -; RUN: opt -function-attrs -S < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt -passes=function-attrs -S < %s | FileCheck %s -; CHECK: Function Attrs -; CHECK-NOT: convergent -; CHECK-NEXT: define i32 @nonleaf() define i32 @nonleaf() convergent { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: define {{[^@]+}}@nonleaf +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @leaf() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @leaf() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NOT: convergent -; CHECK-NEXT: define i32 @leaf() define i32 @leaf() convergent { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: define {{[^@]+}}@leaf +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: ret i32 0 +; ret i32 0 } -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: declare i32 @k() declare i32 @k() convergent -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: define i32 @extern() define i32 @extern() convergent { +; CHECK: Function Attrs: convergent +; CHECK-LABEL: define {{[^@]+}}@extern +; CHECK-SAME: () #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @k() #[[ATTR1]] +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @k() convergent ret i32 %a } ; Convergent should not be removed on the function here. Although the call is ; not explicitly convergent, it picks up the convergent attr from the callee. -; -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: define i32 @extern_non_convergent_call() define i32 @extern_non_convergent_call() convergent { +; CHECK: Function Attrs: convergent +; CHECK-LABEL: define {{[^@]+}}@extern_non_convergent_call +; CHECK-SAME: () #[[ATTR1]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @k() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @k() ret i32 %a } -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: define i32 @indirect_convergent_call( define i32 @indirect_convergent_call(i32 ()* %f) convergent { - %a = call i32 %f() convergent - ret i32 %a +; CHECK: Function Attrs: convergent +; CHECK-LABEL: define {{[^@]+}}@indirect_convergent_call +; CHECK-SAME: (i32 ()* nocapture readonly [[F:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[A:%.*]] = call i32 [[F]]() #[[ATTR1]] +; CHECK-NEXT: ret i32 [[A]] +; + %a = call i32 %f() convergent + ret i32 %a } ; Give indirect_non_convergent_call the norecurse attribute so we get a ; "Function Attrs" comment in the output. -; -; CHECK: Function Attrs -; CHECK-NOT: convergent -; CHECK-NEXT: define i32 @indirect_non_convergent_call( define i32 @indirect_non_convergent_call(i32 ()* %f) convergent norecurse { - %a = call i32 %f() - ret i32 %a +; CHECK: Function Attrs: norecurse +; CHECK-LABEL: define {{[^@]+}}@indirect_non_convergent_call +; CHECK-SAME: (i32 ()* nocapture readonly [[F:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 [[F]]() +; CHECK-NEXT: ret i32 [[A]] +; + %a = call i32 %f() + ret i32 %a } -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: declare void @llvm.nvvm.barrier0() declare void @llvm.nvvm.barrier0() convergent -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: define i32 @intrinsic() define i32 @intrinsic() convergent { ; Implicitly convergent, because the intrinsic is convergent. +; CHECK: Function Attrs: convergent nounwind +; CHECK-LABEL: define {{[^@]+}}@intrinsic +; CHECK-SAME: () #[[ATTR4:[0-9]+]] { +; CHECK-NEXT: call void @llvm.nvvm.barrier0() +; CHECK-NEXT: ret i32 0 +; call void @llvm.nvvm.barrier0() ret i32 0 } -; CHECK: Function Attrs -; CHECK-NOT: convergent -; CHECK-NEXT: define i32 @recursive1() define i32 @recursive1() convergent { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@recursive1 +; CHECK-SAME: () #[[ATTR5:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @recursive2() #[[ATTR1]] +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @recursive2() convergent ret i32 %a } -; CHECK: Function Attrs -; CHECK-NOT: convergent -; CHECK-NEXT: define i32 @recursive2() define i32 @recursive2() convergent { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@recursive2 +; CHECK-SAME: () #[[ATTR5]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @recursive1() #[[ATTR1]] +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @recursive1() convergent ret i32 %a } -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: define i32 @noopt() define i32 @noopt() convergent optnone noinline { +; CHECK: Function Attrs: convergent noinline optnone +; CHECK-LABEL: define {{[^@]+}}@noopt +; CHECK-SAME: () #[[ATTR6:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @noopt_friend() #[[ATTR1]] +; CHECK-NEXT: ret i32 0 +; %a = call i32 @noopt_friend() convergent ret i32 0 } ; A function which is mutually-recursive with a convergent, optnone function ; shouldn't have its convergent attribute stripped. -; CHECK: Function Attrs -; CHECK-SAME: convergent -; CHECK-NEXT: define i32 @noopt_friend() define i32 @noopt_friend() convergent { +; CHECK: Function Attrs: convergent +; CHECK-LABEL: define {{[^@]+}}@noopt_friend +; CHECK-SAME: () #[[ATTR1]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @noopt() +; CHECK-NEXT: ret i32 0 +; %a = call i32 @noopt() ret i32 0 } diff --git a/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll b/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll index 25b6d1d..a824a40 100644 --- a/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll +++ b/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt -passes=function-attrs --aa-pipeline=basic-aa --disable-nofree-inference=false -S < %s | FileCheck %s --check-prefix=FNATTR target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -12,10 +13,13 @@ declare void @_ZdaPv(i8*) local_unnamed_addr #2 ; TEST 1 (positive case) -; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable -; FNATTR-NEXT: define void @only_return() define void @only_return() #0 { - ret void +; FNATTR: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable +; FNATTR-LABEL: define {{[^@]+}}@only_return +; FNATTR-SAME: () #[[ATTR3:[0-9]+]] { +; FNATTR-NEXT: ret void +; + ret void } @@ -25,11 +29,15 @@ define void @only_return() #0 { ; free(p); ; } -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR-NEXT: define void @only_free(i8* nocapture %0) local_unnamed_addr define void @only_free(i8* nocapture %0) local_unnamed_addr #0 { - tail call void @free(i8* %0) #1 - ret void +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@only_free +; FNATTR-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +; FNATTR-NEXT: tail call void @free(i8* [[TMP0]]) #[[ATTR0:[0-9]+]] +; FNATTR-NEXT: ret void +; + tail call void @free(i8* %0) #1 + ret void } @@ -43,18 +51,32 @@ define void @only_free(i8* nocapture %0) local_unnamed_addr #0 { ; free(p); ; } - -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR-NEXT: define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 { +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@free_in_scc1 +; FNATTR-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] { +; FNATTR-NEXT: tail call void @free_in_scc2(i8* [[TMP0]]) #[[ATTR0]] +; FNATTR-NEXT: ret void +; tail call void @free_in_scc2(i8* %0) #1 ret void } - -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR-NEXT: define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr #0 { +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@free_in_scc2 +; FNATTR-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] { +; FNATTR-NEXT: [[CMP:%.*]] = icmp eq i8* [[TMP0]], null +; FNATTR-NEXT: br i1 [[CMP]], label [[REC:%.*]], label [[CALL:%.*]] +; FNATTR: call: +; FNATTR-NEXT: tail call void @free(i8* [[TMP0]]) #[[ATTR0]] +; FNATTR-NEXT: br label [[END:%.*]] +; FNATTR: rec: +; FNATTR-NEXT: tail call void @free_in_scc1(i8* [[TMP0]]) +; FNATTR-NEXT: br label [[END]] +; FNATTR: end: +; FNATTR-NEXT: ret void +; %cmp = icmp eq i8* %0, null br i1 %cmp, label %rec, label %call call: @@ -78,16 +100,24 @@ end: ; } -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; FNATTR-NEXT: define void @mutual_recursion1() define void @mutual_recursion1() #0 { +; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR-LABEL: define {{[^@]+}}@mutual_recursion1 +; FNATTR-SAME: () #[[ATTR4:[0-9]+]] { +; FNATTR-NEXT: call void @mutual_recursion2() +; FNATTR-NEXT: ret void +; call void @mutual_recursion2() ret void } -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; FNATTR-NEXT: define void @mutual_recursion2() define void @mutual_recursion2() #0 { +; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR-LABEL: define {{[^@]+}}@mutual_recursion2 +; FNATTR-SAME: () #[[ATTR4]] { +; FNATTR-NEXT: call void @mutual_recursion1() +; FNATTR-NEXT: ret void +; call void @mutual_recursion1() ret void } @@ -99,9 +129,18 @@ define void @mutual_recursion2() #0 { ; delete [] p; ; } -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR-NEXT: define void @_Z9delete_opPc(i8* %0) local_unnamed_addr define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 { +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@_Z9delete_opPc +; FNATTR-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr #[[ATTR1]] { +; FNATTR-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null +; FNATTR-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]] +; FNATTR: 3: +; FNATTR-NEXT: tail call void @_ZdaPv(i8* nonnull [[TMP0]]) #[[ATTR2:[0-9]+]] +; FNATTR-NEXT: br label [[TMP4]] +; FNATTR: 4: +; FNATTR-NEXT: ret void +; %2 = icmp eq i8* %0, null br i1 %2, label %4, label %3 @@ -116,11 +155,15 @@ define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 { ; TEST 6 (negative case) ; Call realloc -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR-NEXT: define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0 { - %ret = tail call i8* @realloc(i8* %0, i64 %1) #2 - ret i8* %ret +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@call_realloc +; FNATTR-SAME: (i8* nocapture [[TMP0:%.*]], i64 [[TMP1:%.*]]) local_unnamed_addr #[[ATTR1]] { +; FNATTR-NEXT: [[RET:%.*]] = tail call i8* @realloc(i8* [[TMP0]], i64 [[TMP1]]) #[[ATTR2]] +; FNATTR-NEXT: ret i8* [[RET]] +; + %ret = tail call i8* @realloc(i8* %0, i64 %1) #2 + ret i8* %ret } @@ -128,15 +171,17 @@ define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0 ; Call function declaration with "nofree" -; FNATTR: Function Attrs: nofree noinline nounwind readnone uwtable -; FNATTR-NEXT: declare void @nofree_function() declare void @nofree_function() nofree readnone #0 -; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable -; FNATTR-NEXT: define void @call_nofree_function() define void @call_nofree_function() #0 { - tail call void @nofree_function() - ret void +; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR-LABEL: define {{[^@]+}}@call_nofree_function +; FNATTR-SAME: () #[[ATTR4]] { +; FNATTR-NEXT: tail call void @nofree_function() +; FNATTR-NEXT: ret void +; + tail call void @nofree_function() + ret void } ; TEST 8 (negative case) @@ -146,56 +191,73 @@ define void @call_nofree_function() #0 { declare void @maybe_free() #0 -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR: define void @call_maybe_free() define void @call_maybe_free() #0 { - tail call void @maybe_free() - ret void +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@call_maybe_free +; FNATTR-SAME: () #[[ATTR1]] { +; FNATTR-NEXT: tail call void @maybe_free() +; FNATTR-NEXT: ret void +; + tail call void @maybe_free() + ret void } ; TEST 9 (negative case) ; Call both of above functions -; FNATTR: Function Attrs: noinline nounwind uwtable -; FNATTR-NEXT: define void @call_both() define void @call_both() #0 { - tail call void @maybe_free() - tail call void @nofree_function() - ret void +; FNATTR: Function Attrs: noinline nounwind uwtable +; FNATTR-LABEL: define {{[^@]+}}@call_both +; FNATTR-SAME: () #[[ATTR1]] { +; FNATTR-NEXT: tail call void @maybe_free() +; FNATTR-NEXT: tail call void @nofree_function() +; FNATTR-NEXT: ret void +; + tail call void @maybe_free() + tail call void @nofree_function() + ret void } ; TEST 10 (positive case) ; Call intrinsic function -; FNATTRS: Function Attrs: nofree noinline nosync readnone speculatable -; FNATTRS-NEXT: declare float @llvm.floor.f32(float %0) declare float @llvm.floor.f32(float) -; FNATTRS: Function Attrs: noinline nounwind uwtable -; FNATTRS-NEXT: define void @call_floor(float %a) -; FIXME: missing nofree - define void @call_floor(float %a) #0 { - tail call float @llvm.floor.f32(float %a) - ret void +; FNATTR: Function Attrs: mustprogress nofree noinline nosync nounwind readnone willreturn uwtable +; FNATTR-LABEL: define {{[^@]+}}@call_floor +; FNATTR-SAME: (float [[A:%.*]]) #[[ATTR7:[0-9]+]] { +; FNATTR-NEXT: [[TMP1:%.*]] = tail call float @llvm.floor.f32(float [[A]]) +; FNATTR-NEXT: ret void +; + tail call float @llvm.floor.f32(float %a) + ret void } ; TEST 11 (positive case) ; Check propagation. -; FNATTRS: Function Attrs: noinline nounwind uwtable -; FNATTRS-NEXT: define void @f1() define void @f1() #0 { - tail call void @nofree_function() - ret void +; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR-LABEL: define {{[^@]+}}@f1 +; FNATTR-SAME: () #[[ATTR4]] { +; FNATTR-NEXT: tail call void @nofree_function() +; FNATTR-NEXT: ret void +; + tail call void @nofree_function() + ret void } -; FNATTRS: Function Attrs: noinline nounwind uwtable -; FNATTRS-NEXT: define void @f2() define void @f2() #0 { - tail call void @f1() - ret void +; FNATTR: Function Attrs: nofree noinline nosync nounwind readnone uwtable +; FNATTR-LABEL: define {{[^@]+}}@f2 +; FNATTR-SAME: () #[[ATTR4]] { +; FNATTR-NEXT: tail call void @f1() +; FNATTR-NEXT: ret void +; + tail call void @f1() + ret void } diff --git a/llvm/test/Transforms/FunctionAttrs/norecurse.ll b/llvm/test/Transforms/FunctionAttrs/norecurse.ll index 7baa703..fe262a8 100644 --- a/llvm/test/Transforms/FunctionAttrs/norecurse.ll +++ b/llvm/test/Transforms/FunctionAttrs/norecurse.ll @@ -1,121 +1,158 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs),rpo-function-attrs' -S | FileCheck %s -; CHECK: Function Attrs -; CHECK-SAME: norecurse nosync nounwind readnone -; CHECK-NEXT: define i32 @leaf() define i32 @leaf() { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: define {{[^@]+}}@leaf +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: ret i32 1 +; ret i32 1 } -; CHECK: Function Attrs -; CHECK-NOT: norecurse -; CHECK-SAME: readnone -; CHECK-NOT: norecurse -; CHECK-NEXT: define i32 @self_rec() define i32 @self_rec() { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@self_rec +; CHECK-SAME: () #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @self_rec() +; CHECK-NEXT: ret i32 4 +; %a = call i32 @self_rec() ret i32 4 } -; CHECK: Function Attrs -; CHECK-NOT: norecurse -; CHECK-SAME: readnone -; CHECK-NOT: norecurse -; CHECK-NEXT: define i32 @indirect_rec() define i32 @indirect_rec() { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@indirect_rec +; CHECK-SAME: () #[[ATTR1]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec2() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @indirect_rec2() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NOT: norecurse -; CHECK-SAME: readnone -; CHECK-NOT: norecurse -; CHECK-NEXT: define i32 @indirect_rec2() + define i32 @indirect_rec2() { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@indirect_rec2 +; CHECK-SAME: () #[[ATTR1]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @indirect_rec() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NOT: norecurse -; CHECK-SAME: readnone -; CHECK-NOT: norecurse -; CHECK-NEXT: define i32 @extern() define i32 @extern() { +; CHECK: Function Attrs: nofree nosync readnone +; CHECK-LABEL: define {{[^@]+}}@extern +; CHECK-SAME: () #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @k() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @k() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NEXT: declare i32 @k() declare i32 @k() readnone -; CHECK: Function Attrs -; CHECK-NOT: norecurse -; CHECK-SAME: nounwind -; CHECK-NOT: norecurse -; CHECK-NEXT: define void @intrinsic(ptr nocapture writeonly %dest, ptr nocapture readonly %src, i32 %len) define void @intrinsic(ptr %dest, ptr %src, i32 %len) { +; CHECK: Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@intrinsic +; CHECK-SAME: (ptr nocapture writeonly [[DEST:%.*]], ptr nocapture readonly [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR4:[0-9]+]] { +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DEST]], ptr [[SRC]], i32 [[LEN]], i1 false) +; CHECK-NEXT: ret void +; call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 %len, i1 false) ret void } -; CHECK: Function Attrs -; CHECK-NEXT: declare void @llvm.memcpy.p0.p0.i32 declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1) -; CHECK: Function Attrs -; CHECK-SAME: norecurse nosync readnone -; CHECK-NEXT: define internal i32 @called_by_norecurse() define internal i32 @called_by_norecurse() { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse +; CHECK-SAME: () #[[ATTR6:[0-9]+]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @k() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @k() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NEXT: define void @m() + define void @m() norecurse { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@m +; CHECK-SAME: () #[[ATTR6]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() +; CHECK-NEXT: ret void +; %a = call i32 @called_by_norecurse() ret void } -; CHECK: Function Attrs -; CHECK-SAME: norecurse nosync readnone -; CHECK-NEXT: define internal i32 @called_by_norecurse_indirectly() define internal i32 @called_by_norecurse_indirectly() { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly +; CHECK-SAME: () #[[ATTR6]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @k() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @k() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NEXT: define internal void @o + define internal void @o() { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@o +; CHECK-SAME: () #[[ATTR6]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() +; CHECK-NEXT: ret void +; %a = call i32 @called_by_norecurse_indirectly() ret void } -; CHECK: Function Attrs -; CHECK-NEXT: define void @p + define void @p() norecurse { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@p +; CHECK-SAME: () #[[ATTR6]] { +; CHECK-NEXT: call void @o() +; CHECK-NEXT: ret void +; call void @o() ret void } -; CHECK: Function Attrs -; CHECK-NOT: norecurse -; CHECK-SAME: nosync readnone -; CHECK-NOT: norecurse -; CHECK-NEXT: define internal i32 @escapes_as_parameter define internal i32 @escapes_as_parameter(ptr %p) { +; CHECK: Function Attrs: nofree nosync readnone +; CHECK-LABEL: define {{[^@]+}}@escapes_as_parameter +; CHECK-SAME: (ptr nocapture readnone [[P:%.*]]) #[[ATTR2]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @k() +; CHECK-NEXT: ret i32 [[A]] +; %a = call i32 @k() ret i32 %a } -; CHECK: Function Attrs -; CHECK-NEXT: define internal void @q + define internal void @q() { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@q +; CHECK-SAME: () #[[ATTR6]] { +; CHECK-NEXT: [[A:%.*]] = call i32 @escapes_as_parameter(ptr @escapes_as_parameter) +; CHECK-NEXT: ret void +; %a = call i32 @escapes_as_parameter(ptr @escapes_as_parameter) ret void } -; CHECK: Function Attrs -; CHECK-NEXT: define void @r + define void @r() norecurse { +; CHECK: Function Attrs: nofree norecurse nosync readnone +; CHECK-LABEL: define {{[^@]+}}@r +; CHECK-SAME: () #[[ATTR6]] { +; CHECK-NEXT: call void @q() +; CHECK-NEXT: ret void +; call void @q() ret void -} \ No newline at end of file +} -- 2.7.4