[mlir] Update Ch-2.md (#121379)
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / expand-variadic-call.ll
blobcca70005b4cdc1c05fb0f190d4cd1777c28c9602
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: -p --function-signature
2 ; RUN: opt -S --passes=expand-variadics --expand-variadics-override=lowering < %s | FileCheck %s
3 target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
4 target triple = "amdgcn-amd-amdhsa"
6 ; Check the variables are lowered to the locations this target expects
8 ; The types show the call frames
9 ; CHECK: %single_i32.vararg = type <{ i32 }>
10 ; CHECK: %single_double.vararg = type <{ double }>
11 ; CHECK: %single_v4f32.vararg = type <{ <4 x float> }>
12 ; CHECK: %single_v8f32.vararg = type <{ <8 x float> }>
13 ; CHECK: %single_v16f32.vararg = type <{ <16 x float> }>
14 ; CHECK: %single_v32f32.vararg = type <{ <32 x float> }>
15 ; CHECK: %i32_double.vararg = type <{ i32, double }>
16 ; CHECK: %double_i32.vararg = type <{ double, i32 }>
17 ; CHECK: %i32_libcS.vararg = type <{ i32, %struct.libcS }>
18 ; CHECK: %libcS_i32.vararg = type <{ %struct.libcS, i32 }>
19 ; CHECK: %i32_v4f32.vararg = type <{ i32, <4 x float> }>
20 ; CHECK: %v4f32_i32.vararg = type <{ <4 x float>, i32 }>
21 ; CHECK: %i32_v8f32.vararg = type <{ i32, <8 x float> }>
22 ; CHECK: %v8f32_i32.vararg = type <{ <8 x float>, i32 }>
23 ; CHECK: %i32_v16f32.vararg = type <{ i32, <16 x float> }>
24 ; CHECK: %v16f32_i32.vararg = type <{ <16 x float>, i32 }>
25 ; CHECK: %i32_v32f32.vararg = type <{ i32, <32 x float> }>
26 ; CHECK: %v32f32_i32.vararg = type <{ <32 x float>, i32 }>
27 ; CHECK: %fptr_single_i32.vararg = type <{ i32 }>
28 ; CHECK: %fptr_libcS.vararg = type <{ %struct.libcS }>
30 %struct.libcS = type { i8, i16, i32, i64, float, double }
32 @vararg_ptr = hidden addrspace(1) global ptr @vararg, align 8
34 define hidden void @copy(ptr noundef %va) {
35 ; CHECK-LABEL: define {{[^@]+}}@copy(ptr noundef %va) {
36 ; CHECK-NEXT:  entry:
37 ; CHECK-NEXT:    %va.addr = alloca ptr, align 8, addrspace(5)
38 ; CHECK-NEXT:    %cp = alloca ptr, align 8, addrspace(5)
39 ; CHECK-NEXT:    %va.addr.ascast = addrspacecast ptr addrspace(5) %va.addr to ptr
40 ; CHECK-NEXT:    %cp.ascast = addrspacecast ptr addrspace(5) %cp to ptr
41 ; CHECK-NEXT:    store ptr %va, ptr addrspace(5) %va.addr, align 8
42 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %cp)
43 ; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr %cp.ascast, ptr %va.addr.ascast, i32 8, i1 false)
44 ; CHECK-NEXT:    %0 = load ptr, ptr addrspace(5) %cp, align 8
45 ; CHECK-NEXT:    call void @valist(ptr noundef %0)
46 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %cp)
47 ; CHECK-NEXT:    ret void
49 entry:
50   %va.addr = alloca ptr, align 8, addrspace(5)
51   %cp = alloca ptr, align 8, addrspace(5)
52   %va.addr.ascast = addrspacecast ptr addrspace(5) %va.addr to ptr
53   %cp.ascast = addrspacecast ptr addrspace(5) %cp to ptr
54   store ptr %va, ptr addrspace(5) %va.addr, align 8
55   call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %cp)
56   call void @llvm.va_copy.p0(ptr %cp.ascast, ptr nonnull %va.addr.ascast)
57   %0 = load ptr, ptr addrspace(5) %cp, align 8
58   call void @valist(ptr noundef %0)
59   call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %cp)
60   ret void
63 declare void @llvm.lifetime.start.p5(i64 immarg, ptr addrspace(5) nocapture)
65 declare void @llvm.va_copy.p0(ptr, ptr)
67 declare hidden void @valist(ptr noundef)
69 declare void @llvm.lifetime.end.p5(i64 immarg, ptr addrspace(5) nocapture)
71 define hidden void @start_once(...) {
72 ; CHECK-LABEL: define {{[^@]+}}@start_once(ptr %varargs) {
73 ; CHECK-NEXT:  entry:
74 ; CHECK-NEXT:    %s = alloca ptr, align 8, addrspace(5)
75 ; CHECK-NEXT:    %s.ascast = addrspacecast ptr addrspace(5) %s to ptr
76 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %s)
77 ; CHECK-NEXT:    store ptr %varargs, ptr %s.ascast, align 8
78 ; CHECK-NEXT:    %0 = load ptr, ptr addrspace(5) %s, align 8
79 ; CHECK-NEXT:    call void @valist(ptr noundef %0)
80 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %s)
81 ; CHECK-NEXT:    ret void
83 entry:
84   %s = alloca ptr, align 8, addrspace(5)
85   %s.ascast = addrspacecast ptr addrspace(5) %s to ptr
86   call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %s)
87   call void @llvm.va_start.p0(ptr %s.ascast)
88   %0 = load ptr, ptr addrspace(5) %s, align 8
89   call void @valist(ptr noundef %0)
90   call void @llvm.va_end.p0(ptr %s.ascast)
91   call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %s)
92   ret void
95 declare void @llvm.va_start.p0(ptr)
97 declare void @llvm.va_end.p0(ptr)
99 define hidden void @start_twice(...) {
100 ; CHECK-LABEL: define {{[^@]+}}@start_twice(ptr %varargs) {
101 ; CHECK-NEXT:  entry:
102 ; CHECK-NEXT:    %s0 = alloca ptr, align 8, addrspace(5)
103 ; CHECK-NEXT:    %s1 = alloca ptr, align 8, addrspace(5)
104 ; CHECK-NEXT:    %s0.ascast = addrspacecast ptr addrspace(5) %s0 to ptr
105 ; CHECK-NEXT:    %s1.ascast = addrspacecast ptr addrspace(5) %s1 to ptr
106 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %s0)
107 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %s1)
108 ; CHECK-NEXT:    store ptr %varargs, ptr %s0.ascast, align 8
109 ; CHECK-NEXT:    %0 = load ptr, ptr addrspace(5) %s0, align 8
110 ; CHECK-NEXT:    call void @valist(ptr noundef %0)
111 ; CHECK-NEXT:    store ptr %varargs, ptr %s1.ascast, align 8
112 ; CHECK-NEXT:    %1 = load ptr, ptr addrspace(5) %s1, align 8
113 ; CHECK-NEXT:    call void @valist(ptr noundef %1)
114 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %s1)
115 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %s0)
116 ; CHECK-NEXT:    ret void
118 entry:
119   %s0 = alloca ptr, align 8, addrspace(5)
120   %s1 = alloca ptr, align 8, addrspace(5)
121   %s0.ascast = addrspacecast ptr addrspace(5) %s0 to ptr
122   %s1.ascast = addrspacecast ptr addrspace(5) %s1 to ptr
123   call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %s0)
124   call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %s1)
125   call void @llvm.va_start.p0(ptr %s0.ascast)
126   %0 = load ptr, ptr addrspace(5) %s0, align 8
127   call void @valist(ptr noundef %0)
128   call void @llvm.va_end.p0(ptr %s0.ascast)
129   call void @llvm.va_start.p0(ptr %s1.ascast)
130   %1 = load ptr, ptr addrspace(5) %s1, align 8
131   call void @valist(ptr noundef %1)
132   call void @llvm.va_end.p0(ptr %s1.ascast)
133   call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %s1)
134   call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %s0)
135   ret void
138 define hidden void @single_i32(i32 noundef %x) {
139 ; CHECK-LABEL: define {{[^@]+}}@single_i32(i32 noundef %x) {
140 ; CHECK-NEXT:  entry:
141 ; CHECK-NEXT:    %vararg_buffer = alloca %single_i32.vararg, align 4, addrspace(5)
142 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 4, ptr addrspace(5) %vararg_buffer)
143 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
144 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
145 ; CHECK-NEXT:    %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
146 ; CHECK-NEXT:    call void @vararg(ptr %1)
147 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 4, ptr addrspace(5) %vararg_buffer)
148 ; CHECK-NEXT:    ret void
150 entry:
151   tail call void (...) @vararg(i32 noundef %x)
152   ret void
155 declare hidden void @vararg(...)
157 define hidden void @single_double(double noundef %x) {
158 ; CHECK-LABEL: define {{[^@]+}}@single_double(double noundef %x) {
159 ; CHECK-NEXT:  entry:
160 ; CHECK-NEXT:    %vararg_buffer = alloca %single_double.vararg, align 4, addrspace(5)
161 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) %vararg_buffer)
162 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_double.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
163 ; CHECK-NEXT:    store double %x, ptr addrspace(5) %0, align 8
164 ; CHECK-NEXT:    %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
165 ; CHECK-NEXT:    call void @vararg(ptr %1)
166 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 8, ptr addrspace(5) %vararg_buffer)
167 ; CHECK-NEXT:    ret void
169 entry:
170   tail call void (...) @vararg(double noundef %x)
171   ret void
174 define hidden void @single_v4f32(<4 x float> noundef %x) {
175 ; CHECK-LABEL: define {{[^@]+}}@single_v4f32(<4 x float> noundef %x) {
176 ; CHECK-NEXT:  entry:
177 ; CHECK-NEXT:    %vararg_buffer = alloca %single_v4f32.vararg, align 4, addrspace(5)
178 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 16, ptr addrspace(5) %vararg_buffer)
179 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v4f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
180 ; CHECK-NEXT:    store <4 x float> %x, ptr addrspace(5) %0, align 16
181 ; CHECK-NEXT:    %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
182 ; CHECK-NEXT:    call void @vararg(ptr %1)
183 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 16, ptr addrspace(5) %vararg_buffer)
184 ; CHECK-NEXT:    ret void
186 entry:
187   tail call void (...) @vararg(<4 x float> noundef %x)
188   ret void
191 define hidden void @single_v8f32(<8 x float> noundef %x) {
192 ; CHECK-LABEL: define {{[^@]+}}@single_v8f32(<8 x float> noundef %x) {
193 ; CHECK-NEXT:  entry:
194 ; CHECK-NEXT:    %vararg_buffer = alloca %single_v8f32.vararg, align 4, addrspace(5)
195 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 32, ptr addrspace(5) %vararg_buffer)
196 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v8f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
197 ; CHECK-NEXT:    store <8 x float> %x, ptr addrspace(5) %0, align 32
198 ; CHECK-NEXT:    %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
199 ; CHECK-NEXT:    call void @vararg(ptr %1)
200 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 32, ptr addrspace(5) %vararg_buffer)
201 ; CHECK-NEXT:    ret void
203 entry:
204   tail call void (...) @vararg(<8 x float> noundef %x)
205   ret void
208 define hidden void @single_v16f32(<16 x float> noundef %x) {
209 ; CHECK-LABEL: define {{[^@]+}}@single_v16f32(<16 x float> noundef %x) {
210 ; CHECK-NEXT:  entry:
211 ; CHECK-NEXT:    %vararg_buffer = alloca %single_v16f32.vararg, align 4, addrspace(5)
212 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 64, ptr addrspace(5) %vararg_buffer)
213 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v16f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
214 ; CHECK-NEXT:    store <16 x float> %x, ptr addrspace(5) %0, align 64
215 ; CHECK-NEXT:    %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
216 ; CHECK-NEXT:    call void @vararg(ptr %1)
217 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 64, ptr addrspace(5) %vararg_buffer)
218 ; CHECK-NEXT:    ret void
220 entry:
221   tail call void (...) @vararg(<16 x float> noundef %x)
222   ret void
225 define hidden void @single_v32f32(<32 x float> noundef %x) {
226 ; CHECK-LABEL: define {{[^@]+}}@single_v32f32(<32 x float> noundef %x) {
227 ; CHECK-NEXT:  entry:
228 ; CHECK-NEXT:    %vararg_buffer = alloca %single_v32f32.vararg, align 4, addrspace(5)
229 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 128, ptr addrspace(5) %vararg_buffer)
230 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %single_v32f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
231 ; CHECK-NEXT:    store <32 x float> %x, ptr addrspace(5) %0, align 128
232 ; CHECK-NEXT:    %1 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
233 ; CHECK-NEXT:    call void @vararg(ptr %1)
234 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 128, ptr addrspace(5) %vararg_buffer)
235 ; CHECK-NEXT:    ret void
237 entry:
238   tail call void (...) @vararg(<32 x float> noundef %x)
239   ret void
242 define hidden void @i32_double(i32 noundef %x, double noundef %y) {
243 ; CHECK-LABEL: define {{[^@]+}}@i32_double(i32 noundef %x, double noundef %y) {
244 ; CHECK-NEXT:  entry:
245 ; CHECK-NEXT:    %vararg_buffer = alloca %i32_double.vararg, align 4, addrspace(5)
246 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 12, ptr addrspace(5) %vararg_buffer)
247 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_double.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
248 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
249 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_double.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
250 ; CHECK-NEXT:    store double %y, ptr addrspace(5) %1, align 8
251 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
252 ; CHECK-NEXT:    call void @vararg(ptr %2)
253 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 12, ptr addrspace(5) %vararg_buffer)
254 ; CHECK-NEXT:    ret void
256 entry:
257   tail call void (...) @vararg(i32 noundef %x, double noundef %y)
258   ret void
261 define hidden void @double_i32(double noundef %x, i32 noundef %y) {
262 ; CHECK-LABEL: define {{[^@]+}}@double_i32(double noundef %x, i32 noundef %y) {
263 ; CHECK-NEXT:  entry:
264 ; CHECK-NEXT:    %vararg_buffer = alloca %double_i32.vararg, align 4, addrspace(5)
265 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 12, ptr addrspace(5) %vararg_buffer)
266 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %double_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
267 ; CHECK-NEXT:    store double %x, ptr addrspace(5) %0, align 8
268 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %double_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
269 ; CHECK-NEXT:    store i32 %y, ptr addrspace(5) %1, align 4
270 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
271 ; CHECK-NEXT:    call void @vararg(ptr %2)
272 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 12, ptr addrspace(5) %vararg_buffer)
273 ; CHECK-NEXT:    ret void
275 entry:
276   tail call void (...) @vararg(double noundef %x, i32 noundef %y)
277   ret void
280 define hidden void @i32_libcS(i32 noundef %x, i8 %y.coerce0, i16 %y.coerce1, i32 %y.coerce2, i64 %y.coerce3, float %y.coerce4, double %y.coerce5) {
281 ; CHECK-LABEL: define {{[^@]+}}@i32_libcS(i32 noundef %x, i8 %y.coerce0, i16 %y.coerce1, i32 %y.coerce2, i64 %y.coerce3, float %y.coerce4, double %y.coerce5) {
282 ; CHECK-NEXT:  entry:
283 ; CHECK-NEXT:    %vararg_buffer = alloca %i32_libcS.vararg, align 4, addrspace(5)
284 ; CHECK-NEXT:    %.fca.0.insert = insertvalue %struct.libcS poison, i8 %y.coerce0, 0
285 ; CHECK-NEXT:    %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %y.coerce1, 1
286 ; CHECK-NEXT:    %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %y.coerce2, 2
287 ; CHECK-NEXT:    %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %y.coerce3, 3
288 ; CHECK-NEXT:    %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %y.coerce4, 4
289 ; CHECK-NEXT:    %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %y.coerce5, 5
290 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 36, ptr addrspace(5) %vararg_buffer)
291 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_libcS.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
292 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
293 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_libcS.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
294 ; CHECK-NEXT:    store %struct.libcS %.fca.5.insert, ptr addrspace(5) %1, align 8
295 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
296 ; CHECK-NEXT:    call void @vararg(ptr %2)
297 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 36, ptr addrspace(5) %vararg_buffer)
298 ; CHECK-NEXT:    ret void
300 entry:
301   %.fca.0.insert = insertvalue %struct.libcS poison, i8 %y.coerce0, 0
302   %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %y.coerce1, 1
303   %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %y.coerce2, 2
304   %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %y.coerce3, 3
305   %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %y.coerce4, 4
306   %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %y.coerce5, 5
307   tail call void (...) @vararg(i32 noundef %x, %struct.libcS %.fca.5.insert)
308   ret void
311 define hidden void @libcS_i32(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5, i32 noundef %y) {
312 ; CHECK-LABEL: define {{[^@]+}}@libcS_i32(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5, i32 noundef %y) {
313 ; CHECK-NEXT:  entry:
314 ; CHECK-NEXT:    %vararg_buffer = alloca %libcS_i32.vararg, align 4, addrspace(5)
315 ; CHECK-NEXT:    %.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
316 ; CHECK-NEXT:    %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
317 ; CHECK-NEXT:    %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
318 ; CHECK-NEXT:    %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
319 ; CHECK-NEXT:    %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
320 ; CHECK-NEXT:    %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
321 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 36, ptr addrspace(5) %vararg_buffer)
322 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %libcS_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
323 ; CHECK-NEXT:    store %struct.libcS %.fca.5.insert, ptr addrspace(5) %0, align 8
324 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %libcS_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
325 ; CHECK-NEXT:    store i32 %y, ptr addrspace(5) %1, align 4
326 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
327 ; CHECK-NEXT:    call void @vararg(ptr %2)
328 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 36, ptr addrspace(5) %vararg_buffer)
329 ; CHECK-NEXT:    ret void
331 entry:
332   %.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
333   %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
334   %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
335   %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
336   %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
337   %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
338   tail call void (...) @vararg(%struct.libcS %.fca.5.insert, i32 noundef %y)
339   ret void
342 define hidden void @i32_v4f32(i32 noundef %x, <4 x float> noundef %y) {
343 ; CHECK-LABEL: define {{[^@]+}}@i32_v4f32(i32 noundef %x, <4 x float> noundef %y) {
344 ; CHECK-NEXT:  entry:
345 ; CHECK-NEXT:    %vararg_buffer = alloca %i32_v4f32.vararg, align 4, addrspace(5)
346 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 20, ptr addrspace(5) %vararg_buffer)
347 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
348 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
349 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v4f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
350 ; CHECK-NEXT:    store <4 x float> %y, ptr addrspace(5) %1, align 16
351 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
352 ; CHECK-NEXT:    call void @vararg(ptr %2)
353 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 20, ptr addrspace(5) %vararg_buffer)
354 ; CHECK-NEXT:    ret void
356 entry:
357   tail call void (...) @vararg(i32 noundef %x, <4 x float> noundef %y)
358   ret void
361 define hidden void @v4f32_i32(<4 x float> noundef %x, i32 noundef %y) {
362 ; CHECK-LABEL: define {{[^@]+}}@v4f32_i32(<4 x float> noundef %x, i32 noundef %y) {
363 ; CHECK-NEXT:  entry:
364 ; CHECK-NEXT:    %vararg_buffer = alloca %v4f32_i32.vararg, align 4, addrspace(5)
365 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 20, ptr addrspace(5) %vararg_buffer)
366 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
367 ; CHECK-NEXT:    store <4 x float> %x, ptr addrspace(5) %0, align 16
368 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v4f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
369 ; CHECK-NEXT:    store i32 %y, ptr addrspace(5) %1, align 4
370 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
371 ; CHECK-NEXT:    call void @vararg(ptr %2)
372 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 20, ptr addrspace(5) %vararg_buffer)
373 ; CHECK-NEXT:    ret void
375 entry:
376   tail call void (...) @vararg(<4 x float> noundef %x, i32 noundef %y)
377   ret void
380 define hidden void @i32_v8f32(i32 noundef %x, <8 x float> noundef %y) {
381 ; CHECK-LABEL: define {{[^@]+}}@i32_v8f32(i32 noundef %x, <8 x float> noundef %y) {
382 ; CHECK-NEXT:  entry:
383 ; CHECK-NEXT:    %vararg_buffer = alloca %i32_v8f32.vararg, align 4, addrspace(5)
384 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 36, ptr addrspace(5) %vararg_buffer)
385 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
386 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
387 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v8f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
388 ; CHECK-NEXT:    store <8 x float> %y, ptr addrspace(5) %1, align 32
389 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
390 ; CHECK-NEXT:    call void @vararg(ptr %2)
391 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 36, ptr addrspace(5) %vararg_buffer)
392 ; CHECK-NEXT:    ret void
394 entry:
395   tail call void (...) @vararg(i32 noundef %x, <8 x float> noundef %y)
396   ret void
399 define hidden void @v8f32_i32(<8 x float> noundef %x, i32 noundef %y) {
400 ; CHECK-LABEL: define {{[^@]+}}@v8f32_i32(<8 x float> noundef %x, i32 noundef %y) {
401 ; CHECK-NEXT:  entry:
402 ; CHECK-NEXT:    %vararg_buffer = alloca %v8f32_i32.vararg, align 4, addrspace(5)
403 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 36, ptr addrspace(5) %vararg_buffer)
404 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
405 ; CHECK-NEXT:    store <8 x float> %x, ptr addrspace(5) %0, align 32
406 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v8f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
407 ; CHECK-NEXT:    store i32 %y, ptr addrspace(5) %1, align 4
408 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
409 ; CHECK-NEXT:    call void @vararg(ptr %2)
410 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 36, ptr addrspace(5) %vararg_buffer)
411 ; CHECK-NEXT:    ret void
413 entry:
414   tail call void (...) @vararg(<8 x float> noundef %x, i32 noundef %y)
415   ret void
418 define hidden void @i32_v16f32(i32 noundef %x, <16 x float> noundef %y) {
419 ; CHECK-LABEL: define {{[^@]+}}@i32_v16f32(i32 noundef %x, <16 x float> noundef %y) {
420 ; CHECK-NEXT:  entry:
421 ; CHECK-NEXT:    %vararg_buffer = alloca %i32_v16f32.vararg, align 4, addrspace(5)
422 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 68, ptr addrspace(5) %vararg_buffer)
423 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
424 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
425 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v16f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
426 ; CHECK-NEXT:    store <16 x float> %y, ptr addrspace(5) %1, align 64
427 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
428 ; CHECK-NEXT:    call void @vararg(ptr %2)
429 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 68, ptr addrspace(5) %vararg_buffer)
430 ; CHECK-NEXT:    ret void
432 entry:
433   tail call void (...) @vararg(i32 noundef %x, <16 x float> noundef %y)
434   ret void
437 define hidden void @v16f32_i32(<16 x float> noundef %x, i32 noundef %y) {
438 ; CHECK-LABEL: define {{[^@]+}}@v16f32_i32(<16 x float> noundef %x, i32 noundef %y) {
439 ; CHECK-NEXT:  entry:
440 ; CHECK-NEXT:    %vararg_buffer = alloca %v16f32_i32.vararg, align 4, addrspace(5)
441 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 68, ptr addrspace(5) %vararg_buffer)
442 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
443 ; CHECK-NEXT:    store <16 x float> %x, ptr addrspace(5) %0, align 64
444 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v16f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
445 ; CHECK-NEXT:    store i32 %y, ptr addrspace(5) %1, align 4
446 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
447 ; CHECK-NEXT:    call void @vararg(ptr %2)
448 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 68, ptr addrspace(5) %vararg_buffer)
449 ; CHECK-NEXT:    ret void
451 entry:
452   tail call void (...) @vararg(<16 x float> noundef %x, i32 noundef %y)
453   ret void
456 define hidden void @i32_v32f32(i32 noundef %x, <32 x float> noundef %y) {
457 ; CHECK-LABEL: define {{[^@]+}}@i32_v32f32(i32 noundef %x, <32 x float> noundef %y) {
458 ; CHECK-NEXT:  entry:
459 ; CHECK-NEXT:    %vararg_buffer = alloca %i32_v32f32.vararg, align 4, addrspace(5)
460 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 132, ptr addrspace(5) %vararg_buffer)
461 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
462 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %0, align 4
463 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %i32_v32f32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
464 ; CHECK-NEXT:    store <32 x float> %y, ptr addrspace(5) %1, align 128
465 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
466 ; CHECK-NEXT:    call void @vararg(ptr %2)
467 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 132, ptr addrspace(5) %vararg_buffer)
468 ; CHECK-NEXT:    ret void
470 entry:
471   tail call void (...) @vararg(i32 noundef %x, <32 x float> noundef %y)
472   ret void
475 define hidden void @v32f32_i32(<32 x float> noundef %x, i32 noundef %y) {
476 ; CHECK-LABEL: define {{[^@]+}}@v32f32_i32(<32 x float> noundef %x, i32 noundef %y) {
477 ; CHECK-NEXT:  entry:
478 ; CHECK-NEXT:    %vararg_buffer = alloca %v32f32_i32.vararg, align 4, addrspace(5)
479 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 132, ptr addrspace(5) %vararg_buffer)
480 ; CHECK-NEXT:    %0 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
481 ; CHECK-NEXT:    store <32 x float> %x, ptr addrspace(5) %0, align 128
482 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %v32f32_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 1
483 ; CHECK-NEXT:    store i32 %y, ptr addrspace(5) %1, align 4
484 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
485 ; CHECK-NEXT:    call void @vararg(ptr %2)
486 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 132, ptr addrspace(5) %vararg_buffer)
487 ; CHECK-NEXT:    ret void
489 entry:
490   tail call void (...) @vararg(<32 x float> noundef %x, i32 noundef %y)
491   ret void
494 define hidden void @fptr_single_i32(i32 noundef %x) {
495 ; CHECK-LABEL: define {{[^@]+}}@fptr_single_i32(i32 noundef %x) {
496 ; CHECK-NEXT:  entry:
497 ; CHECK-NEXT:    %vararg_buffer = alloca %fptr_single_i32.vararg, align 4, addrspace(5)
498 ; CHECK-NEXT:    %0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
499 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 4, ptr addrspace(5) %vararg_buffer)
500 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %fptr_single_i32.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
501 ; CHECK-NEXT:    store i32 %x, ptr addrspace(5) %1, align 4
502 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
503 ; CHECK-NEXT:    call void %0(ptr %2)
504 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 4, ptr addrspace(5) %vararg_buffer)
505 ; CHECK-NEXT:    ret void
507 entry:
508   %0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
509   tail call void (...) %0(i32 noundef %x)
510   ret void
513 define hidden void @fptr_libcS(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5) {
514 ; CHECK-LABEL: define {{[^@]+}}@fptr_libcS(i8 %x.coerce0, i16 %x.coerce1, i32 %x.coerce2, i64 %x.coerce3, float %x.coerce4, double %x.coerce5) {
515 ; CHECK-NEXT:  entry:
516 ; CHECK-NEXT:    %vararg_buffer = alloca %fptr_libcS.vararg, align 4, addrspace(5)
517 ; CHECK-NEXT:    %0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
518 ; CHECK-NEXT:    %.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
519 ; CHECK-NEXT:    %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
520 ; CHECK-NEXT:    %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
521 ; CHECK-NEXT:    %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
522 ; CHECK-NEXT:    %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
523 ; CHECK-NEXT:    %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
524 ; CHECK-NEXT:    call void @llvm.lifetime.start.p5(i64 32, ptr addrspace(5) %vararg_buffer)
525 ; CHECK-NEXT:    %1 = getelementptr inbounds nuw %fptr_libcS.vararg, ptr addrspace(5) %vararg_buffer, i32 0, i32 0
526 ; CHECK-NEXT:    store %struct.libcS %.fca.5.insert, ptr addrspace(5) %1, align 8
527 ; CHECK-NEXT:    %2 = addrspacecast ptr addrspace(5) %vararg_buffer to ptr
528 ; CHECK-NEXT:    call void %0(ptr %2)
529 ; CHECK-NEXT:    call void @llvm.lifetime.end.p5(i64 32, ptr addrspace(5) %vararg_buffer)
530 ; CHECK-NEXT:    ret void
532 entry:
533   %0 = load volatile ptr, ptr addrspacecast (ptr addrspace(1) @vararg_ptr to ptr), align 8
534   %.fca.0.insert = insertvalue %struct.libcS poison, i8 %x.coerce0, 0
535   %.fca.1.insert = insertvalue %struct.libcS %.fca.0.insert, i16 %x.coerce1, 1
536   %.fca.2.insert = insertvalue %struct.libcS %.fca.1.insert, i32 %x.coerce2, 2
537   %.fca.3.insert = insertvalue %struct.libcS %.fca.2.insert, i64 %x.coerce3, 3
538   %.fca.4.insert = insertvalue %struct.libcS %.fca.3.insert, float %x.coerce4, 4
539   %.fca.5.insert = insertvalue %struct.libcS %.fca.4.insert, double %x.coerce5, 5
540   tail call void (...) %0(%struct.libcS %.fca.5.insert)
541   ret void