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 5 define void @f() { 6 ; CHECK-LABEL: Call edges in function: f 7 ; CHECK-NOT: -> 8 9 entry: 10 ret void 11 } 12 13 ; A bunch more functions just to make it easier to test several call edges at once. 14 define void @f1() { 15 ret void 16 } 17 define void @f2() { 18 ret void 19 } 20 define void @f3() { 21 ret void 22 } 23 define void @f4() { 24 ret void 25 } 26 define void @f5() { 27 ret void 28 } 29 define void @f6() { 30 ret void 31 } 32 define void @f7() { 33 ret void 34 } 35 define void @f8() { 36 ret void 37 } 38 define void @f9() { 39 ret void 40 } 41 define void @f10() { 42 ret void 43 } 44 define void @f11() { 45 ret void 46 } 47 define void @f12() { 48 ret void 49 } 50 51 declare i32 @__gxx_personality_v0(...) 52 53 define void @test0() { 54 ; CHECK-LABEL: Call edges in function: test0 55 ; CHECK-NEXT: -> f 56 ; CHECK-NOT: -> 57 58 entry: 59 call void @f() 60 call void @f() 61 call void @f() 62 call void @f() 63 ret void 64 } 65 66 define 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 82 entry: 83 br label %next 84 85 dead: 86 br label %next 87 88 next: 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 96 exit: 97 ret void ()* @f11 98 99 unwind: 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 110 define 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** bitcast (void ()** @g to i8**) 122 load i8** bitcast (void ()** getelementptr ([4 x void ()*]* @g1, i32 0, i32 2) to i8**) 123 load i8** bitcast (void ()** getelementptr ({i8, void ()*, i8}* @g2, i32 0, i32 1) to i8**) 124 load 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