1; RUN: opt -disable-output -passes=print-lcg %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: 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: Edges in function: test0 55; CHECK-NEXT: call -> 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 ptr @test1(ptr %x) personality ptr @__gxx_personality_v0 { 67; CHECK-LABEL: Edges in function: test1 68; CHECK-NEXT: call -> f6 69; CHECK-NEXT: call -> f10 70; CHECK-NEXT: ref -> f12 71; CHECK-NEXT: ref -> f11 72; CHECK-NEXT: ref -> f7 73; CHECK-NEXT: ref -> f9 74; CHECK-NEXT: ref -> f8 75; CHECK-NEXT: ref -> f5 76; CHECK-NEXT: ref -> f4 77; CHECK-NEXT: ref -> f3 78; CHECK-NEXT: ref -> f2 79; CHECK-NEXT: ref -> f1 80; CHECK-NOT: -> 81 82entry: 83 br label %next 84 85dead: 86 br label %next 87 88next: 89 phi ptr [ @f1, %entry ], [ @f2, %dead ] 90 select i1 true, ptr @f3, ptr @f4 91 store ptr @f5, ptr %x 92 call void @f6() 93 call void (ptr, ptr) @f7(ptr @f8, ptr @f9) 94 invoke void @f10() to label %exit unwind label %unwind 95 96exit: 97 ret ptr @f11 98 99unwind: 100 %res = landingpad { ptr, i32 } 101 cleanup 102 resume { ptr, i32 } { ptr @f12, i32 42 } 103} 104 105@g = global ptr @f1 106@g1 = global [4 x ptr] [ptr @f2, ptr @f3, ptr @f4, ptr @f5] 107@g2 = global {i8, ptr, i8} {i8 1, ptr @f6, i8 2} 108@h = constant ptr @f7 109 110define void @test2() { 111; CHECK-LABEL: Edges in function: test2 112; CHECK-NEXT: ref -> f7 113; CHECK-NEXT: ref -> f6 114; CHECK-NEXT: ref -> f5 115; CHECK-NEXT: ref -> f4 116; CHECK-NEXT: ref -> f3 117; CHECK-NEXT: ref -> f2 118; CHECK-NEXT: ref -> f1 119; CHECK-NOT: -> 120 121 load ptr, ptr @g 122 load ptr, ptr getelementptr ([4 x ptr], ptr @g1, i32 0, i32 2) 123 load ptr, ptr getelementptr ({i8, ptr, i8}, ptr @g2, i32 0, i32 1) 124 load ptr, ptr @h 125 ret void 126} 127 128@test3_ptr = external global ptr 129 130define void @test3_aa1() { 131; CHECK-LABEL: Edges in function: test3_aa1 132; CHECK-NEXT: call -> test3_aa2 133; CHECK-NEXT: ref -> test3_ab1 134; CHECK-NOT: -> 135 136entry: 137 call void @test3_aa2() 138 store ptr @test3_ab1, ptr @test3_ptr 139 ret void 140} 141 142define void @test3_aa2() { 143; CHECK-LABEL: Edges in function: test3_aa2 144; CHECK-NEXT: call -> test3_aa1 145; CHECK-NEXT: call -> test3_ab2 146; CHECK-NOT: -> 147 148entry: 149 call void @test3_aa1() 150 call void @test3_ab2() 151 ret void 152} 153 154define void @test3_ab1() { 155; CHECK-LABEL: Edges in function: test3_ab1 156; CHECK-NEXT: call -> test3_ab2 157; CHECK-NEXT: call -> test3_ac1 158; CHECK-NOT: -> 159 160entry: 161 call void @test3_ab2() 162 call void @test3_ac1() 163 ret void 164} 165 166define void @test3_ab2() { 167; CHECK-LABEL: Edges in function: test3_ab2 168; CHECK-NEXT: call -> test3_ab1 169; CHECK-NEXT: call -> test3_ba1 170; CHECK-NOT: -> 171 172entry: 173 call void @test3_ab1() 174 call void @test3_ba1() 175 ret void 176} 177 178define void @test3_ac1() { 179; CHECK-LABEL: Edges in function: test3_ac1 180; CHECK-NEXT: call -> test3_ac2 181; CHECK-NEXT: ref -> test3_aa2 182; CHECK-NOT: -> 183 184entry: 185 call void @test3_ac2() 186 store ptr @test3_aa2, ptr @test3_ptr 187 ret void 188} 189 190define void @test3_ac2() { 191; CHECK-LABEL: Edges in function: test3_ac2 192; CHECK-NEXT: call -> test3_ac1 193; CHECK-NEXT: ref -> test3_ba1 194; CHECK-NOT: -> 195 196entry: 197 call void @test3_ac1() 198 store ptr @test3_ba1, ptr @test3_ptr 199 ret void 200} 201 202define void @test3_ba1() { 203; CHECK-LABEL: Edges in function: test3_ba1 204; CHECK-NEXT: call -> test3_bb1 205; CHECK-NEXT: ref -> test3_ca1 206; CHECK-NOT: -> 207 208entry: 209 call void @test3_bb1() 210 store ptr @test3_ca1, ptr @test3_ptr 211 ret void 212} 213 214define void @test3_bb1() { 215; CHECK-LABEL: Edges in function: test3_bb1 216; CHECK-NEXT: call -> test3_ca2 217; CHECK-NEXT: ref -> test3_ba1 218; CHECK-NOT: -> 219 220entry: 221 call void @test3_ca2() 222 store ptr @test3_ba1, ptr @test3_ptr 223 ret void 224} 225 226define void @test3_ca1() { 227; CHECK-LABEL: Edges in function: test3_ca1 228; CHECK-NEXT: call -> test3_ca2 229; CHECK-NOT: -> 230 231entry: 232 call void @test3_ca2() 233 ret void 234} 235 236define void @test3_ca2() { 237; CHECK-LABEL: Edges in function: test3_ca2 238; CHECK-NEXT: call -> test3_ca3 239; CHECK-NOT: -> 240 241entry: 242 call void @test3_ca3() 243 ret void 244} 245 246define void @test3_ca3() { 247; CHECK-LABEL: Edges in function: test3_ca3 248; CHECK-NEXT: call -> test3_ca1 249; CHECK-NOT: -> 250 251entry: 252 call void @test3_ca1() 253 ret void 254} 255 256; Verify the SCCs formed. 257; 258; CHECK-LABEL: RefSCC with 1 call SCCs: 259; CHECK-NEXT: SCC with 1 functions: 260; CHECK-NEXT: f 261; 262; CHECK-LABEL: RefSCC with 1 call SCCs: 263; CHECK-NEXT: SCC with 1 functions: 264; CHECK-NEXT: f1 265; 266; CHECK-LABEL: RefSCC with 1 call SCCs: 267; CHECK-NEXT: SCC with 1 functions: 268; CHECK-NEXT: f2 269; 270; CHECK-LABEL: RefSCC with 1 call SCCs: 271; CHECK-NEXT: SCC with 1 functions: 272; CHECK-NEXT: f3 273; 274; CHECK-LABEL: RefSCC with 1 call SCCs: 275; CHECK-NEXT: SCC with 1 functions: 276; CHECK-NEXT: f4 277; 278; CHECK-LABEL: RefSCC with 1 call SCCs: 279; CHECK-NEXT: SCC with 1 functions: 280; CHECK-NEXT: f5 281; 282; CHECK-LABEL: RefSCC with 1 call SCCs: 283; CHECK-NEXT: SCC with 1 functions: 284; CHECK-NEXT: f6 285; 286; CHECK-LABEL: RefSCC with 1 call SCCs: 287; CHECK-NEXT: SCC with 1 functions: 288; CHECK-NEXT: f7 289; 290; CHECK-LABEL: RefSCC with 1 call SCCs: 291; CHECK-NEXT: SCC with 1 functions: 292; CHECK-NEXT: f8 293; 294; CHECK-LABEL: RefSCC with 1 call SCCs: 295; CHECK-NEXT: SCC with 1 functions: 296; CHECK-NEXT: f9 297; 298; CHECK-LABEL: RefSCC with 1 call SCCs: 299; CHECK-NEXT: SCC with 1 functions: 300; CHECK-NEXT: f10 301; 302; CHECK-LABEL: RefSCC with 1 call SCCs: 303; CHECK-NEXT: SCC with 1 functions: 304; CHECK-NEXT: f11 305; 306; CHECK-LABEL: RefSCC with 1 call SCCs: 307; CHECK-NEXT: SCC with 1 functions: 308; CHECK-NEXT: f12 309; 310; CHECK-LABEL: RefSCC with 1 call SCCs: 311; CHECK-NEXT: SCC with 1 functions: 312; CHECK-NEXT: test0 313; 314; CHECK-LABEL: RefSCC with 1 call SCCs: 315; CHECK-NEXT: SCC with 1 functions: 316; CHECK-NEXT: test1 317; 318; CHECK-LABEL: RefSCC with 1 call SCCs: 319; CHECK-NEXT: SCC with 1 functions: 320; CHECK-NEXT: test2 321; 322; CHECK-LABEL: RefSCC with 1 call SCCs: 323; CHECK-NEXT: SCC with 3 functions: 324; CHECK-NEXT: test3_ca2 325; CHECK-NEXT: test3_ca3 326; CHECK-NEXT: test3_ca1 327; 328; CHECK-LABEL: RefSCC with 2 call SCCs: 329; CHECK-NEXT: SCC with 1 functions: 330; CHECK-NEXT: test3_bb1 331; CHECK-NEXT: SCC with 1 functions: 332; CHECK-NEXT: test3_ba1 333; 334; CHECK-LABEL: RefSCC with 3 call SCCs: 335; CHECK-NEXT: SCC with 2 functions: 336; CHECK-NEXT: test3_ac1 337; CHECK-NEXT: test3_ac2 338; CHECK-NEXT: SCC with 2 functions: 339; CHECK-NEXT: test3_ab2 340; CHECK-NEXT: test3_ab1 341; CHECK-NEXT: SCC with 2 functions: 342; CHECK-NEXT: test3_aa1 343; CHECK-NEXT: test3_aa2 344