xref: /llvm-project/llvm/test/Linker/blockaddress.ll (revision f2e868c566107eb2f54e3e6033199297ba11e2d9)
1; RUN: llvm-as %s -o %t.bc
2; RUN: llvm-link %t.bc -S | FileCheck %s
3
4declare void @f(ptr)
5
6; Test that a blockaddress in @y referring to %label in @x can be moved when @y
7; appears after @x.
8define void @x() {
9  br label %label
10
11label:
12  call void @y()
13  ret void
14}
15
16define void @y() {
17; CHECK: define void @y() {
18; CHECK-NEXT: call void @f(ptr blockaddress(@x, %label))
19  call void @f(ptr blockaddress(@x, %label))
20  ret void
21}
22
23; Test that a blockaddress in @a referring to %label in @b can be moved when @a
24; appears before @b.
25define void @a() {
26; CHECK: define void @a() {
27; CHECK-NEXT: call void @f(ptr blockaddress(@b, %label))
28  call void @f(ptr blockaddress(@b, %label))
29  ret void
30}
31
32define void @b() {
33  br label %label
34
35label:
36  call void @a()
37  ret void
38}
39
40; Test that @c and @d can both have blockaddress Constants that refer to one
41; another.
42
43define void @c() {
44; CHECK: define void @c() {
45; CHECK-NEXT:  br label %label
46; CHECK-EMPTY:
47; CHECK-NEXT: label:
48; CHECK-NEXT: call void @f(ptr blockaddress(@d, %label))
49  br label %label
50
51label:
52  call void @f(ptr blockaddress(@d, %label))
53  ret void
54}
55
56define void @d() {
57; CHECK: define void @d() {
58; CHECK-NEXT:  br label %label
59; CHECK-EMPTY:
60; CHECK-NEXT: label:
61; CHECK-NEXT: call void @f(ptr blockaddress(@c, %label))
62  br label %label
63
64label:
65  call void @f(ptr blockaddress(@c, %label))
66  ret void
67}
68
69; Test that Functions added to IRLinker's Worklist member lazily (linkonce_odr)
70; aren't susceptible to the the same issues as @x/@y above.
71define void @parsed() {
72  br label %label
73
74label:
75  ret void
76}
77
78define linkonce_odr void @lazy() {
79; CHECK: define linkonce_odr void @lazy() {
80; CHECK-NEXT: br label %label
81; CHECK-EMPTY:
82; CHECK-NEXT: label:
83; CHECK-NEXT: call void @f(ptr blockaddress(@parsed, %label))
84  br label %label
85
86label:
87  call void @f(ptr blockaddress(@parsed, %label))
88  ret void
89}
90
91define void @parsed2() {
92  call void @lazy()
93  ret void
94}
95
96; Same test as @lazy, just with one more level of lazy parsed functions.
97define void @parsed3() {
98  br label %label
99
100label:
101  ret void
102}
103
104define linkonce_odr void @lazy1() {
105; CHECK: define linkonce_odr void @lazy1() {
106; CHECK-NEXT: br label %label
107; CHECK-EMPTY:
108; CHECK-NEXT: label:
109; CHECK-NEXT: call void @f(ptr blockaddress(@parsed3, %label))
110  br label %label
111
112label:
113  call void @f(ptr blockaddress(@parsed3, %label))
114  ret void
115}
116
117define linkonce_odr void @lazy2() {
118  call void @lazy1()
119  ret void
120}
121
122define void @parsed4() {
123  call void @lazy2()
124  ret void
125}
126