298 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals2; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs),rpo-function-attrs' -S | FileCheck --check-prefixes=COMMON,FNATTRS %s3; RUN: opt -passes=attributor-light -S < %s | FileCheck --check-prefixes=COMMON,ATTRIBUTOR %s4 5 6define i32 @leaf() {7; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)8; FNATTRS-LABEL: define {{[^@]+}}@leaf9; FNATTRS-SAME: () #[[ATTR0:[0-9]+]] {10; FNATTRS-NEXT: ret i32 111;12; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)13; ATTRIBUTOR-LABEL: define {{[^@]+}}@leaf14; ATTRIBUTOR-SAME: () #[[ATTR0:[0-9]+]] {15; ATTRIBUTOR-NEXT: ret i32 116;17 ret i32 118}19 20define i32 @self_rec() {21; FNATTRS: Function Attrs: nofree nosync nounwind memory(none)22; FNATTRS-LABEL: define {{[^@]+}}@self_rec23; FNATTRS-SAME: () #[[ATTR1:[0-9]+]] {24; FNATTRS-NEXT: [[A:%.*]] = call i32 @self_rec()25; FNATTRS-NEXT: ret i32 426;27; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(none)28; ATTRIBUTOR-LABEL: define {{[^@]+}}@self_rec29; ATTRIBUTOR-SAME: () #[[ATTR1:[0-9]+]] {30; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @self_rec() #[[ATTR1]]31; ATTRIBUTOR-NEXT: ret i32 432;33 %a = call i32 @self_rec()34 ret i32 435}36 37define i32 @indirect_rec() {38; FNATTRS: Function Attrs: nofree nosync nounwind memory(none)39; FNATTRS-LABEL: define {{[^@]+}}@indirect_rec40; FNATTRS-SAME: () #[[ATTR1]] {41; FNATTRS-NEXT: [[A:%.*]] = call i32 @indirect_rec2()42; FNATTRS-NEXT: ret i32 [[A]]43;44; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(none)45; ATTRIBUTOR-LABEL: define {{[^@]+}}@indirect_rec46; ATTRIBUTOR-SAME: () #[[ATTR1]] {47; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @indirect_rec2() #[[ATTR1]]48; ATTRIBUTOR-NEXT: ret i32 [[A]]49;50 %a = call i32 @indirect_rec2()51 ret i32 %a52}53 54define i32 @indirect_rec2() {55; FNATTRS: Function Attrs: nofree nosync nounwind memory(none)56; FNATTRS-LABEL: define {{[^@]+}}@indirect_rec257; FNATTRS-SAME: () #[[ATTR1]] {58; FNATTRS-NEXT: [[A:%.*]] = call i32 @indirect_rec()59; FNATTRS-NEXT: ret i32 [[A]]60;61; ATTRIBUTOR: Function Attrs: nofree nosync nounwind memory(none)62; ATTRIBUTOR-LABEL: define {{[^@]+}}@indirect_rec263; ATTRIBUTOR-SAME: () #[[ATTR1]] {64; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @indirect_rec() #[[ATTR1]]65; ATTRIBUTOR-NEXT: ret i32 [[A]]66;67 %a = call i32 @indirect_rec()68 ret i32 %a69}70 71define i32 @extern() {72; FNATTRS: Function Attrs: nofree nosync memory(none)73; FNATTRS-LABEL: define {{[^@]+}}@extern74; FNATTRS-SAME: () #[[ATTR2:[0-9]+]] {75; FNATTRS-NEXT: [[A:%.*]] = call i32 @k()76; FNATTRS-NEXT: ret i32 [[A]]77;78; ATTRIBUTOR: Function Attrs: nosync memory(none)79; ATTRIBUTOR-LABEL: define {{[^@]+}}@extern80; ATTRIBUTOR-SAME: () #[[ATTR2:[0-9]+]] {81; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @k() #[[ATTR7:[0-9]+]]82; ATTRIBUTOR-NEXT: ret i32 [[A]]83;84 %a = call i32 @k()85 ret i32 %a86}87 88declare i32 @k() readnone89 90define void @intrinsic(ptr %dest, ptr %src, i32 %len) {91; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)92; FNATTRS-LABEL: define {{[^@]+}}@intrinsic93; FNATTRS-SAME: (ptr writeonly captures(none) [[DEST:%.*]], ptr readonly captures(none) [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR4:[0-9]+]] {94; FNATTRS-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DEST]], ptr [[SRC]], i32 [[LEN]], i1 false)95; FNATTRS-NEXT: ret void96;97; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)98; ATTRIBUTOR-LABEL: define {{[^@]+}}@intrinsic99; ATTRIBUTOR-SAME: (ptr nofree writeonly captures(none) [[DEST:%.*]], ptr nofree readonly captures(none) [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR4:[0-9]+]] {100; ATTRIBUTOR-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr writeonly captures(none) [[DEST]], ptr readonly captures(none) [[SRC]], i32 [[LEN]], i1 false) #[[ATTR8:[0-9]+]]101; ATTRIBUTOR-NEXT: ret void102;103 call void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 %len, i1 false)104 ret void105}106 107declare void @llvm.memcpy.p0.p0.i32(ptr, ptr, i32, i1)108 109define internal i32 @called_by_norecurse() {110; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)111; FNATTRS-LABEL: define {{[^@]+}}@called_by_norecurse112; FNATTRS-SAME: () #[[ATTR6:[0-9]+]] {113; FNATTRS-NEXT: [[A:%.*]] = call i32 @k()114; FNATTRS-NEXT: ret i32 [[A]]115;116; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)117; ATTRIBUTOR-LABEL: define {{[^@]+}}@called_by_norecurse118; ATTRIBUTOR-SAME: () #[[ATTR6:[0-9]+]] {119; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @k() #[[ATTR7]]120; ATTRIBUTOR-NEXT: ret i32 [[A]]121;122 %a = call i32 @k()123 ret i32 %a124}125 126define void @m() norecurse {127; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)128; FNATTRS-LABEL: define {{[^@]+}}@m129; FNATTRS-SAME: () #[[ATTR6]] {130; FNATTRS-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()131; FNATTRS-NEXT: ret void132;133; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)134; ATTRIBUTOR-LABEL: define {{[^@]+}}@m135; ATTRIBUTOR-SAME: () #[[ATTR6]] {136; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() #[[ATTR2]]137; ATTRIBUTOR-NEXT: ret void138;139 %a = call i32 @called_by_norecurse()140 ret void141}142 143define internal i32 @called_by_norecurse_indirectly() {144; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)145; FNATTRS-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly146; FNATTRS-SAME: () #[[ATTR6]] {147; FNATTRS-NEXT: [[A:%.*]] = call i32 @k()148; FNATTRS-NEXT: ret i32 [[A]]149;150; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)151; ATTRIBUTOR-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly152; ATTRIBUTOR-SAME: () #[[ATTR6]] {153; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @k() #[[ATTR7]]154; ATTRIBUTOR-NEXT: ret i32 [[A]]155;156 %a = call i32 @k()157 ret i32 %a158}159 160define internal void @o() {161; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)162; FNATTRS-LABEL: define {{[^@]+}}@o163; FNATTRS-SAME: () #[[ATTR6]] {164; FNATTRS-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()165; FNATTRS-NEXT: ret void166;167; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)168; ATTRIBUTOR-LABEL: define {{[^@]+}}@o169; ATTRIBUTOR-SAME: () #[[ATTR6]] {170; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() #[[ATTR2]]171; ATTRIBUTOR-NEXT: ret void172;173 %a = call i32 @called_by_norecurse_indirectly()174 ret void175}176 177define void @p() norecurse {178; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)179; FNATTRS-LABEL: define {{[^@]+}}@p180; FNATTRS-SAME: () #[[ATTR6]] {181; FNATTRS-NEXT: call void @o()182; FNATTRS-NEXT: ret void183;184; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)185; ATTRIBUTOR-LABEL: define {{[^@]+}}@p186; ATTRIBUTOR-SAME: () #[[ATTR6]] {187; ATTRIBUTOR-NEXT: call void @o() #[[ATTR2]]188; ATTRIBUTOR-NEXT: ret void189;190 call void @o()191 ret void192}193 194define internal i32 @escapes_as_parameter(ptr %p) {195; FNATTRS: Function Attrs: nofree nosync memory(none)196; FNATTRS-LABEL: define {{[^@]+}}@escapes_as_parameter197; FNATTRS-SAME: (ptr readnone captures(none) [[P:%.*]]) #[[ATTR2]] {198; FNATTRS-NEXT: [[A:%.*]] = call i32 @k()199; FNATTRS-NEXT: ret i32 [[A]]200;201; ATTRIBUTOR: Function Attrs: nosync memory(none)202; ATTRIBUTOR-LABEL: define {{[^@]+}}@escapes_as_parameter203; ATTRIBUTOR-SAME: (ptr nofree readnone captures(none) [[P:%.*]]) #[[ATTR2]] {204; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @k() #[[ATTR7]]205; ATTRIBUTOR-NEXT: ret i32 [[A]]206;207 %a = call i32 @k()208 ret i32 %a209}210 211define internal void @q() {212; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)213; FNATTRS-LABEL: define {{[^@]+}}@q214; FNATTRS-SAME: () #[[ATTR6]] {215; FNATTRS-NEXT: [[A:%.*]] = call i32 @escapes_as_parameter(ptr @escapes_as_parameter)216; FNATTRS-NEXT: ret void217;218; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)219; ATTRIBUTOR-LABEL: define {{[^@]+}}@q220; ATTRIBUTOR-SAME: () #[[ATTR6]] {221; ATTRIBUTOR-NEXT: [[A:%.*]] = call i32 @escapes_as_parameter(ptr nofree nonnull readnone captures(none) @escapes_as_parameter) #[[ATTR2]]222; ATTRIBUTOR-NEXT: ret void223;224 %a = call i32 @escapes_as_parameter(ptr @escapes_as_parameter)225 ret void226}227 228define void @r() norecurse {229; FNATTRS: Function Attrs: nofree norecurse nosync memory(none)230; FNATTRS-LABEL: define {{[^@]+}}@r231; FNATTRS-SAME: () #[[ATTR6]] {232; FNATTRS-NEXT: call void @q()233; FNATTRS-NEXT: ret void234;235; ATTRIBUTOR: Function Attrs: norecurse nosync memory(none)236; ATTRIBUTOR-LABEL: define {{[^@]+}}@r237; ATTRIBUTOR-SAME: () #[[ATTR6]] {238; ATTRIBUTOR-NEXT: call void @q() #[[ATTR2]]239; ATTRIBUTOR-NEXT: ret void240;241 call void @q()242 ret void243}244 245define void @unknown_call(ptr %fn) {246; FNATTRS-LABEL: define {{[^@]+}}@unknown_call247; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) {248; FNATTRS-NEXT: call void [[FN]]()249; FNATTRS-NEXT: ret void250;251; ATTRIBUTOR-LABEL: define {{[^@]+}}@unknown_call252; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[FN:%.*]]) {253; ATTRIBUTOR-NEXT: call void [[FN]]()254; ATTRIBUTOR-NEXT: ret void255;256 call void %fn()257 ret void258}259 260define void @unknown_norecurse_call(ptr %fn) {261; FNATTRS-LABEL: define {{[^@]+}}@unknown_norecurse_call262; FNATTRS-SAME: (ptr readonly captures(none) [[FN:%.*]]) {263; FNATTRS-NEXT: call void [[FN]]() #[[ATTR7:[0-9]+]]264; FNATTRS-NEXT: ret void265;266; ATTRIBUTOR-LABEL: define {{[^@]+}}@unknown_norecurse_call267; ATTRIBUTOR-SAME: (ptr nofree nonnull captures(none) [[FN:%.*]]) {268; ATTRIBUTOR-NEXT: call void [[FN]]() #[[ATTR9:[0-9]+]]269; ATTRIBUTOR-NEXT: ret void270;271 call void %fn() norecurse272 ret void273}274 275;.276; FNATTRS: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }277; FNATTRS: attributes #[[ATTR1]] = { nofree nosync nounwind memory(none) }278; FNATTRS: attributes #[[ATTR2]] = { nofree nosync memory(none) }279; FNATTRS: attributes #[[ATTR3:[0-9]+]] = { memory(none) }280; FNATTRS: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }281; FNATTRS: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }282; FNATTRS: attributes #[[ATTR6]] = { nofree norecurse nosync memory(none) }283; FNATTRS: attributes #[[ATTR7]] = { norecurse }284;.285; ATTRIBUTOR: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }286; ATTRIBUTOR: attributes #[[ATTR1]] = { nofree nosync nounwind memory(none) }287; ATTRIBUTOR: attributes #[[ATTR2]] = { nosync memory(none) }288; ATTRIBUTOR: attributes #[[ATTR3:[0-9]+]] = { memory(none) }289; ATTRIBUTOR: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }290; ATTRIBUTOR: attributes #[[ATTR5:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }291; ATTRIBUTOR: attributes #[[ATTR6]] = { norecurse nosync memory(none) }292; ATTRIBUTOR: attributes #[[ATTR7]] = { nosync }293; ATTRIBUTOR: attributes #[[ATTR8]] = { nofree willreturn }294; ATTRIBUTOR: attributes #[[ATTR9]] = { norecurse }295;.296;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:297; COMMON: {{.*}}298