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