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