Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / Analysis / LazyCallGraph / basic.ll
blobb1a733f4f3212f6f9e99744de4116df5f091074a
1 ; RUN: opt -disable-output -passes=print-lcg %s 2>&1 | FileCheck %s
3 ; Basic validation of the call graph analysis used in the new pass manager.
5 define void @f() {
6 ; CHECK-LABEL: Edges in function: f
7 ; CHECK-NOT: ->
9 entry:
10   ret void
13 ; A bunch more functions just to make it easier to test several call edges at once.
14 define void @f1() {
15   ret void
17 define void @f2() {
18   ret void
20 define void @f3() {
21   ret void
23 define void @f4() {
24   ret void
26 define void @f5() {
27   ret void
29 define void @f6() {
30   ret void
32 define void @f7() {
33   ret void
35 define void @f8() {
36   ret void
38 define void @f9() {
39   ret void
41 define void @f10() {
42   ret void
44 define void @f11() {
45   ret void
47 define void @f12() {
48   ret void
51 declare i32 @__gxx_personality_v0(...)
53 define void @test0() {
54 ; CHECK-LABEL: Edges in function: test0
55 ; CHECK-NEXT: call -> f
56 ; CHECK-NOT: ->
58 entry:
59   call void @f()
60   call void @f()
61   call void @f()
62   call void @f()
63   ret void
66 define 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: ->
82 entry:
83   br label %next
85 dead:
86   br label %next
88 next:
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
96 exit:
97   ret ptr @f11
99 unwind:
100   %res = landingpad { ptr, i32 }
101           cleanup
102   resume { ptr, i32 } { ptr @f12, i32 42 }
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
110 define 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: ->
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
128 @test3_ptr = external global ptr
130 define 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: ->
136 entry:
137   call void @test3_aa2()
138   store ptr @test3_ab1, ptr @test3_ptr
139   ret void
142 define 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: ->
148 entry:
149   call void @test3_aa1()
150   call void @test3_ab2()
151   ret void
154 define 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: ->
160 entry:
161   call void @test3_ab2()
162   call void @test3_ac1()
163   ret void
166 define 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: ->
172 entry:
173   call void @test3_ab1()
174   call void @test3_ba1()
175   ret void
178 define 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: ->
184 entry:
185   call void @test3_ac2()
186   store ptr @test3_aa2, ptr @test3_ptr
187   ret void
190 define 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: ->
196 entry:
197   call void @test3_ac1()
198   store ptr @test3_ba1, ptr @test3_ptr
199   ret void
202 define 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: ->
208 entry:
209   call void @test3_bb1()
210   store ptr @test3_ca1, ptr @test3_ptr
211   ret void
214 define 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: ->
220 entry:
221   call void @test3_ca2()
222   store ptr @test3_ba1, ptr @test3_ptr
223   ret void
226 define void @test3_ca1() {
227 ; CHECK-LABEL: Edges in function: test3_ca1
228 ; CHECK-NEXT: call -> test3_ca2
229 ; CHECK-NOT: ->
231 entry:
232   call void @test3_ca2()
233   ret void
236 define void @test3_ca2() {
237 ; CHECK-LABEL: Edges in function: test3_ca2
238 ; CHECK-NEXT: call -> test3_ca3
239 ; CHECK-NOT: ->
241 entry:
242   call void @test3_ca3()
243   ret void
246 define void @test3_ca3() {
247 ; CHECK-LABEL: Edges in function: test3_ca3
248 ; CHECK-NEXT: call -> test3_ca1
249 ; CHECK-NOT: ->
251 entry:
252   call void @test3_ca1()
253   ret void
256 ; Verify the SCCs formed.
258 ; CHECK-LABEL: RefSCC with 1 call SCCs:
259 ; CHECK-NEXT:    SCC with 1 functions:
260 ; CHECK-NEXT:      f
262 ; CHECK-LABEL: RefSCC with 1 call SCCs:
263 ; CHECK-NEXT:    SCC with 1 functions:
264 ; CHECK-NEXT:      f1
266 ; CHECK-LABEL: RefSCC with 1 call SCCs:
267 ; CHECK-NEXT:    SCC with 1 functions:
268 ; CHECK-NEXT:      f2
270 ; CHECK-LABEL: RefSCC with 1 call SCCs:
271 ; CHECK-NEXT:    SCC with 1 functions:
272 ; CHECK-NEXT:      f3
274 ; CHECK-LABEL: RefSCC with 1 call SCCs:
275 ; CHECK-NEXT:    SCC with 1 functions:
276 ; CHECK-NEXT:      f4
278 ; CHECK-LABEL: RefSCC with 1 call SCCs:
279 ; CHECK-NEXT:    SCC with 1 functions:
280 ; CHECK-NEXT:      f5
282 ; CHECK-LABEL: RefSCC with 1 call SCCs:
283 ; CHECK-NEXT:    SCC with 1 functions:
284 ; CHECK-NEXT:      f6
286 ; CHECK-LABEL: RefSCC with 1 call SCCs:
287 ; CHECK-NEXT:    SCC with 1 functions:
288 ; CHECK-NEXT:      f7
290 ; CHECK-LABEL: RefSCC with 1 call SCCs:
291 ; CHECK-NEXT:    SCC with 1 functions:
292 ; CHECK-NEXT:      f8
294 ; CHECK-LABEL: RefSCC with 1 call SCCs:
295 ; CHECK-NEXT:    SCC with 1 functions:
296 ; CHECK-NEXT:      f9
298 ; CHECK-LABEL: RefSCC with 1 call SCCs:
299 ; CHECK-NEXT:    SCC with 1 functions:
300 ; CHECK-NEXT:      f10
302 ; CHECK-LABEL: RefSCC with 1 call SCCs:
303 ; CHECK-NEXT:    SCC with 1 functions:
304 ; CHECK-NEXT:      f11
306 ; CHECK-LABEL: RefSCC with 1 call SCCs:
307 ; CHECK-NEXT:    SCC with 1 functions:
308 ; CHECK-NEXT:      f12
310 ; CHECK-LABEL: RefSCC with 1 call SCCs:
311 ; CHECK-NEXT:    SCC with 1 functions:
312 ; CHECK-NEXT:      test0
314 ; CHECK-LABEL: RefSCC with 1 call SCCs:
315 ; CHECK-NEXT:    SCC with 1 functions:
316 ; CHECK-NEXT:      test1
318 ; CHECK-LABEL: RefSCC with 1 call SCCs:
319 ; CHECK-NEXT:    SCC with 1 functions:
320 ; CHECK-NEXT:      test2
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
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
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