1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
4 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
5 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
7 declare void @llvm.va_start(i8*)
8 declare void @llvm.va_end(i8*)
10 declare void @notdead(i8*)
12 ; Although frontends are recommended to not generate va_arg due to the lack of
13 ; support for aggregate types, we test simple cases here to ensure they are
16 define i32 @va1(i8* %fmt, ...) nounwind {
17 ; RV32I-FPELIM-LABEL: va1:
18 ; RV32I-FPELIM: # %bb.0:
19 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
20 ; RV32I-FPELIM-NEXT: mv a0, a1
21 ; RV32I-FPELIM-NEXT: sw a7, 44(sp)
22 ; RV32I-FPELIM-NEXT: sw a6, 40(sp)
23 ; RV32I-FPELIM-NEXT: sw a5, 36(sp)
24 ; RV32I-FPELIM-NEXT: sw a4, 32(sp)
25 ; RV32I-FPELIM-NEXT: sw a3, 28(sp)
26 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
27 ; RV32I-FPELIM-NEXT: addi a1, sp, 24
28 ; RV32I-FPELIM-NEXT: sw a1, 12(sp)
29 ; RV32I-FPELIM-NEXT: sw a0, 20(sp)
30 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
31 ; RV32I-FPELIM-NEXT: ret
33 ; RV32I-WITHFP-LABEL: va1:
34 ; RV32I-WITHFP: # %bb.0:
35 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
36 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
37 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
38 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
39 ; RV32I-WITHFP-NEXT: mv a0, a1
40 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
41 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
42 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
43 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
44 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
45 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
46 ; RV32I-WITHFP-NEXT: addi a1, s0, 8
47 ; RV32I-WITHFP-NEXT: sw a1, -12(s0)
48 ; RV32I-WITHFP-NEXT: sw a0, 4(s0)
49 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
50 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
51 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
52 ; RV32I-WITHFP-NEXT: ret
53 %va = alloca i8*, align 4
54 %1 = bitcast i8** %va to i8*
55 call void @llvm.va_start(i8* %1)
56 %argp.cur = load i8*, i8** %va, align 4
57 %argp.next = getelementptr inbounds i8, i8* %argp.cur, i32 4
58 store i8* %argp.next, i8** %va, align 4
59 %2 = bitcast i8* %argp.cur to i32*
60 %3 = load i32, i32* %2, align 4
61 call void @llvm.va_end(i8* %1)
65 define i32 @va1_va_arg(i8* %fmt, ...) nounwind {
66 ; RV32I-FPELIM-LABEL: va1_va_arg:
67 ; RV32I-FPELIM: # %bb.0:
68 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
69 ; RV32I-FPELIM-NEXT: mv a0, a1
70 ; RV32I-FPELIM-NEXT: sw a7, 44(sp)
71 ; RV32I-FPELIM-NEXT: sw a6, 40(sp)
72 ; RV32I-FPELIM-NEXT: sw a5, 36(sp)
73 ; RV32I-FPELIM-NEXT: sw a4, 32(sp)
74 ; RV32I-FPELIM-NEXT: sw a3, 28(sp)
75 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
76 ; RV32I-FPELIM-NEXT: addi a1, sp, 24
77 ; RV32I-FPELIM-NEXT: sw a1, 12(sp)
78 ; RV32I-FPELIM-NEXT: sw a0, 20(sp)
79 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
80 ; RV32I-FPELIM-NEXT: ret
82 ; RV32I-WITHFP-LABEL: va1_va_arg:
83 ; RV32I-WITHFP: # %bb.0:
84 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
85 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
86 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
87 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
88 ; RV32I-WITHFP-NEXT: mv a0, a1
89 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
90 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
91 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
92 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
93 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
94 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
95 ; RV32I-WITHFP-NEXT: addi a1, s0, 8
96 ; RV32I-WITHFP-NEXT: sw a1, -12(s0)
97 ; RV32I-WITHFP-NEXT: sw a0, 4(s0)
98 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
99 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
100 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
101 ; RV32I-WITHFP-NEXT: ret
102 %va = alloca i8*, align 4
103 %1 = bitcast i8** %va to i8*
104 call void @llvm.va_start(i8* %1)
105 %2 = va_arg i8** %va, i32
106 call void @llvm.va_end(i8* %1)
110 ; Ensure the adjustment when restoring the stack pointer using the frame
112 define i32 @va1_va_arg_alloca(i8* %fmt, ...) nounwind {
113 ; RV32I-FPELIM-LABEL: va1_va_arg_alloca:
114 ; RV32I-FPELIM: # %bb.0:
115 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
116 ; RV32I-FPELIM-NEXT: sw ra, 12(sp)
117 ; RV32I-FPELIM-NEXT: sw s0, 8(sp)
118 ; RV32I-FPELIM-NEXT: sw s1, 4(sp)
119 ; RV32I-FPELIM-NEXT: addi s0, sp, 16
120 ; RV32I-FPELIM-NEXT: mv s1, a1
121 ; RV32I-FPELIM-NEXT: sw a7, 28(s0)
122 ; RV32I-FPELIM-NEXT: sw a6, 24(s0)
123 ; RV32I-FPELIM-NEXT: sw a5, 20(s0)
124 ; RV32I-FPELIM-NEXT: sw a4, 16(s0)
125 ; RV32I-FPELIM-NEXT: sw a3, 12(s0)
126 ; RV32I-FPELIM-NEXT: sw a2, 8(s0)
127 ; RV32I-FPELIM-NEXT: addi a0, s0, 8
128 ; RV32I-FPELIM-NEXT: sw a0, -16(s0)
129 ; RV32I-FPELIM-NEXT: sw a1, 4(s0)
130 ; RV32I-FPELIM-NEXT: addi a0, a1, 15
131 ; RV32I-FPELIM-NEXT: andi a0, a0, -16
132 ; RV32I-FPELIM-NEXT: sub a0, sp, a0
133 ; RV32I-FPELIM-NEXT: mv sp, a0
134 ; RV32I-FPELIM-NEXT: call notdead
135 ; RV32I-FPELIM-NEXT: mv a0, s1
136 ; RV32I-FPELIM-NEXT: addi sp, s0, -16
137 ; RV32I-FPELIM-NEXT: lw s1, 4(sp)
138 ; RV32I-FPELIM-NEXT: lw s0, 8(sp)
139 ; RV32I-FPELIM-NEXT: lw ra, 12(sp)
140 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
141 ; RV32I-FPELIM-NEXT: ret
143 ; RV32I-WITHFP-LABEL: va1_va_arg_alloca:
144 ; RV32I-WITHFP: # %bb.0:
145 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
146 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
147 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
148 ; RV32I-WITHFP-NEXT: sw s1, 4(sp)
149 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
150 ; RV32I-WITHFP-NEXT: mv s1, a1
151 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
152 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
153 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
154 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
155 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
156 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
157 ; RV32I-WITHFP-NEXT: addi a0, s0, 8
158 ; RV32I-WITHFP-NEXT: sw a0, -16(s0)
159 ; RV32I-WITHFP-NEXT: sw a1, 4(s0)
160 ; RV32I-WITHFP-NEXT: addi a0, a1, 15
161 ; RV32I-WITHFP-NEXT: andi a0, a0, -16
162 ; RV32I-WITHFP-NEXT: sub a0, sp, a0
163 ; RV32I-WITHFP-NEXT: mv sp, a0
164 ; RV32I-WITHFP-NEXT: call notdead
165 ; RV32I-WITHFP-NEXT: mv a0, s1
166 ; RV32I-WITHFP-NEXT: addi sp, s0, -16
167 ; RV32I-WITHFP-NEXT: lw s1, 4(sp)
168 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
169 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
170 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
171 ; RV32I-WITHFP-NEXT: ret
172 %va = alloca i8*, align 4
173 %1 = bitcast i8** %va to i8*
174 call void @llvm.va_start(i8* %1)
175 %2 = va_arg i8** %va, i32
176 %3 = alloca i8, i32 %2
177 call void @notdead(i8* %3)
178 call void @llvm.va_end(i8* %1)
182 define void @va1_caller() nounwind {
183 ; Pass a double, as a float would be promoted by a C/C++ frontend
184 ; RV32I-FPELIM-LABEL: va1_caller:
185 ; RV32I-FPELIM: # %bb.0:
186 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
187 ; RV32I-FPELIM-NEXT: sw ra, 12(sp)
188 ; RV32I-FPELIM-NEXT: mv a2, zero
189 ; RV32I-FPELIM-NEXT: lui a3, 261888
190 ; RV32I-FPELIM-NEXT: addi a4, zero, 2
191 ; RV32I-FPELIM-NEXT: call va1
192 ; RV32I-FPELIM-NEXT: lw ra, 12(sp)
193 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
194 ; RV32I-FPELIM-NEXT: ret
196 ; RV32I-WITHFP-LABEL: va1_caller:
197 ; RV32I-WITHFP: # %bb.0:
198 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
199 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
200 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
201 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
202 ; RV32I-WITHFP-NEXT: mv a2, zero
203 ; RV32I-WITHFP-NEXT: lui a3, 261888
204 ; RV32I-WITHFP-NEXT: addi a4, zero, 2
205 ; RV32I-WITHFP-NEXT: call va1
206 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
207 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
208 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
209 ; RV32I-WITHFP-NEXT: ret
210 %1 = call i32 (i8*, ...) @va1(i8* undef, double 1.0, i32 2)
214 ; Ensure that 2x xlen size+alignment varargs are accessed via an "aligned"
215 ; register pair (where the first register is even-numbered).
217 define double @va2(i8 *%fmt, ...) nounwind {
218 ; RV32I-FPELIM-LABEL: va2:
219 ; RV32I-FPELIM: # %bb.0:
220 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
221 ; RV32I-FPELIM-NEXT: sw a7, 44(sp)
222 ; RV32I-FPELIM-NEXT: sw a6, 40(sp)
223 ; RV32I-FPELIM-NEXT: sw a5, 36(sp)
224 ; RV32I-FPELIM-NEXT: sw a4, 32(sp)
225 ; RV32I-FPELIM-NEXT: sw a3, 28(sp)
226 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
227 ; RV32I-FPELIM-NEXT: sw a1, 20(sp)
228 ; RV32I-FPELIM-NEXT: addi a0, sp, 35
229 ; RV32I-FPELIM-NEXT: sw a0, 12(sp)
230 ; RV32I-FPELIM-NEXT: addi a0, sp, 27
231 ; RV32I-FPELIM-NEXT: andi a1, a0, -8
232 ; RV32I-FPELIM-NEXT: lw a0, 0(a1)
233 ; RV32I-FPELIM-NEXT: ori a1, a1, 4
234 ; RV32I-FPELIM-NEXT: lw a1, 0(a1)
235 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
236 ; RV32I-FPELIM-NEXT: ret
238 ; RV32I-WITHFP-LABEL: va2:
239 ; RV32I-WITHFP: # %bb.0:
240 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
241 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
242 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
243 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
244 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
245 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
246 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
247 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
248 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
249 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
250 ; RV32I-WITHFP-NEXT: sw a1, 4(s0)
251 ; RV32I-WITHFP-NEXT: addi a0, s0, 19
252 ; RV32I-WITHFP-NEXT: sw a0, -12(s0)
253 ; RV32I-WITHFP-NEXT: addi a0, s0, 11
254 ; RV32I-WITHFP-NEXT: andi a1, a0, -8
255 ; RV32I-WITHFP-NEXT: lw a0, 0(a1)
256 ; RV32I-WITHFP-NEXT: ori a1, a1, 4
257 ; RV32I-WITHFP-NEXT: lw a1, 0(a1)
258 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
259 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
260 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
261 ; RV32I-WITHFP-NEXT: ret
262 %va = alloca i8*, align 4
263 %1 = bitcast i8** %va to i8*
264 call void @llvm.va_start(i8* %1)
265 %2 = bitcast i8** %va to i32*
266 %argp.cur = load i32, i32* %2, align 4
267 %3 = add i32 %argp.cur, 7
269 %argp.cur.aligned = inttoptr i32 %3 to i8*
270 %argp.next = getelementptr inbounds i8, i8* %argp.cur.aligned, i32 8
271 store i8* %argp.next, i8** %va, align 4
272 %5 = inttoptr i32 %4 to double*
273 %6 = load double, double* %5, align 8
274 call void @llvm.va_end(i8* %1)
278 define double @va2_va_arg(i8 *%fmt, ...) nounwind {
279 ; RV32I-FPELIM-LABEL: va2_va_arg:
280 ; RV32I-FPELIM: # %bb.0:
281 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
282 ; RV32I-FPELIM-NEXT: sw a7, 44(sp)
283 ; RV32I-FPELIM-NEXT: sw a6, 40(sp)
284 ; RV32I-FPELIM-NEXT: sw a5, 36(sp)
285 ; RV32I-FPELIM-NEXT: sw a4, 32(sp)
286 ; RV32I-FPELIM-NEXT: sw a3, 28(sp)
287 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
288 ; RV32I-FPELIM-NEXT: sw a1, 20(sp)
289 ; RV32I-FPELIM-NEXT: addi a0, sp, 27
290 ; RV32I-FPELIM-NEXT: andi a0, a0, -8
291 ; RV32I-FPELIM-NEXT: ori a1, a0, 4
292 ; RV32I-FPELIM-NEXT: sw a1, 12(sp)
293 ; RV32I-FPELIM-NEXT: lw a0, 0(a0)
294 ; RV32I-FPELIM-NEXT: addi a2, a1, 4
295 ; RV32I-FPELIM-NEXT: sw a2, 12(sp)
296 ; RV32I-FPELIM-NEXT: lw a1, 0(a1)
297 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
298 ; RV32I-FPELIM-NEXT: ret
300 ; RV32I-WITHFP-LABEL: va2_va_arg:
301 ; RV32I-WITHFP: # %bb.0:
302 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
303 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
304 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
305 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
306 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
307 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
308 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
309 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
310 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
311 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
312 ; RV32I-WITHFP-NEXT: sw a1, 4(s0)
313 ; RV32I-WITHFP-NEXT: addi a0, s0, 11
314 ; RV32I-WITHFP-NEXT: andi a0, a0, -8
315 ; RV32I-WITHFP-NEXT: ori a1, a0, 4
316 ; RV32I-WITHFP-NEXT: sw a1, -12(s0)
317 ; RV32I-WITHFP-NEXT: lw a0, 0(a0)
318 ; RV32I-WITHFP-NEXT: addi a2, a1, 4
319 ; RV32I-WITHFP-NEXT: sw a2, -12(s0)
320 ; RV32I-WITHFP-NEXT: lw a1, 0(a1)
321 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
322 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
323 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
324 ; RV32I-WITHFP-NEXT: ret
325 %va = alloca i8*, align 4
326 %1 = bitcast i8** %va to i8*
327 call void @llvm.va_start(i8* %1)
328 %2 = va_arg i8** %va, double
329 call void @llvm.va_end(i8* %1)
333 define void @va2_caller() nounwind {
334 ; RV32I-FPELIM-LABEL: va2_caller:
335 ; RV32I-FPELIM: # %bb.0:
336 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
337 ; RV32I-FPELIM-NEXT: sw ra, 12(sp)
338 ; RV32I-FPELIM-NEXT: mv a2, zero
339 ; RV32I-FPELIM-NEXT: lui a3, 261888
340 ; RV32I-FPELIM-NEXT: call va2
341 ; RV32I-FPELIM-NEXT: lw ra, 12(sp)
342 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
343 ; RV32I-FPELIM-NEXT: ret
345 ; RV32I-WITHFP-LABEL: va2_caller:
346 ; RV32I-WITHFP: # %bb.0:
347 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
348 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
349 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
350 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
351 ; RV32I-WITHFP-NEXT: mv a2, zero
352 ; RV32I-WITHFP-NEXT: lui a3, 261888
353 ; RV32I-WITHFP-NEXT: call va2
354 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
355 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
356 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
357 ; RV32I-WITHFP-NEXT: ret
358 %1 = call double (i8*, ...) @va2(i8* undef, double 1.000000e+00)
362 ; Ensure a named double argument is passed in a1 and a2, while the vararg
363 ; double is passed in a4 and a5 (rather than a3 and a4)
365 define double @va3(i32 %a, double %b, ...) nounwind {
366 ; RV32I-FPELIM-LABEL: va3:
367 ; RV32I-FPELIM: # %bb.0:
368 ; RV32I-FPELIM-NEXT: addi sp, sp, -32
369 ; RV32I-FPELIM-NEXT: sw ra, 4(sp)
370 ; RV32I-FPELIM-NEXT: mv t0, a2
371 ; RV32I-FPELIM-NEXT: mv a0, a1
372 ; RV32I-FPELIM-NEXT: sw a7, 28(sp)
373 ; RV32I-FPELIM-NEXT: sw a6, 24(sp)
374 ; RV32I-FPELIM-NEXT: sw a5, 20(sp)
375 ; RV32I-FPELIM-NEXT: sw a4, 16(sp)
376 ; RV32I-FPELIM-NEXT: sw a3, 12(sp)
377 ; RV32I-FPELIM-NEXT: addi a1, sp, 27
378 ; RV32I-FPELIM-NEXT: sw a1, 0(sp)
379 ; RV32I-FPELIM-NEXT: addi a1, sp, 19
380 ; RV32I-FPELIM-NEXT: andi a1, a1, -8
381 ; RV32I-FPELIM-NEXT: lw a2, 0(a1)
382 ; RV32I-FPELIM-NEXT: ori a1, a1, 4
383 ; RV32I-FPELIM-NEXT: lw a3, 0(a1)
384 ; RV32I-FPELIM-NEXT: mv a1, t0
385 ; RV32I-FPELIM-NEXT: call __adddf3
386 ; RV32I-FPELIM-NEXT: lw ra, 4(sp)
387 ; RV32I-FPELIM-NEXT: addi sp, sp, 32
388 ; RV32I-FPELIM-NEXT: ret
390 ; RV32I-WITHFP-LABEL: va3:
391 ; RV32I-WITHFP: # %bb.0:
392 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
393 ; RV32I-WITHFP-NEXT: sw ra, 20(sp)
394 ; RV32I-WITHFP-NEXT: sw s0, 16(sp)
395 ; RV32I-WITHFP-NEXT: addi s0, sp, 24
396 ; RV32I-WITHFP-NEXT: mv t0, a2
397 ; RV32I-WITHFP-NEXT: mv a0, a1
398 ; RV32I-WITHFP-NEXT: sw a7, 20(s0)
399 ; RV32I-WITHFP-NEXT: sw a6, 16(s0)
400 ; RV32I-WITHFP-NEXT: sw a5, 12(s0)
401 ; RV32I-WITHFP-NEXT: sw a4, 8(s0)
402 ; RV32I-WITHFP-NEXT: sw a3, 4(s0)
403 ; RV32I-WITHFP-NEXT: addi a1, s0, 19
404 ; RV32I-WITHFP-NEXT: sw a1, -12(s0)
405 ; RV32I-WITHFP-NEXT: addi a1, s0, 11
406 ; RV32I-WITHFP-NEXT: andi a1, a1, -8
407 ; RV32I-WITHFP-NEXT: lw a2, 0(a1)
408 ; RV32I-WITHFP-NEXT: ori a1, a1, 4
409 ; RV32I-WITHFP-NEXT: lw a3, 0(a1)
410 ; RV32I-WITHFP-NEXT: mv a1, t0
411 ; RV32I-WITHFP-NEXT: call __adddf3
412 ; RV32I-WITHFP-NEXT: lw s0, 16(sp)
413 ; RV32I-WITHFP-NEXT: lw ra, 20(sp)
414 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
415 ; RV32I-WITHFP-NEXT: ret
416 %va = alloca i8*, align 4
417 %1 = bitcast i8** %va to i8*
418 call void @llvm.va_start(i8* %1)
419 %2 = bitcast i8** %va to i32*
420 %argp.cur = load i32, i32* %2, align 4
421 %3 = add i32 %argp.cur, 7
423 %argp.cur.aligned = inttoptr i32 %3 to i8*
424 %argp.next = getelementptr inbounds i8, i8* %argp.cur.aligned, i32 8
425 store i8* %argp.next, i8** %va, align 4
426 %5 = inttoptr i32 %4 to double*
427 %6 = load double, double* %5, align 8
428 call void @llvm.va_end(i8* %1)
429 %7 = fadd double %b, %6
433 define double @va3_va_arg(i32 %a, double %b, ...) nounwind {
434 ; RV32I-FPELIM-LABEL: va3_va_arg:
435 ; RV32I-FPELIM: # %bb.0:
436 ; RV32I-FPELIM-NEXT: addi sp, sp, -32
437 ; RV32I-FPELIM-NEXT: sw ra, 4(sp)
438 ; RV32I-FPELIM-NEXT: mv t0, a2
439 ; RV32I-FPELIM-NEXT: mv a0, a1
440 ; RV32I-FPELIM-NEXT: sw a7, 28(sp)
441 ; RV32I-FPELIM-NEXT: sw a6, 24(sp)
442 ; RV32I-FPELIM-NEXT: sw a5, 20(sp)
443 ; RV32I-FPELIM-NEXT: sw a4, 16(sp)
444 ; RV32I-FPELIM-NEXT: sw a3, 12(sp)
445 ; RV32I-FPELIM-NEXT: addi a1, sp, 19
446 ; RV32I-FPELIM-NEXT: andi a1, a1, -8
447 ; RV32I-FPELIM-NEXT: ori a3, a1, 4
448 ; RV32I-FPELIM-NEXT: sw a3, 0(sp)
449 ; RV32I-FPELIM-NEXT: lw a2, 0(a1)
450 ; RV32I-FPELIM-NEXT: addi a1, a3, 4
451 ; RV32I-FPELIM-NEXT: sw a1, 0(sp)
452 ; RV32I-FPELIM-NEXT: lw a3, 0(a3)
453 ; RV32I-FPELIM-NEXT: mv a1, t0
454 ; RV32I-FPELIM-NEXT: call __adddf3
455 ; RV32I-FPELIM-NEXT: lw ra, 4(sp)
456 ; RV32I-FPELIM-NEXT: addi sp, sp, 32
457 ; RV32I-FPELIM-NEXT: ret
459 ; RV32I-WITHFP-LABEL: va3_va_arg:
460 ; RV32I-WITHFP: # %bb.0:
461 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
462 ; RV32I-WITHFP-NEXT: sw ra, 20(sp)
463 ; RV32I-WITHFP-NEXT: sw s0, 16(sp)
464 ; RV32I-WITHFP-NEXT: addi s0, sp, 24
465 ; RV32I-WITHFP-NEXT: mv t0, a2
466 ; RV32I-WITHFP-NEXT: mv a0, a1
467 ; RV32I-WITHFP-NEXT: sw a7, 20(s0)
468 ; RV32I-WITHFP-NEXT: sw a6, 16(s0)
469 ; RV32I-WITHFP-NEXT: sw a5, 12(s0)
470 ; RV32I-WITHFP-NEXT: sw a4, 8(s0)
471 ; RV32I-WITHFP-NEXT: sw a3, 4(s0)
472 ; RV32I-WITHFP-NEXT: addi a1, s0, 11
473 ; RV32I-WITHFP-NEXT: andi a1, a1, -8
474 ; RV32I-WITHFP-NEXT: ori a3, a1, 4
475 ; RV32I-WITHFP-NEXT: sw a3, -12(s0)
476 ; RV32I-WITHFP-NEXT: lw a2, 0(a1)
477 ; RV32I-WITHFP-NEXT: addi a1, a3, 4
478 ; RV32I-WITHFP-NEXT: sw a1, -12(s0)
479 ; RV32I-WITHFP-NEXT: lw a3, 0(a3)
480 ; RV32I-WITHFP-NEXT: mv a1, t0
481 ; RV32I-WITHFP-NEXT: call __adddf3
482 ; RV32I-WITHFP-NEXT: lw s0, 16(sp)
483 ; RV32I-WITHFP-NEXT: lw ra, 20(sp)
484 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
485 ; RV32I-WITHFP-NEXT: ret
486 %va = alloca i8*, align 4
487 %1 = bitcast i8** %va to i8*
488 call void @llvm.va_start(i8* %1)
489 %2 = va_arg i8** %va, double
490 call void @llvm.va_end(i8* %1)
491 %3 = fadd double %b, %2
495 define void @va3_caller() nounwind {
496 ; RV32I-FPELIM-LABEL: va3_caller:
497 ; RV32I-FPELIM: # %bb.0:
498 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
499 ; RV32I-FPELIM-NEXT: sw ra, 12(sp)
500 ; RV32I-FPELIM-NEXT: addi a0, zero, 2
501 ; RV32I-FPELIM-NEXT: mv a1, zero
502 ; RV32I-FPELIM-NEXT: lui a2, 261888
503 ; RV32I-FPELIM-NEXT: mv a4, zero
504 ; RV32I-FPELIM-NEXT: lui a5, 262144
505 ; RV32I-FPELIM-NEXT: call va3
506 ; RV32I-FPELIM-NEXT: lw ra, 12(sp)
507 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
508 ; RV32I-FPELIM-NEXT: ret
510 ; RV32I-WITHFP-LABEL: va3_caller:
511 ; RV32I-WITHFP: # %bb.0:
512 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
513 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
514 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
515 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
516 ; RV32I-WITHFP-NEXT: addi a0, zero, 2
517 ; RV32I-WITHFP-NEXT: mv a1, zero
518 ; RV32I-WITHFP-NEXT: lui a2, 261888
519 ; RV32I-WITHFP-NEXT: mv a4, zero
520 ; RV32I-WITHFP-NEXT: lui a5, 262144
521 ; RV32I-WITHFP-NEXT: call va3
522 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
523 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
524 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
525 ; RV32I-WITHFP-NEXT: ret
526 %1 = call double (i32, double, ...) @va3(i32 2, double 1.000000e+00, double 2.000000e+00)
530 declare void @llvm.va_copy(i8*, i8*)
532 define i32 @va4_va_copy(i32 %argno, ...) nounwind {
533 ; RV32I-FPELIM-LABEL: va4_va_copy:
534 ; RV32I-FPELIM: # %bb.0:
535 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
536 ; RV32I-FPELIM-NEXT: sw ra, 12(sp)
537 ; RV32I-FPELIM-NEXT: sw s1, 8(sp)
538 ; RV32I-FPELIM-NEXT: mv s1, a1
539 ; RV32I-FPELIM-NEXT: sw a7, 44(sp)
540 ; RV32I-FPELIM-NEXT: sw a6, 40(sp)
541 ; RV32I-FPELIM-NEXT: sw a5, 36(sp)
542 ; RV32I-FPELIM-NEXT: sw a4, 32(sp)
543 ; RV32I-FPELIM-NEXT: sw a3, 28(sp)
544 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
545 ; RV32I-FPELIM-NEXT: sw a1, 20(sp)
546 ; RV32I-FPELIM-NEXT: addi a0, sp, 24
547 ; RV32I-FPELIM-NEXT: sw a0, 4(sp)
548 ; RV32I-FPELIM-NEXT: sw a0, 0(sp)
549 ; RV32I-FPELIM-NEXT: call notdead
550 ; RV32I-FPELIM-NEXT: lw a0, 4(sp)
551 ; RV32I-FPELIM-NEXT: addi a0, a0, 3
552 ; RV32I-FPELIM-NEXT: andi a0, a0, -4
553 ; RV32I-FPELIM-NEXT: addi a1, a0, 4
554 ; RV32I-FPELIM-NEXT: sw a1, 4(sp)
555 ; RV32I-FPELIM-NEXT: lw a1, 0(a0)
556 ; RV32I-FPELIM-NEXT: addi a0, a0, 7
557 ; RV32I-FPELIM-NEXT: andi a0, a0, -4
558 ; RV32I-FPELIM-NEXT: addi a2, a0, 4
559 ; RV32I-FPELIM-NEXT: sw a2, 4(sp)
560 ; RV32I-FPELIM-NEXT: lw a2, 0(a0)
561 ; RV32I-FPELIM-NEXT: addi a0, a0, 7
562 ; RV32I-FPELIM-NEXT: andi a0, a0, -4
563 ; RV32I-FPELIM-NEXT: addi a3, a0, 4
564 ; RV32I-FPELIM-NEXT: sw a3, 4(sp)
565 ; RV32I-FPELIM-NEXT: add a1, a1, s1
566 ; RV32I-FPELIM-NEXT: add a1, a1, a2
567 ; RV32I-FPELIM-NEXT: lw a0, 0(a0)
568 ; RV32I-FPELIM-NEXT: add a0, a1, a0
569 ; RV32I-FPELIM-NEXT: lw s1, 8(sp)
570 ; RV32I-FPELIM-NEXT: lw ra, 12(sp)
571 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
572 ; RV32I-FPELIM-NEXT: ret
574 ; RV32I-WITHFP-LABEL: va4_va_copy:
575 ; RV32I-WITHFP: # %bb.0:
576 ; RV32I-WITHFP-NEXT: addi sp, sp, -64
577 ; RV32I-WITHFP-NEXT: sw ra, 28(sp)
578 ; RV32I-WITHFP-NEXT: sw s0, 24(sp)
579 ; RV32I-WITHFP-NEXT: sw s1, 20(sp)
580 ; RV32I-WITHFP-NEXT: addi s0, sp, 32
581 ; RV32I-WITHFP-NEXT: mv s1, a1
582 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
583 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
584 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
585 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
586 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
587 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
588 ; RV32I-WITHFP-NEXT: sw a1, 4(s0)
589 ; RV32I-WITHFP-NEXT: addi a0, s0, 8
590 ; RV32I-WITHFP-NEXT: sw a0, -16(s0)
591 ; RV32I-WITHFP-NEXT: sw a0, -20(s0)
592 ; RV32I-WITHFP-NEXT: call notdead
593 ; RV32I-WITHFP-NEXT: lw a0, -16(s0)
594 ; RV32I-WITHFP-NEXT: addi a0, a0, 3
595 ; RV32I-WITHFP-NEXT: andi a0, a0, -4
596 ; RV32I-WITHFP-NEXT: addi a1, a0, 4
597 ; RV32I-WITHFP-NEXT: sw a1, -16(s0)
598 ; RV32I-WITHFP-NEXT: lw a1, 0(a0)
599 ; RV32I-WITHFP-NEXT: addi a0, a0, 7
600 ; RV32I-WITHFP-NEXT: andi a0, a0, -4
601 ; RV32I-WITHFP-NEXT: addi a2, a0, 4
602 ; RV32I-WITHFP-NEXT: sw a2, -16(s0)
603 ; RV32I-WITHFP-NEXT: lw a2, 0(a0)
604 ; RV32I-WITHFP-NEXT: addi a0, a0, 7
605 ; RV32I-WITHFP-NEXT: andi a0, a0, -4
606 ; RV32I-WITHFP-NEXT: addi a3, a0, 4
607 ; RV32I-WITHFP-NEXT: sw a3, -16(s0)
608 ; RV32I-WITHFP-NEXT: add a1, a1, s1
609 ; RV32I-WITHFP-NEXT: add a1, a1, a2
610 ; RV32I-WITHFP-NEXT: lw a0, 0(a0)
611 ; RV32I-WITHFP-NEXT: add a0, a1, a0
612 ; RV32I-WITHFP-NEXT: lw s1, 20(sp)
613 ; RV32I-WITHFP-NEXT: lw s0, 24(sp)
614 ; RV32I-WITHFP-NEXT: lw ra, 28(sp)
615 ; RV32I-WITHFP-NEXT: addi sp, sp, 64
616 ; RV32I-WITHFP-NEXT: ret
617 %vargs = alloca i8*, align 4
618 %wargs = alloca i8*, align 4
619 %1 = bitcast i8** %vargs to i8*
620 %2 = bitcast i8** %wargs to i8*
621 call void @llvm.va_start(i8* %1)
622 %3 = va_arg i8** %vargs, i32
623 call void @llvm.va_copy(i8* %2, i8* %1)
624 %4 = load i8*, i8** %wargs, align 4
625 call void @notdead(i8* %4)
626 %5 = va_arg i8** %vargs, i32
627 %6 = va_arg i8** %vargs, i32
628 %7 = va_arg i8** %vargs, i32
629 call void @llvm.va_end(i8* %1)
630 call void @llvm.va_end(i8* %2)
631 %add1 = add i32 %5, %3
632 %add2 = add i32 %add1, %6
633 %add3 = add i32 %add2, %7
637 ; Check 2x*xlen values are aligned appropriately when passed on the stack in a vararg call
639 define i32 @va5_aligned_stack_callee(i32 %a, ...) nounwind {
640 ; RV32I-FPELIM-LABEL: va5_aligned_stack_callee:
641 ; RV32I-FPELIM: # %bb.0:
642 ; RV32I-FPELIM-NEXT: addi sp, sp, -32
643 ; RV32I-FPELIM-NEXT: sw a7, 28(sp)
644 ; RV32I-FPELIM-NEXT: sw a6, 24(sp)
645 ; RV32I-FPELIM-NEXT: sw a5, 20(sp)
646 ; RV32I-FPELIM-NEXT: sw a4, 16(sp)
647 ; RV32I-FPELIM-NEXT: sw a3, 12(sp)
648 ; RV32I-FPELIM-NEXT: sw a2, 8(sp)
649 ; RV32I-FPELIM-NEXT: sw a1, 4(sp)
650 ; RV32I-FPELIM-NEXT: addi a0, zero, 1
651 ; RV32I-FPELIM-NEXT: addi sp, sp, 32
652 ; RV32I-FPELIM-NEXT: ret
654 ; RV32I-WITHFP-LABEL: va5_aligned_stack_callee:
655 ; RV32I-WITHFP: # %bb.0:
656 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
657 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
658 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
659 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
660 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
661 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
662 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
663 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
664 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
665 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
666 ; RV32I-WITHFP-NEXT: sw a1, 4(s0)
667 ; RV32I-WITHFP-NEXT: addi a0, zero, 1
668 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
669 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
670 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
671 ; RV32I-WITHFP-NEXT: ret
675 define void @va5_aligned_stack_caller() nounwind {
676 ; The double should be 8-byte aligned on the stack, but the two-element array
677 ; should only be 4-byte aligned
678 ; RV32I-FPELIM-LABEL: va5_aligned_stack_caller:
679 ; RV32I-FPELIM: # %bb.0:
680 ; RV32I-FPELIM-NEXT: addi sp, sp, -64
681 ; RV32I-FPELIM-NEXT: sw ra, 60(sp)
682 ; RV32I-FPELIM-NEXT: addi a0, zero, 17
683 ; RV32I-FPELIM-NEXT: sw a0, 24(sp)
684 ; RV32I-FPELIM-NEXT: addi a0, zero, 16
685 ; RV32I-FPELIM-NEXT: sw a0, 20(sp)
686 ; RV32I-FPELIM-NEXT: addi a0, zero, 15
687 ; RV32I-FPELIM-NEXT: sw a0, 16(sp)
688 ; RV32I-FPELIM-NEXT: lui a0, 262236
689 ; RV32I-FPELIM-NEXT: addi a0, a0, 655
690 ; RV32I-FPELIM-NEXT: sw a0, 12(sp)
691 ; RV32I-FPELIM-NEXT: lui a0, 377487
692 ; RV32I-FPELIM-NEXT: addi a0, a0, 1475
693 ; RV32I-FPELIM-NEXT: sw a0, 8(sp)
694 ; RV32I-FPELIM-NEXT: addi a0, zero, 14
695 ; RV32I-FPELIM-NEXT: sw a0, 0(sp)
696 ; RV32I-FPELIM-NEXT: lui a0, 262153
697 ; RV32I-FPELIM-NEXT: addi a0, a0, 491
698 ; RV32I-FPELIM-NEXT: sw a0, 44(sp)
699 ; RV32I-FPELIM-NEXT: lui a0, 545260
700 ; RV32I-FPELIM-NEXT: addi a0, a0, -1967
701 ; RV32I-FPELIM-NEXT: sw a0, 40(sp)
702 ; RV32I-FPELIM-NEXT: lui a0, 964690
703 ; RV32I-FPELIM-NEXT: addi a0, a0, -328
704 ; RV32I-FPELIM-NEXT: sw a0, 36(sp)
705 ; RV32I-FPELIM-NEXT: lui a0, 335544
706 ; RV32I-FPELIM-NEXT: addi a0, a0, 1311
707 ; RV32I-FPELIM-NEXT: sw a0, 32(sp)
708 ; RV32I-FPELIM-NEXT: lui a0, 688509
709 ; RV32I-FPELIM-NEXT: addi a6, a0, -2048
710 ; RV32I-FPELIM-NEXT: addi a2, sp, 32
711 ; RV32I-FPELIM-NEXT: addi a0, zero, 1
712 ; RV32I-FPELIM-NEXT: addi a1, zero, 11
713 ; RV32I-FPELIM-NEXT: addi a3, zero, 12
714 ; RV32I-FPELIM-NEXT: addi a4, zero, 13
715 ; RV32I-FPELIM-NEXT: addi a7, zero, 4
716 ; RV32I-FPELIM-NEXT: call va5_aligned_stack_callee
717 ; RV32I-FPELIM-NEXT: lw ra, 60(sp)
718 ; RV32I-FPELIM-NEXT: addi sp, sp, 64
719 ; RV32I-FPELIM-NEXT: ret
721 ; RV32I-WITHFP-LABEL: va5_aligned_stack_caller:
722 ; RV32I-WITHFP: # %bb.0:
723 ; RV32I-WITHFP-NEXT: addi sp, sp, -64
724 ; RV32I-WITHFP-NEXT: sw ra, 60(sp)
725 ; RV32I-WITHFP-NEXT: sw s0, 56(sp)
726 ; RV32I-WITHFP-NEXT: addi s0, sp, 64
727 ; RV32I-WITHFP-NEXT: addi a0, zero, 17
728 ; RV32I-WITHFP-NEXT: sw a0, 24(sp)
729 ; RV32I-WITHFP-NEXT: addi a0, zero, 16
730 ; RV32I-WITHFP-NEXT: sw a0, 20(sp)
731 ; RV32I-WITHFP-NEXT: addi a0, zero, 15
732 ; RV32I-WITHFP-NEXT: sw a0, 16(sp)
733 ; RV32I-WITHFP-NEXT: lui a0, 262236
734 ; RV32I-WITHFP-NEXT: addi a0, a0, 655
735 ; RV32I-WITHFP-NEXT: sw a0, 12(sp)
736 ; RV32I-WITHFP-NEXT: lui a0, 377487
737 ; RV32I-WITHFP-NEXT: addi a0, a0, 1475
738 ; RV32I-WITHFP-NEXT: sw a0, 8(sp)
739 ; RV32I-WITHFP-NEXT: addi a0, zero, 14
740 ; RV32I-WITHFP-NEXT: sw a0, 0(sp)
741 ; RV32I-WITHFP-NEXT: lui a0, 262153
742 ; RV32I-WITHFP-NEXT: addi a0, a0, 491
743 ; RV32I-WITHFP-NEXT: sw a0, -20(s0)
744 ; RV32I-WITHFP-NEXT: lui a0, 545260
745 ; RV32I-WITHFP-NEXT: addi a0, a0, -1967
746 ; RV32I-WITHFP-NEXT: sw a0, -24(s0)
747 ; RV32I-WITHFP-NEXT: lui a0, 964690
748 ; RV32I-WITHFP-NEXT: addi a0, a0, -328
749 ; RV32I-WITHFP-NEXT: sw a0, -28(s0)
750 ; RV32I-WITHFP-NEXT: lui a0, 335544
751 ; RV32I-WITHFP-NEXT: addi a0, a0, 1311
752 ; RV32I-WITHFP-NEXT: sw a0, -32(s0)
753 ; RV32I-WITHFP-NEXT: lui a0, 688509
754 ; RV32I-WITHFP-NEXT: addi a6, a0, -2048
755 ; RV32I-WITHFP-NEXT: addi a2, s0, -32
756 ; RV32I-WITHFP-NEXT: addi a0, zero, 1
757 ; RV32I-WITHFP-NEXT: addi a1, zero, 11
758 ; RV32I-WITHFP-NEXT: addi a3, zero, 12
759 ; RV32I-WITHFP-NEXT: addi a4, zero, 13
760 ; RV32I-WITHFP-NEXT: addi a7, zero, 4
761 ; RV32I-WITHFP-NEXT: call va5_aligned_stack_callee
762 ; RV32I-WITHFP-NEXT: lw s0, 56(sp)
763 ; RV32I-WITHFP-NEXT: lw ra, 60(sp)
764 ; RV32I-WITHFP-NEXT: addi sp, sp, 64
765 ; RV32I-WITHFP-NEXT: ret
766 %1 = call i32 (i32, ...) @va5_aligned_stack_callee(i32 1, i32 11,
767 fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13, i64 20000000000,
768 i32 14, double 2.720000e+00, i32 15, [2 x i32] [i32 16, i32 17])
772 ; A function with no fixed arguments is not valid C, but can be
773 ; specified in LLVM IR. We must ensure the vararg save area is
774 ; still set up correctly.
776 define i32 @va6_no_fixed_args(...) nounwind {
777 ; RV32I-FPELIM-LABEL: va6_no_fixed_args:
778 ; RV32I-FPELIM: # %bb.0:
779 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
780 ; RV32I-FPELIM-NEXT: sw a7, 44(sp)
781 ; RV32I-FPELIM-NEXT: sw a6, 40(sp)
782 ; RV32I-FPELIM-NEXT: sw a5, 36(sp)
783 ; RV32I-FPELIM-NEXT: sw a4, 32(sp)
784 ; RV32I-FPELIM-NEXT: sw a3, 28(sp)
785 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
786 ; RV32I-FPELIM-NEXT: sw a1, 20(sp)
787 ; RV32I-FPELIM-NEXT: addi a1, sp, 20
788 ; RV32I-FPELIM-NEXT: sw a1, 12(sp)
789 ; RV32I-FPELIM-NEXT: sw a0, 16(sp)
790 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
791 ; RV32I-FPELIM-NEXT: ret
793 ; RV32I-WITHFP-LABEL: va6_no_fixed_args:
794 ; RV32I-WITHFP: # %bb.0:
795 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
796 ; RV32I-WITHFP-NEXT: sw ra, 12(sp)
797 ; RV32I-WITHFP-NEXT: sw s0, 8(sp)
798 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
799 ; RV32I-WITHFP-NEXT: sw a7, 28(s0)
800 ; RV32I-WITHFP-NEXT: sw a6, 24(s0)
801 ; RV32I-WITHFP-NEXT: sw a5, 20(s0)
802 ; RV32I-WITHFP-NEXT: sw a4, 16(s0)
803 ; RV32I-WITHFP-NEXT: sw a3, 12(s0)
804 ; RV32I-WITHFP-NEXT: sw a2, 8(s0)
805 ; RV32I-WITHFP-NEXT: sw a1, 4(s0)
806 ; RV32I-WITHFP-NEXT: addi a1, s0, 4
807 ; RV32I-WITHFP-NEXT: sw a1, -12(s0)
808 ; RV32I-WITHFP-NEXT: sw a0, 0(s0)
809 ; RV32I-WITHFP-NEXT: lw s0, 8(sp)
810 ; RV32I-WITHFP-NEXT: lw ra, 12(sp)
811 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
812 ; RV32I-WITHFP-NEXT: ret
813 %va = alloca i8*, align 4
814 %1 = bitcast i8** %va to i8*
815 call void @llvm.va_start(i8* %1)
816 %2 = va_arg i8** %va, i32
817 call void @llvm.va_end(i8* %1)