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 -mattr=+f -target-abi ilp32f \
5 ; RUN: -verify-machineinstrs < %s \
6 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
7 ; RUN: llc -mtriple=riscv32 -mattr=+d -target-abi ilp32d \
8 ; RUN: -verify-machineinstrs < %s \
9 ; RUN: | FileCheck -check-prefix=RV32I-FPELIM %s
10 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all < %s \
11 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
12 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
13 ; RUN: -mattr=+f -target-abi ilp32f < %s \
14 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
15 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -frame-pointer=all \
16 ; RUN: -mattr=+d -target-abi ilp32d < %s \
17 ; RUN: | FileCheck -check-prefix=RV32I-WITHFP %s
19 ; This file contains tests that should have identical output for the ilp32,
20 ; ilp32f, and ilp32d ABIs. i.e. where no arguments are passed according to
21 ; the floating point ABI. As well as calling convention details, we check that
22 ; ra and fp are consistently stored to fp-4 and fp-8.
24 ; Check that on RV32, i64 is passed in a pair of registers. Unlike
25 ; the convention for varargs, this need not be an aligned pair.
27 define i32 @callee_i64_in_regs(i32 %a, i64 %b) nounwind {
28 ; RV32I-FPELIM-LABEL: callee_i64_in_regs:
29 ; RV32I-FPELIM: # %bb.0:
30 ; RV32I-FPELIM-NEXT: add a0, a0, a1
31 ; RV32I-FPELIM-NEXT: ret
33 ; RV32I-WITHFP-LABEL: callee_i64_in_regs:
34 ; RV32I-WITHFP: # %bb.0:
35 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
36 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
37 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
38 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
39 ; RV32I-WITHFP-NEXT: add a0, a0, a1
40 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
41 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
42 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
43 ; RV32I-WITHFP-NEXT: ret
44 %b_trunc = trunc i64 %b to i32
45 %1 = add i32 %a, %b_trunc
49 define i32 @caller_i64_in_regs() nounwind {
50 ; RV32I-FPELIM-LABEL: caller_i64_in_regs:
51 ; RV32I-FPELIM: # %bb.0:
52 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
53 ; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
54 ; RV32I-FPELIM-NEXT: li a0, 1
55 ; RV32I-FPELIM-NEXT: li a1, 2
56 ; RV32I-FPELIM-NEXT: li a2, 0
57 ; RV32I-FPELIM-NEXT: call callee_i64_in_regs
58 ; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
59 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
60 ; RV32I-FPELIM-NEXT: ret
62 ; RV32I-WITHFP-LABEL: caller_i64_in_regs:
63 ; RV32I-WITHFP: # %bb.0:
64 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
65 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
66 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
67 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
68 ; RV32I-WITHFP-NEXT: li a0, 1
69 ; RV32I-WITHFP-NEXT: li a1, 2
70 ; RV32I-WITHFP-NEXT: li a2, 0
71 ; RV32I-WITHFP-NEXT: call callee_i64_in_regs
72 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
73 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
74 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
75 ; RV32I-WITHFP-NEXT: ret
76 %1 = call i32 @callee_i64_in_regs(i32 1, i64 2)
80 ; Check that the stack is used once the GPRs are exhausted
82 define i32 @callee_many_scalars(i8 %a, i16 %b, i32 %c, i64 %d, i32 %e, i32 %f, i64 %g, i32 %h) nounwind {
83 ; RV32I-FPELIM-LABEL: callee_many_scalars:
84 ; RV32I-FPELIM: # %bb.0:
85 ; RV32I-FPELIM-NEXT: lw t0, 4(sp)
86 ; RV32I-FPELIM-NEXT: lw t1, 0(sp)
87 ; RV32I-FPELIM-NEXT: andi a0, a0, 255
88 ; RV32I-FPELIM-NEXT: slli a1, a1, 16
89 ; RV32I-FPELIM-NEXT: srli a1, a1, 16
90 ; RV32I-FPELIM-NEXT: add a0, a0, a2
91 ; RV32I-FPELIM-NEXT: add a0, a0, a1
92 ; RV32I-FPELIM-NEXT: xor a1, a4, t1
93 ; RV32I-FPELIM-NEXT: xor a2, a3, a7
94 ; RV32I-FPELIM-NEXT: or a1, a2, a1
95 ; RV32I-FPELIM-NEXT: seqz a1, a1
96 ; RV32I-FPELIM-NEXT: add a0, a0, a5
97 ; RV32I-FPELIM-NEXT: add a0, a0, a6
98 ; RV32I-FPELIM-NEXT: add a0, a0, t0
99 ; RV32I-FPELIM-NEXT: add a0, a1, a0
100 ; RV32I-FPELIM-NEXT: ret
102 ; RV32I-WITHFP-LABEL: callee_many_scalars:
103 ; RV32I-WITHFP: # %bb.0:
104 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
105 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
106 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
107 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
108 ; RV32I-WITHFP-NEXT: lw t0, 4(s0)
109 ; RV32I-WITHFP-NEXT: lw t1, 0(s0)
110 ; RV32I-WITHFP-NEXT: andi a0, a0, 255
111 ; RV32I-WITHFP-NEXT: slli a1, a1, 16
112 ; RV32I-WITHFP-NEXT: srli a1, a1, 16
113 ; RV32I-WITHFP-NEXT: add a0, a0, a2
114 ; RV32I-WITHFP-NEXT: add a0, a0, a1
115 ; RV32I-WITHFP-NEXT: xor a1, a4, t1
116 ; RV32I-WITHFP-NEXT: xor a2, a3, a7
117 ; RV32I-WITHFP-NEXT: or a1, a2, a1
118 ; RV32I-WITHFP-NEXT: seqz a1, a1
119 ; RV32I-WITHFP-NEXT: add a0, a0, a5
120 ; RV32I-WITHFP-NEXT: add a0, a0, a6
121 ; RV32I-WITHFP-NEXT: add a0, a0, t0
122 ; RV32I-WITHFP-NEXT: add a0, a1, a0
123 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
124 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
125 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
126 ; RV32I-WITHFP-NEXT: ret
127 %a_ext = zext i8 %a to i32
128 %b_ext = zext i16 %b to i32
129 %1 = add i32 %a_ext, %b_ext
131 %3 = icmp eq i64 %d, %g
132 %4 = zext i1 %3 to i32
140 define i32 @caller_many_scalars() nounwind {
141 ; RV32I-FPELIM-LABEL: caller_many_scalars:
142 ; RV32I-FPELIM: # %bb.0:
143 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
144 ; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
145 ; RV32I-FPELIM-NEXT: li a0, 8
146 ; RV32I-FPELIM-NEXT: sw a0, 4(sp)
147 ; RV32I-FPELIM-NEXT: li a0, 1
148 ; RV32I-FPELIM-NEXT: li a1, 2
149 ; RV32I-FPELIM-NEXT: li a2, 3
150 ; RV32I-FPELIM-NEXT: li a3, 4
151 ; RV32I-FPELIM-NEXT: li a5, 5
152 ; RV32I-FPELIM-NEXT: li a6, 6
153 ; RV32I-FPELIM-NEXT: li a7, 7
154 ; RV32I-FPELIM-NEXT: sw zero, 0(sp)
155 ; RV32I-FPELIM-NEXT: li a4, 0
156 ; RV32I-FPELIM-NEXT: call callee_many_scalars
157 ; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
158 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
159 ; RV32I-FPELIM-NEXT: ret
161 ; RV32I-WITHFP-LABEL: caller_many_scalars:
162 ; RV32I-WITHFP: # %bb.0:
163 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
164 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
165 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
166 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
167 ; RV32I-WITHFP-NEXT: li a0, 8
168 ; RV32I-WITHFP-NEXT: sw a0, 4(sp)
169 ; RV32I-WITHFP-NEXT: li a0, 1
170 ; RV32I-WITHFP-NEXT: li a1, 2
171 ; RV32I-WITHFP-NEXT: li a2, 3
172 ; RV32I-WITHFP-NEXT: li a3, 4
173 ; RV32I-WITHFP-NEXT: li a5, 5
174 ; RV32I-WITHFP-NEXT: li a6, 6
175 ; RV32I-WITHFP-NEXT: li a7, 7
176 ; RV32I-WITHFP-NEXT: sw zero, 0(sp)
177 ; RV32I-WITHFP-NEXT: li a4, 0
178 ; RV32I-WITHFP-NEXT: call callee_many_scalars
179 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
180 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
181 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
182 ; RV32I-WITHFP-NEXT: ret
183 %1 = call i32 @callee_many_scalars(i8 1, i16 2, i32 3, i64 4, i32 5, i32 6, i64 7, i32 8)
188 ; Check that i128 and fp128 are passed indirectly
190 define i32 @callee_large_scalars(i128 %a, fp128 %b) nounwind {
191 ; RV32I-FPELIM-LABEL: callee_large_scalars:
192 ; RV32I-FPELIM: # %bb.0:
193 ; RV32I-FPELIM-NEXT: lw a2, 0(a1)
194 ; RV32I-FPELIM-NEXT: lw a3, 0(a0)
195 ; RV32I-FPELIM-NEXT: lw a4, 4(a1)
196 ; RV32I-FPELIM-NEXT: lw a5, 12(a1)
197 ; RV32I-FPELIM-NEXT: lw a6, 12(a0)
198 ; RV32I-FPELIM-NEXT: lw a7, 4(a0)
199 ; RV32I-FPELIM-NEXT: lw a1, 8(a1)
200 ; RV32I-FPELIM-NEXT: lw a0, 8(a0)
201 ; RV32I-FPELIM-NEXT: xor a5, a6, a5
202 ; RV32I-FPELIM-NEXT: xor a4, a7, a4
203 ; RV32I-FPELIM-NEXT: or a4, a4, a5
204 ; RV32I-FPELIM-NEXT: xor a0, a0, a1
205 ; RV32I-FPELIM-NEXT: xor a2, a3, a2
206 ; RV32I-FPELIM-NEXT: or a0, a2, a0
207 ; RV32I-FPELIM-NEXT: or a0, a0, a4
208 ; RV32I-FPELIM-NEXT: seqz a0, a0
209 ; RV32I-FPELIM-NEXT: ret
211 ; RV32I-WITHFP-LABEL: callee_large_scalars:
212 ; RV32I-WITHFP: # %bb.0:
213 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
214 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
215 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
216 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
217 ; RV32I-WITHFP-NEXT: lw a2, 0(a1)
218 ; RV32I-WITHFP-NEXT: lw a3, 0(a0)
219 ; RV32I-WITHFP-NEXT: lw a4, 4(a1)
220 ; RV32I-WITHFP-NEXT: lw a5, 12(a1)
221 ; RV32I-WITHFP-NEXT: lw a6, 12(a0)
222 ; RV32I-WITHFP-NEXT: lw a7, 4(a0)
223 ; RV32I-WITHFP-NEXT: lw a1, 8(a1)
224 ; RV32I-WITHFP-NEXT: lw a0, 8(a0)
225 ; RV32I-WITHFP-NEXT: xor a5, a6, a5
226 ; RV32I-WITHFP-NEXT: xor a4, a7, a4
227 ; RV32I-WITHFP-NEXT: or a4, a4, a5
228 ; RV32I-WITHFP-NEXT: xor a0, a0, a1
229 ; RV32I-WITHFP-NEXT: xor a2, a3, a2
230 ; RV32I-WITHFP-NEXT: or a0, a2, a0
231 ; RV32I-WITHFP-NEXT: or a0, a0, a4
232 ; RV32I-WITHFP-NEXT: seqz a0, a0
233 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
234 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
235 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
236 ; RV32I-WITHFP-NEXT: ret
237 %b_bitcast = bitcast fp128 %b to i128
238 %1 = icmp eq i128 %a, %b_bitcast
239 %2 = zext i1 %1 to i32
243 define i32 @caller_large_scalars() nounwind {
244 ; RV32I-FPELIM-LABEL: caller_large_scalars:
245 ; RV32I-FPELIM: # %bb.0:
246 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
247 ; RV32I-FPELIM-NEXT: sw ra, 44(sp) # 4-byte Folded Spill
248 ; RV32I-FPELIM-NEXT: lui a0, 524272
249 ; RV32I-FPELIM-NEXT: sw a0, 12(sp)
250 ; RV32I-FPELIM-NEXT: sw zero, 8(sp)
251 ; RV32I-FPELIM-NEXT: sw zero, 4(sp)
252 ; RV32I-FPELIM-NEXT: sw zero, 0(sp)
253 ; RV32I-FPELIM-NEXT: sw zero, 36(sp)
254 ; RV32I-FPELIM-NEXT: sw zero, 32(sp)
255 ; RV32I-FPELIM-NEXT: sw zero, 28(sp)
256 ; RV32I-FPELIM-NEXT: li a2, 1
257 ; RV32I-FPELIM-NEXT: addi a0, sp, 24
258 ; RV32I-FPELIM-NEXT: mv a1, sp
259 ; RV32I-FPELIM-NEXT: sw a2, 24(sp)
260 ; RV32I-FPELIM-NEXT: call callee_large_scalars
261 ; RV32I-FPELIM-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
262 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
263 ; RV32I-FPELIM-NEXT: ret
265 ; RV32I-WITHFP-LABEL: caller_large_scalars:
266 ; RV32I-WITHFP: # %bb.0:
267 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
268 ; RV32I-WITHFP-NEXT: sw ra, 44(sp) # 4-byte Folded Spill
269 ; RV32I-WITHFP-NEXT: sw s0, 40(sp) # 4-byte Folded Spill
270 ; RV32I-WITHFP-NEXT: addi s0, sp, 48
271 ; RV32I-WITHFP-NEXT: lui a0, 524272
272 ; RV32I-WITHFP-NEXT: sw a0, -36(s0)
273 ; RV32I-WITHFP-NEXT: sw zero, -40(s0)
274 ; RV32I-WITHFP-NEXT: sw zero, -44(s0)
275 ; RV32I-WITHFP-NEXT: sw zero, -48(s0)
276 ; RV32I-WITHFP-NEXT: sw zero, -12(s0)
277 ; RV32I-WITHFP-NEXT: sw zero, -16(s0)
278 ; RV32I-WITHFP-NEXT: sw zero, -20(s0)
279 ; RV32I-WITHFP-NEXT: li a2, 1
280 ; RV32I-WITHFP-NEXT: addi a0, s0, -24
281 ; RV32I-WITHFP-NEXT: addi a1, s0, -48
282 ; RV32I-WITHFP-NEXT: sw a2, -24(s0)
283 ; RV32I-WITHFP-NEXT: call callee_large_scalars
284 ; RV32I-WITHFP-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
285 ; RV32I-WITHFP-NEXT: lw s0, 40(sp) # 4-byte Folded Reload
286 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
287 ; RV32I-WITHFP-NEXT: ret
288 %1 = call i32 @callee_large_scalars(i128 1, fp128 0xL00000000000000007FFF000000000000)
292 ; Check that arguments larger than 2*xlen are handled correctly when their
293 ; address is passed on the stack rather than in memory
295 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
296 define i32 @callee_large_scalars_exhausted_regs(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i128 %h, i32 %i, fp128 %j) nounwind {
297 ; RV32I-FPELIM-LABEL: callee_large_scalars_exhausted_regs:
298 ; RV32I-FPELIM: # %bb.0:
299 ; RV32I-FPELIM-NEXT: lw a0, 4(sp)
300 ; RV32I-FPELIM-NEXT: lw a1, 0(a0)
301 ; RV32I-FPELIM-NEXT: lw a2, 0(a7)
302 ; RV32I-FPELIM-NEXT: lw a3, 4(a0)
303 ; RV32I-FPELIM-NEXT: lw a4, 12(a0)
304 ; RV32I-FPELIM-NEXT: lw a5, 12(a7)
305 ; RV32I-FPELIM-NEXT: lw a6, 4(a7)
306 ; RV32I-FPELIM-NEXT: lw a0, 8(a0)
307 ; RV32I-FPELIM-NEXT: lw a7, 8(a7)
308 ; RV32I-FPELIM-NEXT: xor a4, a5, a4
309 ; RV32I-FPELIM-NEXT: xor a3, a6, a3
310 ; RV32I-FPELIM-NEXT: or a3, a3, a4
311 ; RV32I-FPELIM-NEXT: xor a0, a7, a0
312 ; RV32I-FPELIM-NEXT: xor a1, a2, a1
313 ; RV32I-FPELIM-NEXT: or a0, a1, a0
314 ; RV32I-FPELIM-NEXT: or a0, a0, a3
315 ; RV32I-FPELIM-NEXT: seqz a0, a0
316 ; RV32I-FPELIM-NEXT: ret
318 ; RV32I-WITHFP-LABEL: callee_large_scalars_exhausted_regs:
319 ; RV32I-WITHFP: # %bb.0:
320 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
321 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
322 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
323 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
324 ; RV32I-WITHFP-NEXT: lw a0, 4(s0)
325 ; RV32I-WITHFP-NEXT: lw a1, 0(a0)
326 ; RV32I-WITHFP-NEXT: lw a2, 0(a7)
327 ; RV32I-WITHFP-NEXT: lw a3, 4(a0)
328 ; RV32I-WITHFP-NEXT: lw a4, 12(a0)
329 ; RV32I-WITHFP-NEXT: lw a5, 12(a7)
330 ; RV32I-WITHFP-NEXT: lw a6, 4(a7)
331 ; RV32I-WITHFP-NEXT: lw a0, 8(a0)
332 ; RV32I-WITHFP-NEXT: lw a7, 8(a7)
333 ; RV32I-WITHFP-NEXT: xor a4, a5, a4
334 ; RV32I-WITHFP-NEXT: xor a3, a6, a3
335 ; RV32I-WITHFP-NEXT: or a3, a3, a4
336 ; RV32I-WITHFP-NEXT: xor a0, a7, a0
337 ; RV32I-WITHFP-NEXT: xor a1, a2, a1
338 ; RV32I-WITHFP-NEXT: or a0, a1, a0
339 ; RV32I-WITHFP-NEXT: or a0, a0, a3
340 ; RV32I-WITHFP-NEXT: seqz a0, a0
341 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
342 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
343 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
344 ; RV32I-WITHFP-NEXT: ret
345 %j_bitcast = bitcast fp128 %j to i128
346 %1 = icmp eq i128 %h, %j_bitcast
347 %2 = zext i1 %1 to i32
351 define i32 @caller_large_scalars_exhausted_regs() nounwind {
352 ; RV32I-FPELIM-LABEL: caller_large_scalars_exhausted_regs:
353 ; RV32I-FPELIM: # %bb.0:
354 ; RV32I-FPELIM-NEXT: addi sp, sp, -64
355 ; RV32I-FPELIM-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
356 ; RV32I-FPELIM-NEXT: addi a0, sp, 16
357 ; RV32I-FPELIM-NEXT: sw a0, 4(sp)
358 ; RV32I-FPELIM-NEXT: li a0, 9
359 ; RV32I-FPELIM-NEXT: sw a0, 0(sp)
360 ; RV32I-FPELIM-NEXT: lui a0, 524272
361 ; RV32I-FPELIM-NEXT: sw a0, 28(sp)
362 ; RV32I-FPELIM-NEXT: sw zero, 24(sp)
363 ; RV32I-FPELIM-NEXT: sw zero, 20(sp)
364 ; RV32I-FPELIM-NEXT: sw zero, 16(sp)
365 ; RV32I-FPELIM-NEXT: sw zero, 52(sp)
366 ; RV32I-FPELIM-NEXT: sw zero, 48(sp)
367 ; RV32I-FPELIM-NEXT: li a0, 8
368 ; RV32I-FPELIM-NEXT: sw a0, 40(sp)
369 ; RV32I-FPELIM-NEXT: li a0, 1
370 ; RV32I-FPELIM-NEXT: li a1, 2
371 ; RV32I-FPELIM-NEXT: li a2, 3
372 ; RV32I-FPELIM-NEXT: li a3, 4
373 ; RV32I-FPELIM-NEXT: li a4, 5
374 ; RV32I-FPELIM-NEXT: li a5, 6
375 ; RV32I-FPELIM-NEXT: li a6, 7
376 ; RV32I-FPELIM-NEXT: addi a7, sp, 40
377 ; RV32I-FPELIM-NEXT: sw zero, 44(sp)
378 ; RV32I-FPELIM-NEXT: call callee_large_scalars_exhausted_regs
379 ; RV32I-FPELIM-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
380 ; RV32I-FPELIM-NEXT: addi sp, sp, 64
381 ; RV32I-FPELIM-NEXT: ret
383 ; RV32I-WITHFP-LABEL: caller_large_scalars_exhausted_regs:
384 ; RV32I-WITHFP: # %bb.0:
385 ; RV32I-WITHFP-NEXT: addi sp, sp, -64
386 ; RV32I-WITHFP-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
387 ; RV32I-WITHFP-NEXT: sw s0, 56(sp) # 4-byte Folded Spill
388 ; RV32I-WITHFP-NEXT: addi s0, sp, 64
389 ; RV32I-WITHFP-NEXT: addi a0, s0, -48
390 ; RV32I-WITHFP-NEXT: sw a0, 4(sp)
391 ; RV32I-WITHFP-NEXT: li a0, 9
392 ; RV32I-WITHFP-NEXT: sw a0, 0(sp)
393 ; RV32I-WITHFP-NEXT: lui a0, 524272
394 ; RV32I-WITHFP-NEXT: sw a0, -36(s0)
395 ; RV32I-WITHFP-NEXT: sw zero, -40(s0)
396 ; RV32I-WITHFP-NEXT: sw zero, -44(s0)
397 ; RV32I-WITHFP-NEXT: sw zero, -48(s0)
398 ; RV32I-WITHFP-NEXT: sw zero, -12(s0)
399 ; RV32I-WITHFP-NEXT: sw zero, -16(s0)
400 ; RV32I-WITHFP-NEXT: li a0, 8
401 ; RV32I-WITHFP-NEXT: sw a0, -24(s0)
402 ; RV32I-WITHFP-NEXT: li a0, 1
403 ; RV32I-WITHFP-NEXT: li a1, 2
404 ; RV32I-WITHFP-NEXT: li a2, 3
405 ; RV32I-WITHFP-NEXT: li a3, 4
406 ; RV32I-WITHFP-NEXT: li a4, 5
407 ; RV32I-WITHFP-NEXT: li a5, 6
408 ; RV32I-WITHFP-NEXT: li a6, 7
409 ; RV32I-WITHFP-NEXT: addi a7, s0, -24
410 ; RV32I-WITHFP-NEXT: sw zero, -20(s0)
411 ; RV32I-WITHFP-NEXT: call callee_large_scalars_exhausted_regs
412 ; RV32I-WITHFP-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
413 ; RV32I-WITHFP-NEXT: lw s0, 56(sp) # 4-byte Folded Reload
414 ; RV32I-WITHFP-NEXT: addi sp, sp, 64
415 ; RV32I-WITHFP-NEXT: ret
416 %1 = call i32 @callee_large_scalars_exhausted_regs(
417 i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i128 8, i32 9,
418 fp128 0xL00000000000000007FFF000000000000)
422 ; Ensure that libcalls generated in the middle-end obey the calling convention
424 define i32 @caller_mixed_scalar_libcalls(i64 %a) nounwind {
425 ; RV32I-FPELIM-LABEL: caller_mixed_scalar_libcalls:
426 ; RV32I-FPELIM: # %bb.0:
427 ; RV32I-FPELIM-NEXT: addi sp, sp, -32
428 ; RV32I-FPELIM-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
429 ; RV32I-FPELIM-NEXT: mv a2, a1
430 ; RV32I-FPELIM-NEXT: mv a1, a0
431 ; RV32I-FPELIM-NEXT: addi a0, sp, 8
432 ; RV32I-FPELIM-NEXT: call __floatditf
433 ; RV32I-FPELIM-NEXT: lw a0, 8(sp)
434 ; RV32I-FPELIM-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
435 ; RV32I-FPELIM-NEXT: addi sp, sp, 32
436 ; RV32I-FPELIM-NEXT: ret
438 ; RV32I-WITHFP-LABEL: caller_mixed_scalar_libcalls:
439 ; RV32I-WITHFP: # %bb.0:
440 ; RV32I-WITHFP-NEXT: addi sp, sp, -32
441 ; RV32I-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
442 ; RV32I-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
443 ; RV32I-WITHFP-NEXT: addi s0, sp, 32
444 ; RV32I-WITHFP-NEXT: mv a2, a1
445 ; RV32I-WITHFP-NEXT: mv a1, a0
446 ; RV32I-WITHFP-NEXT: addi a0, s0, -24
447 ; RV32I-WITHFP-NEXT: call __floatditf
448 ; RV32I-WITHFP-NEXT: lw a0, -24(s0)
449 ; RV32I-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
450 ; RV32I-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
451 ; RV32I-WITHFP-NEXT: addi sp, sp, 32
452 ; RV32I-WITHFP-NEXT: ret
453 %1 = sitofp i64 %a to fp128
454 %2 = bitcast fp128 %1 to i128
455 %3 = trunc i128 %2 to i32
459 ; Check passing of coerced integer arrays
461 %struct.small = type { i32, ptr }
463 define i32 @callee_small_coerced_struct([2 x i32] %a.coerce) nounwind {
464 ; RV32I-FPELIM-LABEL: callee_small_coerced_struct:
465 ; RV32I-FPELIM: # %bb.0:
466 ; RV32I-FPELIM-NEXT: xor a0, a0, a1
467 ; RV32I-FPELIM-NEXT: seqz a0, a0
468 ; RV32I-FPELIM-NEXT: ret
470 ; RV32I-WITHFP-LABEL: callee_small_coerced_struct:
471 ; RV32I-WITHFP: # %bb.0:
472 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
473 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
474 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
475 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
476 ; RV32I-WITHFP-NEXT: xor a0, a0, a1
477 ; RV32I-WITHFP-NEXT: seqz a0, a0
478 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
479 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
480 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
481 ; RV32I-WITHFP-NEXT: ret
482 %1 = extractvalue [2 x i32] %a.coerce, 0
483 %2 = extractvalue [2 x i32] %a.coerce, 1
484 %3 = icmp eq i32 %1, %2
485 %4 = zext i1 %3 to i32
489 define i32 @caller_small_coerced_struct() nounwind {
490 ; RV32I-FPELIM-LABEL: caller_small_coerced_struct:
491 ; RV32I-FPELIM: # %bb.0:
492 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
493 ; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
494 ; RV32I-FPELIM-NEXT: li a0, 1
495 ; RV32I-FPELIM-NEXT: li a1, 2
496 ; RV32I-FPELIM-NEXT: call callee_small_coerced_struct
497 ; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
498 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
499 ; RV32I-FPELIM-NEXT: ret
501 ; RV32I-WITHFP-LABEL: caller_small_coerced_struct:
502 ; RV32I-WITHFP: # %bb.0:
503 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
504 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
505 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
506 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
507 ; RV32I-WITHFP-NEXT: li a0, 1
508 ; RV32I-WITHFP-NEXT: li a1, 2
509 ; RV32I-WITHFP-NEXT: call callee_small_coerced_struct
510 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
511 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
512 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
513 ; RV32I-WITHFP-NEXT: ret
514 %1 = call i32 @callee_small_coerced_struct([2 x i32] [i32 1, i32 2])
518 ; Check large struct arguments, which are passed byval
520 %struct.large = type { i32, i32, i32, i32 }
522 define i32 @callee_large_struct(ptr byval(%struct.large) align 4 %a) nounwind {
523 ; RV32I-FPELIM-LABEL: callee_large_struct:
524 ; RV32I-FPELIM: # %bb.0:
525 ; RV32I-FPELIM-NEXT: lw a1, 0(a0)
526 ; RV32I-FPELIM-NEXT: lw a0, 12(a0)
527 ; RV32I-FPELIM-NEXT: add a0, a1, a0
528 ; RV32I-FPELIM-NEXT: ret
530 ; RV32I-WITHFP-LABEL: callee_large_struct:
531 ; RV32I-WITHFP: # %bb.0:
532 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
533 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
534 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
535 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
536 ; RV32I-WITHFP-NEXT: lw a1, 0(a0)
537 ; RV32I-WITHFP-NEXT: lw a0, 12(a0)
538 ; RV32I-WITHFP-NEXT: add a0, a1, a0
539 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
540 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
541 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
542 ; RV32I-WITHFP-NEXT: ret
543 %1 = getelementptr inbounds %struct.large, ptr %a, i32 0, i32 3
544 %2 = load i32, ptr %a
545 %3 = load i32, ptr %1
550 define i32 @caller_large_struct() nounwind {
551 ; RV32I-FPELIM-LABEL: caller_large_struct:
552 ; RV32I-FPELIM: # %bb.0:
553 ; RV32I-FPELIM-NEXT: addi sp, sp, -48
554 ; RV32I-FPELIM-NEXT: sw ra, 44(sp) # 4-byte Folded Spill
555 ; RV32I-FPELIM-NEXT: li a0, 1
556 ; RV32I-FPELIM-NEXT: sw a0, 24(sp)
557 ; RV32I-FPELIM-NEXT: li a1, 2
558 ; RV32I-FPELIM-NEXT: sw a1, 28(sp)
559 ; RV32I-FPELIM-NEXT: li a2, 3
560 ; RV32I-FPELIM-NEXT: sw a2, 32(sp)
561 ; RV32I-FPELIM-NEXT: li a3, 4
562 ; RV32I-FPELIM-NEXT: sw a3, 36(sp)
563 ; RV32I-FPELIM-NEXT: sw a0, 8(sp)
564 ; RV32I-FPELIM-NEXT: sw a1, 12(sp)
565 ; RV32I-FPELIM-NEXT: sw a2, 16(sp)
566 ; RV32I-FPELIM-NEXT: sw a3, 20(sp)
567 ; RV32I-FPELIM-NEXT: addi a0, sp, 8
568 ; RV32I-FPELIM-NEXT: call callee_large_struct
569 ; RV32I-FPELIM-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
570 ; RV32I-FPELIM-NEXT: addi sp, sp, 48
571 ; RV32I-FPELIM-NEXT: ret
573 ; RV32I-WITHFP-LABEL: caller_large_struct:
574 ; RV32I-WITHFP: # %bb.0:
575 ; RV32I-WITHFP-NEXT: addi sp, sp, -48
576 ; RV32I-WITHFP-NEXT: sw ra, 44(sp) # 4-byte Folded Spill
577 ; RV32I-WITHFP-NEXT: sw s0, 40(sp) # 4-byte Folded Spill
578 ; RV32I-WITHFP-NEXT: addi s0, sp, 48
579 ; RV32I-WITHFP-NEXT: li a0, 1
580 ; RV32I-WITHFP-NEXT: sw a0, -24(s0)
581 ; RV32I-WITHFP-NEXT: li a1, 2
582 ; RV32I-WITHFP-NEXT: sw a1, -20(s0)
583 ; RV32I-WITHFP-NEXT: li a2, 3
584 ; RV32I-WITHFP-NEXT: sw a2, -16(s0)
585 ; RV32I-WITHFP-NEXT: li a3, 4
586 ; RV32I-WITHFP-NEXT: sw a3, -12(s0)
587 ; RV32I-WITHFP-NEXT: sw a0, -40(s0)
588 ; RV32I-WITHFP-NEXT: sw a1, -36(s0)
589 ; RV32I-WITHFP-NEXT: sw a2, -32(s0)
590 ; RV32I-WITHFP-NEXT: sw a3, -28(s0)
591 ; RV32I-WITHFP-NEXT: addi a0, s0, -40
592 ; RV32I-WITHFP-NEXT: call callee_large_struct
593 ; RV32I-WITHFP-NEXT: lw ra, 44(sp) # 4-byte Folded Reload
594 ; RV32I-WITHFP-NEXT: lw s0, 40(sp) # 4-byte Folded Reload
595 ; RV32I-WITHFP-NEXT: addi sp, sp, 48
596 ; RV32I-WITHFP-NEXT: ret
597 %ls = alloca %struct.large, align 8
599 %b = getelementptr inbounds %struct.large, ptr %ls, i32 0, i32 1
601 %c = getelementptr inbounds %struct.large, ptr %ls, i32 0, i32 2
603 %d = getelementptr inbounds %struct.large, ptr %ls, i32 0, i32 3
605 %1 = call i32 @callee_large_struct(ptr byval(%struct.large) align 4 %ls)
609 ; Check 2x*xlen values are aligned appropriately when passed on the stack
610 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
611 define i32 @callee_aligned_stack(i32 %a, i32 %b, fp128 %c, i32 %d, i32 %e, i64 %f, i32 %g, i32 %h, i64 %i, i32 %j, [2 x i32] %k) nounwind {
612 ; The i64 should be 8-byte aligned on the stack, but the two-element array
613 ; should only be 4-byte aligned
614 ; RV32I-FPELIM-LABEL: callee_aligned_stack:
615 ; RV32I-FPELIM: # %bb.0:
616 ; RV32I-FPELIM-NEXT: lw a0, 0(a2)
617 ; RV32I-FPELIM-NEXT: lw a1, 8(sp)
618 ; RV32I-FPELIM-NEXT: lw a2, 0(sp)
619 ; RV32I-FPELIM-NEXT: lw a3, 20(sp)
620 ; RV32I-FPELIM-NEXT: lw a4, 16(sp)
621 ; RV32I-FPELIM-NEXT: add a0, a0, a7
622 ; RV32I-FPELIM-NEXT: add a1, a2, a1
623 ; RV32I-FPELIM-NEXT: add a0, a0, a1
624 ; RV32I-FPELIM-NEXT: add a3, a4, a3
625 ; RV32I-FPELIM-NEXT: add a0, a0, a3
626 ; RV32I-FPELIM-NEXT: ret
628 ; RV32I-WITHFP-LABEL: callee_aligned_stack:
629 ; RV32I-WITHFP: # %bb.0:
630 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
631 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
632 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
633 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
634 ; RV32I-WITHFP-NEXT: lw a0, 0(a2)
635 ; RV32I-WITHFP-NEXT: lw a1, 8(s0)
636 ; RV32I-WITHFP-NEXT: lw a2, 0(s0)
637 ; RV32I-WITHFP-NEXT: lw a3, 20(s0)
638 ; RV32I-WITHFP-NEXT: lw a4, 16(s0)
639 ; RV32I-WITHFP-NEXT: add a0, a0, a7
640 ; RV32I-WITHFP-NEXT: add a1, a2, a1
641 ; RV32I-WITHFP-NEXT: add a0, a0, a1
642 ; RV32I-WITHFP-NEXT: add a3, a4, a3
643 ; RV32I-WITHFP-NEXT: add a0, a0, a3
644 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
645 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
646 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
647 ; RV32I-WITHFP-NEXT: ret
648 %1 = bitcast fp128 %c to i128
649 %2 = trunc i128 %1 to i32
652 %5 = trunc i64 %i to i32
655 %8 = extractvalue [2 x i32] %k, 0
660 define void @caller_aligned_stack() nounwind {
661 ; The i64 should be 8-byte aligned on the stack, but the two-element array
662 ; should only be 4-byte aligned
663 ; RV32I-FPELIM-LABEL: caller_aligned_stack:
664 ; RV32I-FPELIM: # %bb.0:
665 ; RV32I-FPELIM-NEXT: addi sp, sp, -64
666 ; RV32I-FPELIM-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
667 ; RV32I-FPELIM-NEXT: li a0, 19
668 ; RV32I-FPELIM-NEXT: sw a0, 24(sp)
669 ; RV32I-FPELIM-NEXT: li a0, 18
670 ; RV32I-FPELIM-NEXT: sw a0, 20(sp)
671 ; RV32I-FPELIM-NEXT: li a0, 17
672 ; RV32I-FPELIM-NEXT: sw a0, 16(sp)
673 ; RV32I-FPELIM-NEXT: sw zero, 12(sp)
674 ; RV32I-FPELIM-NEXT: li a0, 16
675 ; RV32I-FPELIM-NEXT: sw a0, 8(sp)
676 ; RV32I-FPELIM-NEXT: li a0, 15
677 ; RV32I-FPELIM-NEXT: sw a0, 0(sp)
678 ; RV32I-FPELIM-NEXT: lui a0, 262153
679 ; RV32I-FPELIM-NEXT: addi a0, a0, 491
680 ; RV32I-FPELIM-NEXT: sw a0, 44(sp)
681 ; RV32I-FPELIM-NEXT: lui a0, 545260
682 ; RV32I-FPELIM-NEXT: addi a0, a0, -1967
683 ; RV32I-FPELIM-NEXT: sw a0, 40(sp)
684 ; RV32I-FPELIM-NEXT: lui a0, 964690
685 ; RV32I-FPELIM-NEXT: addi a0, a0, -328
686 ; RV32I-FPELIM-NEXT: sw a0, 36(sp)
687 ; RV32I-FPELIM-NEXT: lui a0, 335544
688 ; RV32I-FPELIM-NEXT: addi t0, a0, 1311
689 ; RV32I-FPELIM-NEXT: lui a0, 688509
690 ; RV32I-FPELIM-NEXT: addi a5, a0, -2048
691 ; RV32I-FPELIM-NEXT: li a0, 1
692 ; RV32I-FPELIM-NEXT: li a1, 11
693 ; RV32I-FPELIM-NEXT: addi a2, sp, 32
694 ; RV32I-FPELIM-NEXT: li a3, 12
695 ; RV32I-FPELIM-NEXT: li a4, 13
696 ; RV32I-FPELIM-NEXT: li a6, 4
697 ; RV32I-FPELIM-NEXT: li a7, 14
698 ; RV32I-FPELIM-NEXT: sw t0, 32(sp)
699 ; RV32I-FPELIM-NEXT: call callee_aligned_stack
700 ; RV32I-FPELIM-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
701 ; RV32I-FPELIM-NEXT: addi sp, sp, 64
702 ; RV32I-FPELIM-NEXT: ret
704 ; RV32I-WITHFP-LABEL: caller_aligned_stack:
705 ; RV32I-WITHFP: # %bb.0:
706 ; RV32I-WITHFP-NEXT: addi sp, sp, -64
707 ; RV32I-WITHFP-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
708 ; RV32I-WITHFP-NEXT: sw s0, 56(sp) # 4-byte Folded Spill
709 ; RV32I-WITHFP-NEXT: addi s0, sp, 64
710 ; RV32I-WITHFP-NEXT: li a0, 19
711 ; RV32I-WITHFP-NEXT: sw a0, 24(sp)
712 ; RV32I-WITHFP-NEXT: li a0, 18
713 ; RV32I-WITHFP-NEXT: sw a0, 20(sp)
714 ; RV32I-WITHFP-NEXT: li a0, 17
715 ; RV32I-WITHFP-NEXT: sw a0, 16(sp)
716 ; RV32I-WITHFP-NEXT: sw zero, 12(sp)
717 ; RV32I-WITHFP-NEXT: li a0, 16
718 ; RV32I-WITHFP-NEXT: sw a0, 8(sp)
719 ; RV32I-WITHFP-NEXT: li a0, 15
720 ; RV32I-WITHFP-NEXT: sw a0, 0(sp)
721 ; RV32I-WITHFP-NEXT: lui a0, 262153
722 ; RV32I-WITHFP-NEXT: addi a0, a0, 491
723 ; RV32I-WITHFP-NEXT: sw a0, -20(s0)
724 ; RV32I-WITHFP-NEXT: lui a0, 545260
725 ; RV32I-WITHFP-NEXT: addi a0, a0, -1967
726 ; RV32I-WITHFP-NEXT: sw a0, -24(s0)
727 ; RV32I-WITHFP-NEXT: lui a0, 964690
728 ; RV32I-WITHFP-NEXT: addi a0, a0, -328
729 ; RV32I-WITHFP-NEXT: sw a0, -28(s0)
730 ; RV32I-WITHFP-NEXT: lui a0, 335544
731 ; RV32I-WITHFP-NEXT: addi t0, a0, 1311
732 ; RV32I-WITHFP-NEXT: lui a0, 688509
733 ; RV32I-WITHFP-NEXT: addi a5, a0, -2048
734 ; RV32I-WITHFP-NEXT: li a0, 1
735 ; RV32I-WITHFP-NEXT: li a1, 11
736 ; RV32I-WITHFP-NEXT: addi a2, s0, -32
737 ; RV32I-WITHFP-NEXT: li a3, 12
738 ; RV32I-WITHFP-NEXT: li a4, 13
739 ; RV32I-WITHFP-NEXT: li a6, 4
740 ; RV32I-WITHFP-NEXT: li a7, 14
741 ; RV32I-WITHFP-NEXT: sw t0, -32(s0)
742 ; RV32I-WITHFP-NEXT: call callee_aligned_stack
743 ; RV32I-WITHFP-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
744 ; RV32I-WITHFP-NEXT: lw s0, 56(sp) # 4-byte Folded Reload
745 ; RV32I-WITHFP-NEXT: addi sp, sp, 64
746 ; RV32I-WITHFP-NEXT: ret
747 %1 = call i32 @callee_aligned_stack(i32 1, i32 11,
748 fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13,
749 i64 20000000000, i32 14, i32 15, i64 16, i32 17,
750 [2 x i32] [i32 18, i32 19])
754 ; Check return of 2x xlen scalars
756 define i64 @callee_small_scalar_ret() nounwind {
757 ; RV32I-FPELIM-LABEL: callee_small_scalar_ret:
758 ; RV32I-FPELIM: # %bb.0:
759 ; RV32I-FPELIM-NEXT: lui a0, 466866
760 ; RV32I-FPELIM-NEXT: addi a0, a0, 1677
761 ; RV32I-FPELIM-NEXT: li a1, 287
762 ; RV32I-FPELIM-NEXT: ret
764 ; RV32I-WITHFP-LABEL: callee_small_scalar_ret:
765 ; RV32I-WITHFP: # %bb.0:
766 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
767 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
768 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
769 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
770 ; RV32I-WITHFP-NEXT: lui a0, 466866
771 ; RV32I-WITHFP-NEXT: addi a0, a0, 1677
772 ; RV32I-WITHFP-NEXT: li a1, 287
773 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
774 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
775 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
776 ; RV32I-WITHFP-NEXT: ret
777 ret i64 1234567898765
780 define i32 @caller_small_scalar_ret() nounwind {
781 ; RV32I-FPELIM-LABEL: caller_small_scalar_ret:
782 ; RV32I-FPELIM: # %bb.0:
783 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
784 ; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
785 ; RV32I-FPELIM-NEXT: call callee_small_scalar_ret
786 ; RV32I-FPELIM-NEXT: lui a2, 56
787 ; RV32I-FPELIM-NEXT: addi a2, a2, 580
788 ; RV32I-FPELIM-NEXT: xor a1, a1, a2
789 ; RV32I-FPELIM-NEXT: lui a2, 200614
790 ; RV32I-FPELIM-NEXT: addi a2, a2, 647
791 ; RV32I-FPELIM-NEXT: xor a0, a0, a2
792 ; RV32I-FPELIM-NEXT: or a0, a0, a1
793 ; RV32I-FPELIM-NEXT: seqz a0, a0
794 ; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
795 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
796 ; RV32I-FPELIM-NEXT: ret
798 ; RV32I-WITHFP-LABEL: caller_small_scalar_ret:
799 ; RV32I-WITHFP: # %bb.0:
800 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
801 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
802 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
803 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
804 ; RV32I-WITHFP-NEXT: call callee_small_scalar_ret
805 ; RV32I-WITHFP-NEXT: lui a2, 56
806 ; RV32I-WITHFP-NEXT: addi a2, a2, 580
807 ; RV32I-WITHFP-NEXT: xor a1, a1, a2
808 ; RV32I-WITHFP-NEXT: lui a2, 200614
809 ; RV32I-WITHFP-NEXT: addi a2, a2, 647
810 ; RV32I-WITHFP-NEXT: xor a0, a0, a2
811 ; RV32I-WITHFP-NEXT: or a0, a0, a1
812 ; RV32I-WITHFP-NEXT: seqz a0, a0
813 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
814 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
815 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
816 ; RV32I-WITHFP-NEXT: ret
817 %1 = call i64 @callee_small_scalar_ret()
818 %2 = icmp eq i64 987654321234567, %1
819 %3 = zext i1 %2 to i32
823 ; Check return of 2x xlen structs
825 define %struct.small @callee_small_struct_ret() nounwind {
826 ; RV32I-FPELIM-LABEL: callee_small_struct_ret:
827 ; RV32I-FPELIM: # %bb.0:
828 ; RV32I-FPELIM-NEXT: li a0, 1
829 ; RV32I-FPELIM-NEXT: li a1, 0
830 ; RV32I-FPELIM-NEXT: ret
832 ; RV32I-WITHFP-LABEL: callee_small_struct_ret:
833 ; RV32I-WITHFP: # %bb.0:
834 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
835 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
836 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
837 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
838 ; RV32I-WITHFP-NEXT: li a0, 1
839 ; RV32I-WITHFP-NEXT: li a1, 0
840 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
841 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
842 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
843 ; RV32I-WITHFP-NEXT: ret
844 ret %struct.small { i32 1, ptr null }
847 define i32 @caller_small_struct_ret() nounwind {
848 ; RV32I-FPELIM-LABEL: caller_small_struct_ret:
849 ; RV32I-FPELIM: # %bb.0:
850 ; RV32I-FPELIM-NEXT: addi sp, sp, -16
851 ; RV32I-FPELIM-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
852 ; RV32I-FPELIM-NEXT: call callee_small_struct_ret
853 ; RV32I-FPELIM-NEXT: add a0, a0, a1
854 ; RV32I-FPELIM-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
855 ; RV32I-FPELIM-NEXT: addi sp, sp, 16
856 ; RV32I-FPELIM-NEXT: ret
858 ; RV32I-WITHFP-LABEL: caller_small_struct_ret:
859 ; RV32I-WITHFP: # %bb.0:
860 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
861 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
862 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
863 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
864 ; RV32I-WITHFP-NEXT: call callee_small_struct_ret
865 ; RV32I-WITHFP-NEXT: add a0, a0, a1
866 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
867 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
868 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
869 ; RV32I-WITHFP-NEXT: ret
870 %1 = call %struct.small @callee_small_struct_ret()
871 %2 = extractvalue %struct.small %1, 0
872 %3 = extractvalue %struct.small %1, 1
873 %4 = ptrtoint ptr %3 to i32
878 ; Check return of >2x xlen scalars
880 define fp128 @callee_large_scalar_ret() nounwind {
881 ; RV32I-FPELIM-LABEL: callee_large_scalar_ret:
882 ; RV32I-FPELIM: # %bb.0:
883 ; RV32I-FPELIM-NEXT: lui a1, 524272
884 ; RV32I-FPELIM-NEXT: sw a1, 12(a0)
885 ; RV32I-FPELIM-NEXT: sw zero, 8(a0)
886 ; RV32I-FPELIM-NEXT: sw zero, 4(a0)
887 ; RV32I-FPELIM-NEXT: sw zero, 0(a0)
888 ; RV32I-FPELIM-NEXT: ret
890 ; RV32I-WITHFP-LABEL: callee_large_scalar_ret:
891 ; RV32I-WITHFP: # %bb.0:
892 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
893 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
894 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
895 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
896 ; RV32I-WITHFP-NEXT: lui a1, 524272
897 ; RV32I-WITHFP-NEXT: sw a1, 12(a0)
898 ; RV32I-WITHFP-NEXT: sw zero, 8(a0)
899 ; RV32I-WITHFP-NEXT: sw zero, 4(a0)
900 ; RV32I-WITHFP-NEXT: sw zero, 0(a0)
901 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
902 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
903 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
904 ; RV32I-WITHFP-NEXT: ret
905 ret fp128 0xL00000000000000007FFF000000000000
908 define void @caller_large_scalar_ret() nounwind {
909 ; RV32I-FPELIM-LABEL: caller_large_scalar_ret:
910 ; RV32I-FPELIM: # %bb.0:
911 ; RV32I-FPELIM-NEXT: addi sp, sp, -32
912 ; RV32I-FPELIM-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
913 ; RV32I-FPELIM-NEXT: mv a0, sp
914 ; RV32I-FPELIM-NEXT: call callee_large_scalar_ret
915 ; RV32I-FPELIM-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
916 ; RV32I-FPELIM-NEXT: addi sp, sp, 32
917 ; RV32I-FPELIM-NEXT: ret
919 ; RV32I-WITHFP-LABEL: caller_large_scalar_ret:
920 ; RV32I-WITHFP: # %bb.0:
921 ; RV32I-WITHFP-NEXT: addi sp, sp, -32
922 ; RV32I-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
923 ; RV32I-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
924 ; RV32I-WITHFP-NEXT: addi s0, sp, 32
925 ; RV32I-WITHFP-NEXT: addi a0, s0, -32
926 ; RV32I-WITHFP-NEXT: call callee_large_scalar_ret
927 ; RV32I-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
928 ; RV32I-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
929 ; RV32I-WITHFP-NEXT: addi sp, sp, 32
930 ; RV32I-WITHFP-NEXT: ret
931 %1 = call fp128 @callee_large_scalar_ret()
935 ; Check return of >2x xlen structs
937 define void @callee_large_struct_ret(ptr noalias sret(%struct.large) %agg.result) nounwind {
938 ; RV32I-FPELIM-LABEL: callee_large_struct_ret:
939 ; RV32I-FPELIM: # %bb.0:
940 ; RV32I-FPELIM-NEXT: li a1, 1
941 ; RV32I-FPELIM-NEXT: sw a1, 0(a0)
942 ; RV32I-FPELIM-NEXT: li a1, 2
943 ; RV32I-FPELIM-NEXT: sw a1, 4(a0)
944 ; RV32I-FPELIM-NEXT: li a1, 3
945 ; RV32I-FPELIM-NEXT: sw a1, 8(a0)
946 ; RV32I-FPELIM-NEXT: li a1, 4
947 ; RV32I-FPELIM-NEXT: sw a1, 12(a0)
948 ; RV32I-FPELIM-NEXT: ret
950 ; RV32I-WITHFP-LABEL: callee_large_struct_ret:
951 ; RV32I-WITHFP: # %bb.0:
952 ; RV32I-WITHFP-NEXT: addi sp, sp, -16
953 ; RV32I-WITHFP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
954 ; RV32I-WITHFP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
955 ; RV32I-WITHFP-NEXT: addi s0, sp, 16
956 ; RV32I-WITHFP-NEXT: li a1, 1
957 ; RV32I-WITHFP-NEXT: sw a1, 0(a0)
958 ; RV32I-WITHFP-NEXT: li a1, 2
959 ; RV32I-WITHFP-NEXT: sw a1, 4(a0)
960 ; RV32I-WITHFP-NEXT: li a1, 3
961 ; RV32I-WITHFP-NEXT: sw a1, 8(a0)
962 ; RV32I-WITHFP-NEXT: li a1, 4
963 ; RV32I-WITHFP-NEXT: sw a1, 12(a0)
964 ; RV32I-WITHFP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
965 ; RV32I-WITHFP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
966 ; RV32I-WITHFP-NEXT: addi sp, sp, 16
967 ; RV32I-WITHFP-NEXT: ret
968 store i32 1, ptr %agg.result, align 4
969 %b = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 1
970 store i32 2, ptr %b, align 4
971 %c = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 2
972 store i32 3, ptr %c, align 4
973 %d = getelementptr inbounds %struct.large, ptr %agg.result, i32 0, i32 3
974 store i32 4, ptr %d, align 4
978 define i32 @caller_large_struct_ret() nounwind {
979 ; RV32I-FPELIM-LABEL: caller_large_struct_ret:
980 ; RV32I-FPELIM: # %bb.0:
981 ; RV32I-FPELIM-NEXT: addi sp, sp, -32
982 ; RV32I-FPELIM-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
983 ; RV32I-FPELIM-NEXT: addi a0, sp, 8
984 ; RV32I-FPELIM-NEXT: call callee_large_struct_ret
985 ; RV32I-FPELIM-NEXT: lw a0, 8(sp)
986 ; RV32I-FPELIM-NEXT: lw a1, 20(sp)
987 ; RV32I-FPELIM-NEXT: add a0, a0, a1
988 ; RV32I-FPELIM-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
989 ; RV32I-FPELIM-NEXT: addi sp, sp, 32
990 ; RV32I-FPELIM-NEXT: ret
992 ; RV32I-WITHFP-LABEL: caller_large_struct_ret:
993 ; RV32I-WITHFP: # %bb.0:
994 ; RV32I-WITHFP-NEXT: addi sp, sp, -32
995 ; RV32I-WITHFP-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
996 ; RV32I-WITHFP-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
997 ; RV32I-WITHFP-NEXT: addi s0, sp, 32
998 ; RV32I-WITHFP-NEXT: addi a0, s0, -24
999 ; RV32I-WITHFP-NEXT: call callee_large_struct_ret
1000 ; RV32I-WITHFP-NEXT: lw a0, -24(s0)
1001 ; RV32I-WITHFP-NEXT: lw a1, -12(s0)
1002 ; RV32I-WITHFP-NEXT: add a0, a0, a1
1003 ; RV32I-WITHFP-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1004 ; RV32I-WITHFP-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1005 ; RV32I-WITHFP-NEXT: addi sp, sp, 32
1006 ; RV32I-WITHFP-NEXT: ret
1007 %1 = alloca %struct.large
1008 call void @callee_large_struct_ret(ptr sret(%struct.large) %1)
1009 %2 = load i32, ptr %1
1010 %3 = getelementptr inbounds %struct.large, ptr %1, i32 0, i32 3
1011 %4 = load i32, ptr %3