1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals 2; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM 3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM 4; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM 5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM 6; 7; When a function is marked `alwaysinline` and is able to be inlined, 8; we can IPO its boundaries 9 10; the function is not exactly defined, and marked alwaysinline and can be inlined, 11; so the function can be analyzed 12define linkonce void @inner1() alwaysinline { 13; CHECK: Function Attrs: alwaysinline nofree norecurse nosync nounwind readnone willreturn 14; CHECK-LABEL: define {{[^@]+}}@inner1 15; CHECK-SAME: () #[[ATTR0:[0-9]+]] { 16; CHECK-NEXT: entry: 17; CHECK-NEXT: ret void 18; 19entry: 20 ret void 21} 22 23define void @outer1() { 24; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn 25; CHECK-LABEL: define {{[^@]+}}@outer1 26; CHECK-SAME: () #[[ATTR1:[0-9]+]] { 27; CHECK-NEXT: entry: 28; CHECK-NEXT: ret void 29; 30entry: 31 call void @inner1() 32 ret void 33} 34 35; The function is not alwaysinline and is not exactly defined 36; so it will not be analyzed 37define linkonce i32 @inner2() { 38; CHECK-LABEL: define {{[^@]+}}@inner2() { 39; CHECK-NEXT: entry: 40; CHECK-NEXT: ret i32 1 41; 42entry: 43 ret i32 1 44} 45 46; CHECK-NOT: Function Attrs 47define i32 @outer2() { 48; CHECK: Function Attrs: norecurse 49; CHECK-LABEL: define {{[^@]+}}@outer2 50; CHECK-SAME: () #[[ATTR2:[0-9]+]] { 51; CHECK-NEXT: entry: 52; CHECK-NEXT: [[R:%.*]] = call i32 @inner2() #[[ATTR3:[0-9]+]] 53; CHECK-NEXT: ret i32 [[R]] 54; 55entry: 56 %r = call i32 @inner2() alwaysinline 57 ret i32 %r 58} 59 60; This function cannot be inlined although it is marked alwaysinline 61; it is `unexactly defined` and alwaysinline but cannot be inlined. 62; so it will not be analyzed 63define linkonce i32 @inner3(i8* %addr) alwaysinline { 64; CHECK: Function Attrs: alwaysinline 65; CHECK-LABEL: define {{[^@]+}}@inner3 66; CHECK-SAME: (i8* [[ADDR:%.*]]) #[[ATTR3]] { 67; CHECK-NEXT: entry: 68; CHECK-NEXT: indirectbr i8* [[ADDR]], [label [[ONE:%.*]], label %two] 69; CHECK: one: 70; CHECK-NEXT: ret i32 42 71; CHECK: two: 72; CHECK-NEXT: ret i32 44 73; 74entry: 75 indirectbr i8* %addr, [ label %one, label %two ] 76 77one: 78 ret i32 42 79 80two: 81 ret i32 44 82} 83 84define i32 @outer3(i32 %x) { 85; CHECK: Function Attrs: norecurse 86; CHECK-LABEL: define {{[^@]+}}@outer3 87; CHECK-SAME: (i32 [[X:%.*]]) #[[ATTR2]] { 88; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 42 89; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[CMP]], i8* blockaddress(@inner3, [[ONE:%.*]]), i8* blockaddress(@inner3, [[TWO:%.*]]) 90; CHECK-NEXT: [[CALL:%.*]] = call i32 @inner3(i8* [[ADDR]]) 91; CHECK-NEXT: ret i32 [[CALL]] 92; 93 %cmp = icmp slt i32 %x, 42 94 %addr = select i1 %cmp, i8* blockaddress(@inner3, %one), i8* blockaddress(@inner3, %two) 95 %call = call i32 @inner3(i8* %addr) 96 ret i32 %call 97} 98;. 99; CHECK: attributes #[[ATTR0]] = { alwaysinline nofree norecurse nosync nounwind readnone willreturn } 100; CHECK: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn } 101; CHECK: attributes #[[ATTR2]] = { norecurse } 102; CHECK: attributes #[[ATTR3]] = { alwaysinline } 103;. 104