Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / RISCV / vararg.ll
blob60286a76e041c18be711d7a105c4e38bdf8c5bbe
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
14 ; lowered correctly
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)
62   ret i32 %3
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)
107   ret i32 %2
110 ; Ensure the adjustment when restoring the stack pointer using the frame
111 ; pointer is correct
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)
179   ret i32 %2
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)
211   ret void
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
268   %4 = and i32 %3, -8
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)
275   ret double %6
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)
330   ret double %2
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)
359  ret void
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
422   %4 = and i32 %3, -8
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
430   ret double %7
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
492   ret double %3
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)
527  ret void
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
634   ret i32 %add3
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
672   ret i32 1
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])
769   ret void
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)
818   ret i32 %2