1; RUN: opt -disable-output -passes=print-cg %s 2>&1 | FileCheck %s 2; 3; Basic validation of the call graph analysis used in the new pass manager. 4 5define void @f() { 6; CHECK-LABEL: Call edges in function: f 7; CHECK-NOT: -> 8 9entry: 10 ret void 11} 12 13; A bunch more functions just to make it easier to test several call edges at once. 14define void @f1() { 15 ret void 16} 17define void @f2() { 18 ret void 19} 20define void @f3() { 21 ret void 22} 23define void @f4() { 24 ret void 25} 26define void @f5() { 27 ret void 28} 29define void @f6() { 30 ret void 31} 32define void @f7() { 33 ret void 34} 35define void @f8() { 36 ret void 37} 38define void @f9() { 39 ret void 40} 41define void @f10() { 42 ret void 43} 44define void @f11() { 45 ret void 46} 47define void @f12() { 48 ret void 49} 50 51declare i32 @__gxx_personality_v0(...) 52 53define void @test0() { 54; CHECK-LABEL: Call edges in function: test0 55; CHECK-NEXT: -> f 56; CHECK-NOT: -> 57 58entry: 59 call void @f() 60 call void @f() 61 call void @f() 62 call void @f() 63 ret void 64} 65 66define void ()* @test1(void ()** %x) { 67; CHECK-LABEL: Call edges in function: test1 68; CHECK-NEXT: -> f12 69; CHECK-NEXT: -> f11 70; CHECK-NEXT: -> f10 71; CHECK-NEXT: -> f7 72; CHECK-NEXT: -> f9 73; CHECK-NEXT: -> f8 74; CHECK-NEXT: -> f6 75; CHECK-NEXT: -> f5 76; CHECK-NEXT: -> f4 77; CHECK-NEXT: -> f3 78; CHECK-NEXT: -> f2 79; CHECK-NEXT: -> f1 80; CHECK-NOT: -> 81 82entry: 83 br label %next 84 85dead: 86 br label %next 87 88next: 89 phi void ()* [ @f1, %entry ], [ @f2, %dead ] 90 select i1 true, void ()* @f3, void ()* @f4 91 store void ()* @f5, void ()** %x 92 call void @f6() 93 call void (void ()*, void ()*) bitcast (void ()* @f7 to void (void ()*, void ()*)*)(void ()* @f8, void ()* @f9) 94 invoke void @f10() to label %exit unwind label %unwind 95 96exit: 97 ret void ()* @f11 98 99unwind: 100 %res = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0 101 cleanup 102 resume { i8*, i32 } { i8* bitcast (void ()* @f12 to i8*), i32 42 } 103} 104 105@g = global void ()* @f1 106@g1 = global [4 x void ()*] [void ()* @f2, void ()* @f3, void ()* @f4, void ()* @f5] 107@g2 = global {i8, void ()*, i8} {i8 1, void ()* @f6, i8 2} 108@h = constant void ()* @f7 109 110define void @test2() { 111; CHECK-LABEL: Call edges in function: test2 112; CHECK-NEXT: -> f7 113; CHECK-NEXT: -> f6 114; CHECK-NEXT: -> f5 115; CHECK-NEXT: -> f4 116; CHECK-NEXT: -> f3 117; CHECK-NEXT: -> f2 118; CHECK-NEXT: -> f1 119; CHECK-NOT: -> 120 121 load i8*, i8** bitcast (void ()** @g to i8**) 122 load i8*, i8** bitcast (void ()** getelementptr ([4 x void ()*], [4 x void ()*]* @g1, i32 0, i32 2) to i8**) 123 load i8*, i8** bitcast (void ()** getelementptr ({i8, void ()*, i8}, {i8, void ()*, i8}* @g2, i32 0, i32 1) to i8**) 124 load i8*, i8** bitcast (void ()** @h to i8**) 125 ret void 126} 127 128; Verify the SCCs formed. 129; 130; CHECK-LABEL: SCC with 1 functions: 131; CHECK-NEXT: f7 132; 133; CHECK-LABEL: SCC with 1 functions: 134; CHECK-NEXT: f6 135; 136; CHECK-LABEL: SCC with 1 functions: 137; CHECK-NEXT: f5 138; 139; CHECK-LABEL: SCC with 1 functions: 140; CHECK-NEXT: f4 141; 142; CHECK-LABEL: SCC with 1 functions: 143; CHECK-NEXT: f3 144; 145; CHECK-LABEL: SCC with 1 functions: 146; CHECK-NEXT: f2 147; 148; CHECK-LABEL: SCC with 1 functions: 149; CHECK-NEXT: f1 150; 151; CHECK-LABEL: SCC with 1 functions: 152; CHECK-NEXT: test2 153; 154; CHECK-LABEL: SCC with 1 functions: 155; CHECK-NEXT: f12 156; 157; CHECK-LABEL: SCC with 1 functions: 158; CHECK-NEXT: f11 159; 160; CHECK-LABEL: SCC with 1 functions: 161; CHECK-NEXT: f10 162; 163; CHECK-LABEL: SCC with 1 functions: 164; CHECK-NEXT: f9 165; 166; CHECK-LABEL: SCC with 1 functions: 167; CHECK-NEXT: f8 168; 169; CHECK-LABEL: SCC with 1 functions: 170; CHECK-NEXT: test1 171; 172; CHECK-LABEL: SCC with 1 functions: 173; CHECK-NEXT: f 174; 175; CHECK-LABEL: SCC with 1 functions: 176; CHECK-NEXT: test0 177