xref: /llvm-project/llvm/test/Bitcode/blockaddress-addrspace.ll (revision 40c0d076c074ade7cd29b60678c1af933d9f0d21)
1; RUN: rm -rf %t && split-file %s %t
2; RUN: llvm-as %t/global-use-good.ll -o - | llvm-dis -o /dev/null
3; RUN: not llvm-as %t/global-use-bad.ll -o /dev/null 2>&1 | FileCheck %t/global-use-bad.ll
4; RUN: llvm-as %t/global-fwddecl-good.ll -o - | llvm-dis -o /dev/null
5; RUN: not llvm-as %t/global-fwddecl-bad.ll -o /dev/null 2>&1 | FileCheck %t/global-fwddecl-bad.ll
6; RUN: llvm-as %t/return-fwddecl-good.ll  -o - | llvm-dis -o /dev/null
7; RUN: not llvm-as %t/return-fwddecl-bad.ll -o /dev/null 2>&1 | FileCheck %t/return-fwddecl-bad.ll
8; RUN: llvm-as %t/return-self-good.ll  -o - | llvm-dis -o /dev/null
9; RUN: not llvm-as %t/return-self-bad.ll -o /dev/null 2>&1 | FileCheck %t/return-self-bad.ll
10; RUN: not llvm-as %t/return-self-bad-2.ll -o /dev/null 2>&1 | FileCheck %t/return-self-bad-2.ll
11; RUN: not llvm-as %t/return-unknown-fn-bad.ll -o /dev/null 2>&1 | FileCheck %t/return-unknown-fn-bad.ll
12; RUN: llvm-as %t/call-fwddecl-good.ll  -o - | llvm-dis -o /dev/null
13; RUN: not llvm-as %t/call-fwddecl-bad.ll -o /dev/null 2>&1 | FileCheck %t/call-fwddecl-bad.ll
14; RUN: llvm-as %t/phi-good.ll  -o - | llvm-dis -o /dev/null
15; RUN: not llvm-as %t/phi-bad.ll -o /dev/null 2>&1 | FileCheck %t/phi-bad.ll
16; RUN: llvm-as %t/fwddecl-phi-good.ll  -o - | llvm-dis -o /dev/null
17; RUN: not llvm-as %t/fwddecl-phi-bad.ll -o /dev/null 2>&1 | FileCheck %t/fwddecl-phi-bad.ll
18; RUN: not llvm-as %t/bad-type-not-ptr.ll -o /dev/null 2>&1 | FileCheck %t/bad-type-not-ptr.ll
19; RUN: not llvm-as %t/bad-type-not-i8-ptr.ll -o /dev/null 2>&1 | FileCheck %t/bad-type-not-i8-ptr.ll
20
21
22;--- global-use-good.ll
23target datalayout = "P2"
24define void @fn_in_prog_as_implicit() {
25  unreachable
26bb:
27  ret void
28}
29define void @fn_in_prog_as_explicit() addrspace(2) {
30  unreachable
31bb:
32  ret void
33}
34define void @fn_in_other_as() addrspace(1) {
35  unreachable
36bb:
37  ret void
38}
39@global1 = constant ptr addrspace(2) blockaddress(@fn_in_prog_as_implicit, %bb)
40@global2 = constant ptr addrspace(2) blockaddress(@fn_in_prog_as_explicit, %bb)
41@global3 = constant ptr addrspace(1) blockaddress(@fn_in_other_as, %bb)
42
43;--- global-use-bad.ll
44define void @fn() addrspace(1) {
45  unreachable
46bb:
47  ret void
48}
49@global1 = constant ptr addrspace(2) blockaddress(@fn, %bb)
50; CHECK: [[#@LINE-1]]:38: error: constant expression type mismatch: got type 'ptr addrspace(1)' but expected 'ptr addrspace(2)'
51
52; Check that a global blockaddress of a forward-declared function
53; uses the type of the global variable address space for the forward declaration
54;--- global-fwddecl-good.ll
55@global = constant ptr addrspace(2) blockaddress(@fwddecl_in_prog_as, %bb)
56define void @fwddecl_in_prog_as() addrspace(2) {
57  unreachable
58bb:
59  ret void
60}
61
62;--- global-fwddecl-bad.ll
63; This forward declaration does not match the actual function type so we should get an error:
64@global = constant ptr addrspace(2) blockaddress(@fwddecl_in_unexpected_as, %bb)
65; CHECK: [[#@LINE-1]]:77: error: 'bb' defined with type 'ptr addrspace(1)' but expected 'ptr addrspace(2)'
66define void @fwddecl_in_unexpected_as() addrspace(1) {
67  unreachable
68bb:
69  ret void
70}
71
72
73; When returning blockaddresses of forward-declared functions we
74; can also use the type of the variable.
75;--- return-fwddecl-good.ll
76define ptr addrspace(2) @take_as2() {
77  ret ptr addrspace(2) blockaddress(@fwddecl_as2, %bb)
78}
79define ptr addrspace(1) @take_as1() {
80  ret ptr addrspace(1) blockaddress(@fwddecl_as1, %bb)
81}
82define void @fwddecl_as1() addrspace(1) {
83  unreachable
84bb:
85  ret void
86}
87define void @fwddecl_as2() addrspace(2) {
88  unreachable
89bb:
90  ret void
91}
92
93;--- return-fwddecl-bad.ll
94define ptr addrspace(2) @take_bad() {
95  ret ptr addrspace(2) blockaddress(@fwddecl_as1, %bb)
96  ; CHECK: [[#@LINE-1]]:51: error: 'bb' defined with type 'ptr addrspace(1)' but expected 'ptr addrspace(2)'
97}
98define void @fwddecl_as1() addrspace(1) {
99  unreachable
100bb:
101  ret void
102}
103
104;--- return-self-good.ll
105target datalayout = "P2"
106define ptr addrspace(0) @take_self_as0() addrspace(0) {
107L1:
108  br label %L2
109L2:
110  ret ptr addrspace(0) blockaddress(@take_self_as0, %L3)
111L3:
112  unreachable
113}
114define ptr addrspace(2) @take_self_prog_as() {
115L1:
116  br label %L2
117L2:
118  ret ptr addrspace(2) blockaddress(@take_self_prog_as, %L3)
119L3:
120  unreachable
121}
122define ptr addrspace(1) @take_self_as1() addrspace(1) {
123L1:
124  br label %L2
125L2:
126  ret ptr addrspace(1) blockaddress(@take_self_as1, %L3)
127L3:
128  unreachable
129}
130define ptr addrspace(2) @take_self_as2() addrspace(2) {
131L1:
132  br label %L2
133L2:
134  ret ptr addrspace(2) blockaddress(@take_self_as2, %L3)
135L3:
136  unreachable
137}
138
139;--- return-self-bad.ll
140target datalayout = "P2"
141define ptr addrspace(2) @take_self_bad() addrspace(1) {
142L1:
143  br label %L2
144L2:
145  ret ptr addrspace(2) blockaddress(@take_self_bad, %L3)
146  ; CHECK: [[#@LINE-1]]:24: error: constant expression type mismatch: got type 'ptr addrspace(1)' but expected 'ptr addrspace(2)'
147L3:
148  unreachable
149}
150;--- return-self-bad-2.ll
151target datalayout = "P2"
152define ptr @take_self_bad_prog_as() {
153L1:
154  br label %L2
155L2:
156  ret ptr blockaddress(@take_self_bad_prog_as, %L3)
157  ; CHECK: [[#@LINE-1]]:11: error: constant expression type mismatch: got type 'ptr addrspace(2)' but expected 'ptr'
158L3:
159  unreachable
160}
161
162;--- return-unknown-fn-bad.ll
163target datalayout = "P2"
164define ptr addrspace(1) @return_unknown_fn() addrspace(1) {
165  ret ptr addrspace(1) blockaddress(@undefined, %bb)
166  ; CHECK: [[#@LINE-1]]:37: error: expected function name in blockaddress
167}
168
169
170;--- call-fwddecl-good.ll
171target datalayout = "P2"
172define void @call_from_fn_in_as2() addrspace(2) {
173  call addrspace(2) void blockaddress(@fwddecl_as2, %bb)()
174  ret void
175}
176define void @call_from_fn_in_as1() addrspace(1) {
177  call addrspace(1) void blockaddress(@fwddecl_as1, %bb)()
178  ret void
179}
180define void @fwddecl_as2() addrspace(2) {
181  unreachable
182bb:
183  ret void
184}
185define void @fwddecl_as1() addrspace(1) {
186  unreachable
187bb:
188  ret void
189}
190
191;--- call-fwddecl-bad.ll
192target datalayout = "P2"
193define void @call_from_fn_in_as2_explicit() addrspace(2) {
194  call addrspace(2) void blockaddress(@fwddecl_as1, %bb)()
195  ; CHECK: [[#@LINE-1]]:53: error: 'bb' defined with type 'ptr addrspace(1)' but expected 'ptr addrspace(2)'
196  ret void
197}
198define void @fwddecl_as1() addrspace(1) {
199  unreachable
200bb:
201  ret void
202}
203
204;--- phi-good.ll
205target datalayout = "P2"
206define ptr addrspace(1) @f1() addrspace(1) {
207L1:
208  br label %L3
209L2:
210  br label %L3
211L3:
212  %p = phi ptr addrspace(1) [ blockaddress(@f1, %L4), %L2 ], [ null, %L1 ]
213  ret ptr addrspace(1) %p
214L4:
215  unreachable
216}
217define ptr addrspace(2) @f2() {
218L1:
219  br label %L3
220L2:
221  br label %L3
222L3:
223  %p = phi ptr addrspace(2) [ blockaddress(@f2, %L4), %L2 ], [ null, %L1 ]
224  ret ptr addrspace(2) %p
225L4:
226  unreachable
227}
228
229;--- phi-bad.ll
230target datalayout = "P2"
231define ptr @f() {
232L1:
233  br label %L3
234L2:
235  br label %L3
236L3:
237  %p = phi ptr [ blockaddress(@f, %L4), %L2 ], [ null, %L1 ]
238  ; CHECK: [[#@LINE-1]]:18: error: constant expression type mismatch: got type 'ptr addrspace(2)' but expected 'ptr'
239  ret ptr %p
240}
241
242; A blockaddress function forward-declaration used in a phi node should
243; create the forward declaration in the same address space as the current function
244;--- fwddecl-phi-good.ll
245define ptr addrspace(1) @f() addrspace(1) {
246L1:
247  br label %L3
248L2:
249  br label %L3
250L3:
251  %p = phi ptr addrspace(1) [ blockaddress(@fwddecl_as1, %bb), %L2 ], [ null, %L1 ]
252  ret ptr addrspace(1) %p
253L4:
254  unreachable
255}
256define void @fwddecl_as1() addrspace(1) {
257  unreachable
258bb:
259  ret void
260}
261
262;--- fwddecl-phi-bad.ll
263define ptr addrspace(2) @f() addrspace(2) {
264L1:
265  br label %L3
266L2:
267  br label %L3
268L3:
269  %p = phi ptr addrspace(2) [ blockaddress(@fwddecl_as1, %bb), %L2 ], [ null, %L1 ]
270  ; CHECK: [[#@LINE-1]]:58: error: 'bb' defined with type 'ptr addrspace(1)' but expected 'ptr addrspace(2)'
271  ret ptr addrspace(2) %p
272L4:
273  unreachable
274}
275define void @fwddecl_as1() addrspace(1) {
276  unreachable
277bb:
278  ret void
279}
280
281;--- bad-type-not-ptr.ll
282@global = constant i8 blockaddress(@unknown_fn, %bb)
283; CHECK: [[#@LINE-1]]:23: error: type of blockaddress must be a pointer and not 'i8'
284;--- bad-type-not-i8-ptr.ll
285@global = constant ptr blockaddress(@unknown_fn, %bb)
286; CHECK: [[#@LINE-1]]:37: error: expected function name in blockaddress
287