1; RUN: llc -mtriple=amdgcn-amd-amdhsa-amdgiz -mcpu=fiji -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
2; RUN: llc -mtriple=amdgcn-amd-amdhsa-amdgiz -mcpu=hawaii -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
3; RUN: llc -mtriple=amdgcn-amd-amdhsa-amdgiz -mcpu=gfx900 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
4
5declare void @external_void_func_void() #0
6
7declare i1 @external_i1_func_void() #0
8declare zeroext i1 @external_i1_zeroext_func_void() #0
9declare signext i1 @external_i1_signext_func_void() #0
10
11declare i8 @external_i8_func_void() #0
12declare zeroext i8 @external_i8_zeroext_func_void() #0
13declare signext i8 @external_i8_signext_func_void() #0
14
15declare i16 @external_i16_func_void() #0
16declare <2 x i16> @external_v2i16_func_void() #0
17declare <4 x i16> @external_v4i16_func_void() #0
18declare zeroext i16 @external_i16_zeroext_func_void() #0
19declare signext i16 @external_i16_signext_func_void() #0
20
21declare i32 @external_i32_func_void() #0
22declare i64 @external_i64_func_void() #0
23declare half @external_f16_func_void() #0
24declare float @external_f32_func_void() #0
25declare double @external_f64_func_void() #0
26
27declare <2 x half> @external_v2f16_func_void() #0
28declare <4 x half> @external_v4f16_func_void() #0
29declare <2 x double> @external_v2f64_func_void() #0
30
31declare <2 x i32> @external_v2i32_func_void() #0
32declare <3 x i32> @external_v3i32_func_void() #0
33declare <4 x i32> @external_v4i32_func_void() #0
34declare <5 x i32> @external_v5i32_func_void() #0
35declare <8 x i32> @external_v8i32_func_void() #0
36declare <16 x i32> @external_v16i32_func_void() #0
37declare <32 x i32> @external_v32i32_func_void() #0
38declare { <32 x i32>, i32 } @external_v32i32_i32_func_void() #0
39
40declare { i32, i64 } @external_i32_i64_func_void() #0
41
42; GCN-LABEL: {{^}}test_call_external_void_func_void:
43define amdgpu_kernel void @test_call_external_void_func_void() #0 {
44  call void @external_void_func_void()
45  ret void
46}
47
48; GCN-LABEL: {{^}}test_call_external_void_func_void_x2:
49define amdgpu_kernel void @test_call_external_void_func_void_x2() #0 {
50  call void @external_void_func_void()
51  call void @external_void_func_void()
52  ret void
53}
54
55; GCN-LABEL: {{^}}test_call_external_i1_func_void:
56define amdgpu_kernel void @test_call_external_i1_func_void() #0 {
57  %val = call i1 @external_i1_func_void()
58  store volatile i1 %val, i1 addrspace(1)* undef
59  ret void
60}
61
62; GCN-LABEL: {{^}}test_call_external_i1_zeroext_func_void:
63define amdgpu_kernel void @test_call_external_i1_zeroext_func_void() #0 {
64  %val = call i1 @external_i1_zeroext_func_void()
65  %val.ext = zext i1 %val to i32
66  store volatile i32 %val.ext, i32 addrspace(1)* undef
67  ret void
68}
69
70; GCN-LABEL: {{^}}test_call_external_i1_signext_func_void:
71define amdgpu_kernel void @test_call_external_i1_signext_func_void() #0 {
72  %val = call i1 @external_i1_signext_func_void()
73  %val.ext = zext i1 %val to i32
74  store volatile i32 %val.ext, i32 addrspace(1)* undef
75  ret void
76}
77
78; GCN-LABEL: {{^}}test_call_external_i8_func_void:
79define amdgpu_kernel void @test_call_external_i8_func_void() #0 {
80  %val = call i8 @external_i8_func_void()
81  store volatile i8 %val, i8 addrspace(1)* undef
82  ret void
83}
84
85; GCN-LABEL: {{^}}test_call_external_i8_zeroext_func_void:
86define amdgpu_kernel void @test_call_external_i8_zeroext_func_void() #0 {
87  %val = call i8 @external_i8_zeroext_func_void()
88  %val.ext = zext i8 %val to i32
89  store volatile i32 %val.ext, i32 addrspace(1)* undef
90  ret void
91}
92
93; GCN-LABEL: {{^}}test_call_external_i8_signext_func_void:
94define amdgpu_kernel void @test_call_external_i8_signext_func_void() #0 {
95  %val = call i8 @external_i8_signext_func_void()
96  %val.ext = zext i8 %val to i32
97  store volatile i32 %val.ext, i32 addrspace(1)* undef
98  ret void
99}
100
101; GCN-LABEL: {{^}}test_call_external_i16_func_void:
102define amdgpu_kernel void @test_call_external_i16_func_void() #0 {
103  %val = call i16 @external_i16_func_void()
104  store volatile i16 %val, i16 addrspace(1)* undef
105  ret void
106}
107
108; GCN-LABEL: {{^}}test_call_external_i16_zeroext_func_void:
109define amdgpu_kernel void @test_call_external_i16_zeroext_func_void() #0 {
110  %val = call i16 @external_i16_zeroext_func_void()
111  %val.ext = zext i16 %val to i32
112  store volatile i32 %val.ext, i32 addrspace(1)* undef
113  ret void
114}
115
116; GCN-LABEL: {{^}}test_call_external_i16_signext_func_void:
117define amdgpu_kernel void @test_call_external_i16_signext_func_void() #0 {
118  %val = call i16 @external_i16_signext_func_void()
119  %val.ext = zext i16 %val to i32
120  store volatile i32 %val.ext, i32 addrspace(1)* undef
121  ret void
122}
123
124; GCN-LABEL: {{^}}test_call_external_i32_func_void:
125define amdgpu_kernel void @test_call_external_i32_func_void() #0 {
126  %val = call i32 @external_i32_func_void()
127  store volatile i32 %val, i32 addrspace(1)* undef
128  ret void
129}
130
131; GCN-LABEL: {{^}}test_call_external_i64_func_void:
132define amdgpu_kernel void @test_call_external_i64_func_void() #0 {
133  %val = call i64 @external_i64_func_void()
134  store volatile i64 %val, i64 addrspace(1)* undef
135  ret void
136}
137
138; GCN-LABEL: {{^}}test_call_external_f16_func_void:
139define amdgpu_kernel void @test_call_external_f16_func_void() #0 {
140  %val = call half @external_f16_func_void()
141  store volatile half %val, half addrspace(1)* undef
142  ret void
143}
144
145; GCN-LABEL: {{^}}test_call_external_f32_func_void:
146define amdgpu_kernel void @test_call_external_f32_func_void() #0 {
147  %val = call float @external_f32_func_void()
148  store volatile float %val, float addrspace(1)* undef
149  ret void
150}
151
152; GCN-LABEL: {{^}}test_call_external_f64_func_void:
153define amdgpu_kernel void @test_call_external_f64_func_void() #0 {
154  %val = call double @external_f64_func_void()
155  store volatile double %val, double addrspace(1)* undef
156  ret void
157}
158
159; GCN-LABEL: {{^}}test_call_external_v2f64_func_void:
160define amdgpu_kernel void @test_call_external_v2f64_func_void() #0 {
161  %val = call <2 x double> @external_v2f64_func_void()
162  store volatile <2 x double> %val, <2 x double> addrspace(1)* undef
163  ret void
164}
165
166; GCN-LABEL: {{^}}test_call_external_v2i32_func_void:
167define amdgpu_kernel void @test_call_external_v2i32_func_void() #0 {
168  %val = call <2 x i32> @external_v2i32_func_void()
169  store volatile <2 x i32> %val, <2 x i32> addrspace(1)* undef
170  ret void
171}
172
173; GCN-LABEL: {{^}}test_call_external_v3i32_func_void:
174define amdgpu_kernel void @test_call_external_v3i32_func_void() #0 {
175  %val = call <3 x i32> @external_v3i32_func_void()
176  store volatile <3 x i32> %val, <3 x i32> addrspace(1)* undef, align 8
177  ret void
178}
179
180; GCN-LABEL: {{^}}test_call_external_v4i32_func_void:
181define amdgpu_kernel void @test_call_external_v4i32_func_void() #0 {
182  %val = call <4 x i32> @external_v4i32_func_void()
183  store volatile <4 x i32> %val, <4 x i32> addrspace(1)* undef, align 8
184  ret void
185}
186
187; GCN-LABEL: {{^}}test_call_external_v5i32_func_void:
188define amdgpu_kernel void @test_call_external_v5i32_func_void() #0 {
189  %val = call <5 x i32> @external_v5i32_func_void()
190  store volatile <5 x i32> %val, <5 x i32> addrspace(1)* undef, align 8
191  ret void
192}
193
194; GCN-LABEL: {{^}}test_call_external_v8i32_func_void:
195define amdgpu_kernel void @test_call_external_v8i32_func_void() #0 {
196  %val = call <8 x i32> @external_v8i32_func_void()
197  store volatile <8 x i32> %val, <8 x i32> addrspace(1)* undef, align 8
198  ret void
199}
200
201; GCN-LABEL: {{^}}test_call_external_v16i32_func_void:
202define amdgpu_kernel void @test_call_external_v16i32_func_void() #0 {
203  %val = call <16 x i32> @external_v16i32_func_void()
204  store volatile <16 x i32> %val, <16 x i32> addrspace(1)* undef, align 8
205  ret void
206}
207
208; GCN-LABEL: {{^}}test_call_external_v32i32_func_void:
209define amdgpu_kernel void @test_call_external_v32i32_func_void() #0 {
210  %val = call <32 x i32> @external_v32i32_func_void()
211  store volatile <32 x i32> %val, <32 x i32> addrspace(1)* undef, align 8
212  ret void
213}
214
215; GCN-LABEL: {{^}}test_call_external_v2i16_func_void:
216define amdgpu_kernel void @test_call_external_v2i16_func_void() #0 {
217  %val = call <2 x i16> @external_v2i16_func_void()
218  store volatile <2 x i16> %val, <2 x i16> addrspace(1)* undef
219  ret void
220}
221
222; GCN-LABEL: {{^}}test_call_external_v4i16_func_void:
223define amdgpu_kernel void @test_call_external_v4i16_func_void() #0 {
224  %val = call <4 x i16> @external_v4i16_func_void()
225  store volatile <4 x i16> %val, <4 x i16> addrspace(1)* undef
226  ret void
227}
228
229; GCN-LABEL: {{^}}test_call_external_v2f16_func_void:
230define amdgpu_kernel void @test_call_external_v2f16_func_void() #0 {
231  %val = call <2 x half> @external_v2f16_func_void()
232  store volatile <2 x half> %val, <2 x half> addrspace(1)* undef
233  ret void
234}
235
236; GCN-LABEL: {{^}}test_call_external_v4f16_func_void:
237define amdgpu_kernel void @test_call_external_v4f16_func_void() #0 {
238  %val = call <4 x half> @external_v4f16_func_void()
239  store volatile <4 x half> %val, <4 x half> addrspace(1)* undef
240  ret void
241}
242
243; GCN-LABEL: {{^}}test_call_external_i32_i64_func_void:
244define amdgpu_kernel void @test_call_external_i32_i64_func_void() #0 {
245  %val = call { i32, i64 } @external_i32_i64_func_void()
246  %val.0 = extractvalue { i32, i64 } %val, 0
247  %val.1 = extractvalue { i32, i64 } %val, 1
248  store volatile i32 %val.0, i32 addrspace(1)* undef
249  store volatile i64 %val.1, i64 addrspace(1)* undef
250  ret void
251}
252
253; Requires writing results to stack
254; GCN-LABEL: {{^}}test_call_external_v32i32_i32_func_void:
255define amdgpu_kernel void @test_call_external_v32i32_i32_func_void() #0 {
256  %val = call { <32 x i32>, i32 } @external_v32i32_i32_func_void()
257  %val0 = extractvalue { <32 x i32>, i32 } %val, 0
258  %val1 = extractvalue { <32 x i32>, i32 } %val, 1
259  store volatile <32 x i32> %val0, <32 x i32> addrspace(1)* undef, align 8
260  store volatile i32 %val1, i32 addrspace(1)* undef
261  ret void
262}
263
264attributes #0 = { nounwind }
265attributes #1 = { nounwind readnone }
266attributes #2 = { nounwind noinline }
267