Files
clang-p2996/llvm/test/CodeGen/RISCV/interrupt-attr-nocall.ll
Craig Topper f27f369710 [RISCV] Remove interrupt handler special case from RISCVFrameLowering::determineCalleeSaves. (#88069)
This code was trying to save temporary argument registers in interrupt
handler functions that contain calls. With the exception that all FP
registers are saved including the normally callee saved registers.

If all of the callees use an FP ABI and the interrupt handler doesn't
touch the normally callee saved FP registers, we don't need to save
them.

It doesn't appear that we need to special case functions with calls. The
normal callee saved register handling will already check each of the calls
and consider a register clobbered if the call doesn't explicitly say it is preserved.

All of the test changes are from the removal of the FP callee saved
registers. There are tests for interrupt handlers with F and D extension
that use ilp32 or lp64 ABIs that are not affected by this change. They
still save the FP callee saved registers as they should.

gcc appears to have a bug where the D extension being enabled with the
ilp32f or lp64f ABI does not save the FP callee saved regs. The callee
would only save/restore the lower 32 bits and clobber the upper bits.
LLVM saves the FP callee saved regs in this case and there is an
unchanged test for it.

The unnecessary save/restore was raised in this thread
https://discourse.llvm.org/t/has-bugs-when-optimizing-save-restore-csrs-by-changing-csr-xlen-f32-interrupt/78200/1
2024-04-10 10:28:54 -07:00

704 lines
32 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple riscv32-unknown-elf -o - %s \
; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32
; RUN: llc -mtriple riscv32-unknown-elf -mattr=+f -o - %s \
; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32IF
; RUN: llc -mtriple riscv32-unknown-elf -mattr=+f,+d -o - %s \
; RUN: 2>&1 | FileCheck %s -check-prefix CHECK-RV32IFD
;
; TODO: Add RV64 tests when we can lower global addresses.
; Checking all registers that are used are being saved.
; This includes Caller (arguments and temps) and
; Callee saved registers.
;
; extern int a, b, c;
; __attribute__((interrupt)) void foo_no_call(void) {
; c = a + b;
; }
;
@a = external global i32
@b = external global i32
@c = external global i32
define void @foo_i32() nounwind #0 {
; CHECK-RV32-LABEL: foo_i32:
; CHECK-RV32: # %bb.0:
; CHECK-RV32-NEXT: addi sp, sp, -16
; CHECK-RV32-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a1, 8(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: lui a0, %hi(a)
; CHECK-RV32-NEXT: lw a0, %lo(a)(a0)
; CHECK-RV32-NEXT: lui a1, %hi(b)
; CHECK-RV32-NEXT: lw a1, %lo(b)(a1)
; CHECK-RV32-NEXT: add a0, a1, a0
; CHECK-RV32-NEXT: lui a1, %hi(c)
; CHECK-RV32-NEXT: sw a0, %lo(c)(a1)
; CHECK-RV32-NEXT: lw a0, 12(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a1, 8(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: addi sp, sp, 16
; CHECK-RV32-NEXT: mret
;
; CHECK-RV32IF-LABEL: foo_i32:
; CHECK-RV32IF: # %bb.0:
; CHECK-RV32IF-NEXT: addi sp, sp, -16
; CHECK-RV32IF-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a1, 8(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: lui a0, %hi(a)
; CHECK-RV32IF-NEXT: lw a0, %lo(a)(a0)
; CHECK-RV32IF-NEXT: lui a1, %hi(b)
; CHECK-RV32IF-NEXT: lw a1, %lo(b)(a1)
; CHECK-RV32IF-NEXT: add a0, a1, a0
; CHECK-RV32IF-NEXT: lui a1, %hi(c)
; CHECK-RV32IF-NEXT: sw a0, %lo(c)(a1)
; CHECK-RV32IF-NEXT: lw a0, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a1, 8(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: addi sp, sp, 16
; CHECK-RV32IF-NEXT: mret
;
; CHECK-RV32IFD-LABEL: foo_i32:
; CHECK-RV32IFD: # %bb.0:
; CHECK-RV32IFD-NEXT: addi sp, sp, -16
; CHECK-RV32IFD-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw a1, 8(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: lui a0, %hi(a)
; CHECK-RV32IFD-NEXT: lw a0, %lo(a)(a0)
; CHECK-RV32IFD-NEXT: lui a1, %hi(b)
; CHECK-RV32IFD-NEXT: lw a1, %lo(b)(a1)
; CHECK-RV32IFD-NEXT: add a0, a1, a0
; CHECK-RV32IFD-NEXT: lui a1, %hi(c)
; CHECK-RV32IFD-NEXT: sw a0, %lo(c)(a1)
; CHECK-RV32IFD-NEXT: lw a0, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw a1, 8(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: addi sp, sp, 16
; CHECK-RV32IFD-NEXT: mret
%1 = load i32, ptr @a
%2 = load i32, ptr @b
%add = add nsw i32 %2, %1
store i32 %add, ptr @c
ret void
}
;
; Additionally check frame pointer and return address are properly saved.
;
define void @foo_fp_i32() nounwind #1 {
; CHECK-RV32-LABEL: foo_fp_i32:
; CHECK-RV32: # %bb.0:
; CHECK-RV32-NEXT: addi sp, sp, -16
; CHECK-RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a0, 4(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a1, 0(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: addi s0, sp, 16
; CHECK-RV32-NEXT: lui a0, %hi(a)
; CHECK-RV32-NEXT: lw a0, %lo(a)(a0)
; CHECK-RV32-NEXT: lui a1, %hi(b)
; CHECK-RV32-NEXT: lw a1, %lo(b)(a1)
; CHECK-RV32-NEXT: add a0, a1, a0
; CHECK-RV32-NEXT: lui a1, %hi(c)
; CHECK-RV32-NEXT: sw a0, %lo(c)(a1)
; CHECK-RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a0, 4(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a1, 0(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: addi sp, sp, 16
; CHECK-RV32-NEXT: mret
;
; CHECK-RV32IF-LABEL: foo_fp_i32:
; CHECK-RV32IF: # %bb.0:
; CHECK-RV32IF-NEXT: addi sp, sp, -16
; CHECK-RV32IF-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a0, 4(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a1, 0(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: addi s0, sp, 16
; CHECK-RV32IF-NEXT: lui a0, %hi(a)
; CHECK-RV32IF-NEXT: lw a0, %lo(a)(a0)
; CHECK-RV32IF-NEXT: lui a1, %hi(b)
; CHECK-RV32IF-NEXT: lw a1, %lo(b)(a1)
; CHECK-RV32IF-NEXT: add a0, a1, a0
; CHECK-RV32IF-NEXT: lui a1, %hi(c)
; CHECK-RV32IF-NEXT: sw a0, %lo(c)(a1)
; CHECK-RV32IF-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a0, 4(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a1, 0(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: addi sp, sp, 16
; CHECK-RV32IF-NEXT: mret
;
; CHECK-RV32IFD-LABEL: foo_fp_i32:
; CHECK-RV32IFD: # %bb.0:
; CHECK-RV32IFD-NEXT: addi sp, sp, -16
; CHECK-RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw a0, 4(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw a1, 0(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: addi s0, sp, 16
; CHECK-RV32IFD-NEXT: lui a0, %hi(a)
; CHECK-RV32IFD-NEXT: lw a0, %lo(a)(a0)
; CHECK-RV32IFD-NEXT: lui a1, %hi(b)
; CHECK-RV32IFD-NEXT: lw a1, %lo(b)(a1)
; CHECK-RV32IFD-NEXT: add a0, a1, a0
; CHECK-RV32IFD-NEXT: lui a1, %hi(c)
; CHECK-RV32IFD-NEXT: sw a0, %lo(c)(a1)
; CHECK-RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw a0, 4(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw a1, 0(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: addi sp, sp, 16
; CHECK-RV32IFD-NEXT: mret
%1 = load i32, ptr @a
%2 = load i32, ptr @b
%add = add nsw i32 %2, %1
store i32 %add, ptr @c
ret void
}
@e = external global float
@f = external global float
@d = external global float
define void @foo_float() nounwind #0 {
; CHECK-RV32-LABEL: foo_float:
; CHECK-RV32: # %bb.0:
; CHECK-RV32-NEXT: addi sp, sp, -64
; CHECK-RV32-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t0, 56(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t1, 52(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t2, 48(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a0, 44(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a1, 40(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a2, 36(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a3, 32(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a4, 28(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a5, 24(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a6, 20(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a7, 16(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t3, 12(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t4, 8(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t5, 4(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t6, 0(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: lui a0, %hi(e)
; CHECK-RV32-NEXT: lw a0, %lo(e)(a0)
; CHECK-RV32-NEXT: lui a1, %hi(f)
; CHECK-RV32-NEXT: lw a1, %lo(f)(a1)
; CHECK-RV32-NEXT: call __addsf3
; CHECK-RV32-NEXT: lui a1, %hi(d)
; CHECK-RV32-NEXT: sw a0, %lo(d)(a1)
; CHECK-RV32-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t0, 56(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t1, 52(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t2, 48(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a0, 44(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a1, 40(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a2, 36(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a3, 32(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a4, 28(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a5, 24(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a6, 20(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a7, 16(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t3, 12(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t4, 8(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t5, 4(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t6, 0(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: addi sp, sp, 64
; CHECK-RV32-NEXT: mret
;
; CHECK-RV32IF-LABEL: foo_float:
; CHECK-RV32IF: # %bb.0:
; CHECK-RV32IF-NEXT: addi sp, sp, -16
; CHECK-RV32IF-NEXT: sw a0, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa4, 8(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa5, 4(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: lui a0, %hi(e)
; CHECK-RV32IF-NEXT: flw fa5, %lo(e)(a0)
; CHECK-RV32IF-NEXT: lui a0, %hi(f)
; CHECK-RV32IF-NEXT: flw fa4, %lo(f)(a0)
; CHECK-RV32IF-NEXT: fadd.s fa5, fa5, fa4
; CHECK-RV32IF-NEXT: lui a0, %hi(d)
; CHECK-RV32IF-NEXT: fsw fa5, %lo(d)(a0)
; CHECK-RV32IF-NEXT: lw a0, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa4, 8(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa5, 4(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: addi sp, sp, 16
; CHECK-RV32IF-NEXT: mret
;
; CHECK-RV32IFD-LABEL: foo_float:
; CHECK-RV32IFD: # %bb.0:
; CHECK-RV32IFD-NEXT: addi sp, sp, -32
; CHECK-RV32IFD-NEXT: sw a0, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa4, 16(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa5, 8(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: lui a0, %hi(e)
; CHECK-RV32IFD-NEXT: flw fa5, %lo(e)(a0)
; CHECK-RV32IFD-NEXT: lui a0, %hi(f)
; CHECK-RV32IFD-NEXT: flw fa4, %lo(f)(a0)
; CHECK-RV32IFD-NEXT: fadd.s fa5, fa5, fa4
; CHECK-RV32IFD-NEXT: lui a0, %hi(d)
; CHECK-RV32IFD-NEXT: fsw fa5, %lo(d)(a0)
; CHECK-RV32IFD-NEXT: lw a0, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa4, 16(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa5, 8(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: addi sp, sp, 32
; CHECK-RV32IFD-NEXT: mret
%1 = load float, ptr @e
%2 = load float, ptr @f
%add = fadd float %1, %2
store float %add, ptr @d
ret void
}
;
; Additionally check frame pointer and return address are properly saved.
;
define void @foo_fp_float() nounwind #1 {
; CHECK-RV32-LABEL: foo_fp_float:
; CHECK-RV32: # %bb.0:
; CHECK-RV32-NEXT: addi sp, sp, -80
; CHECK-RV32-NEXT: sw ra, 76(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t0, 72(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t1, 68(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t2, 64(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw s0, 60(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a0, 56(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a1, 52(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a2, 48(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a3, 44(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a4, 40(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a5, 36(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a6, 32(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a7, 28(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t3, 24(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t4, 20(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t5, 16(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t6, 12(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: addi s0, sp, 80
; CHECK-RV32-NEXT: lui a0, %hi(e)
; CHECK-RV32-NEXT: lw a0, %lo(e)(a0)
; CHECK-RV32-NEXT: lui a1, %hi(f)
; CHECK-RV32-NEXT: lw a1, %lo(f)(a1)
; CHECK-RV32-NEXT: call __addsf3
; CHECK-RV32-NEXT: lui a1, %hi(d)
; CHECK-RV32-NEXT: sw a0, %lo(d)(a1)
; CHECK-RV32-NEXT: lw ra, 76(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t0, 72(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t1, 68(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t2, 64(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw s0, 60(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a0, 56(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a1, 52(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a2, 48(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a3, 44(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a4, 40(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a5, 36(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a6, 32(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a7, 28(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t3, 24(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t4, 20(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t5, 16(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t6, 12(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: addi sp, sp, 80
; CHECK-RV32-NEXT: mret
;
; CHECK-RV32IF-LABEL: foo_fp_float:
; CHECK-RV32IF: # %bb.0:
; CHECK-RV32IF-NEXT: addi sp, sp, -32
; CHECK-RV32IF-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a0, 20(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa4, 16(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa5, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: addi s0, sp, 32
; CHECK-RV32IF-NEXT: lui a0, %hi(e)
; CHECK-RV32IF-NEXT: flw fa5, %lo(e)(a0)
; CHECK-RV32IF-NEXT: lui a0, %hi(f)
; CHECK-RV32IF-NEXT: flw fa4, %lo(f)(a0)
; CHECK-RV32IF-NEXT: fadd.s fa5, fa5, fa4
; CHECK-RV32IF-NEXT: lui a0, %hi(d)
; CHECK-RV32IF-NEXT: fsw fa5, %lo(d)(a0)
; CHECK-RV32IF-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a0, 20(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa4, 16(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa5, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: addi sp, sp, 32
; CHECK-RV32IF-NEXT: mret
;
; CHECK-RV32IFD-LABEL: foo_fp_float:
; CHECK-RV32IFD: # %bb.0:
; CHECK-RV32IFD-NEXT: addi sp, sp, -32
; CHECK-RV32IFD-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw a0, 20(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa4, 8(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa5, 0(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: addi s0, sp, 32
; CHECK-RV32IFD-NEXT: lui a0, %hi(e)
; CHECK-RV32IFD-NEXT: flw fa5, %lo(e)(a0)
; CHECK-RV32IFD-NEXT: lui a0, %hi(f)
; CHECK-RV32IFD-NEXT: flw fa4, %lo(f)(a0)
; CHECK-RV32IFD-NEXT: fadd.s fa5, fa5, fa4
; CHECK-RV32IFD-NEXT: lui a0, %hi(d)
; CHECK-RV32IFD-NEXT: fsw fa5, %lo(d)(a0)
; CHECK-RV32IFD-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw a0, 20(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa4, 8(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa5, 0(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: addi sp, sp, 32
; CHECK-RV32IFD-NEXT: mret
%1 = load float, ptr @e
%2 = load float, ptr @f
%add = fadd float %1, %2
store float %add, ptr @d
ret void
}
@h = external global double
@i = external global double
@g = external global double
define void @foo_double() nounwind #0 {
; CHECK-RV32-LABEL: foo_double:
; CHECK-RV32: # %bb.0:
; CHECK-RV32-NEXT: addi sp, sp, -64
; CHECK-RV32-NEXT: sw ra, 60(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t0, 56(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t1, 52(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t2, 48(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a0, 44(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a1, 40(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a2, 36(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a3, 32(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a4, 28(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a5, 24(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a6, 20(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a7, 16(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t3, 12(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t4, 8(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t5, 4(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t6, 0(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: lui a1, %hi(h)
; CHECK-RV32-NEXT: lw a0, %lo(h)(a1)
; CHECK-RV32-NEXT: lw a1, %lo(h+4)(a1)
; CHECK-RV32-NEXT: lui a3, %hi(i)
; CHECK-RV32-NEXT: lw a2, %lo(i)(a3)
; CHECK-RV32-NEXT: lw a3, %lo(i+4)(a3)
; CHECK-RV32-NEXT: call __adddf3
; CHECK-RV32-NEXT: lui a2, %hi(g)
; CHECK-RV32-NEXT: sw a1, %lo(g+4)(a2)
; CHECK-RV32-NEXT: sw a0, %lo(g)(a2)
; CHECK-RV32-NEXT: lw ra, 60(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t0, 56(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t1, 52(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t2, 48(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a0, 44(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a1, 40(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a2, 36(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a3, 32(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a4, 28(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a5, 24(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a6, 20(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a7, 16(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t3, 12(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t4, 8(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t5, 4(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t6, 0(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: addi sp, sp, 64
; CHECK-RV32-NEXT: mret
;
; CHECK-RV32IF-LABEL: foo_double:
; CHECK-RV32IF: # %bb.0:
; CHECK-RV32IF-NEXT: addi sp, sp, -144
; CHECK-RV32IF-NEXT: sw ra, 140(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t0, 136(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t1, 132(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t2, 128(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a0, 124(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a1, 120(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a2, 116(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a3, 112(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a4, 108(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a5, 104(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a6, 100(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a7, 96(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t3, 92(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t4, 88(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t5, 84(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t6, 80(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft0, 76(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft1, 72(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft2, 68(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft3, 64(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft4, 60(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft5, 56(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft6, 52(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft7, 48(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa0, 44(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa1, 40(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa2, 36(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa3, 32(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa4, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa5, 24(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa6, 20(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa7, 16(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft8, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft9, 8(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft10, 4(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft11, 0(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: lui a1, %hi(h)
; CHECK-RV32IF-NEXT: lw a0, %lo(h)(a1)
; CHECK-RV32IF-NEXT: lw a1, %lo(h+4)(a1)
; CHECK-RV32IF-NEXT: lui a3, %hi(i)
; CHECK-RV32IF-NEXT: lw a2, %lo(i)(a3)
; CHECK-RV32IF-NEXT: lw a3, %lo(i+4)(a3)
; CHECK-RV32IF-NEXT: call __adddf3
; CHECK-RV32IF-NEXT: lui a2, %hi(g)
; CHECK-RV32IF-NEXT: sw a1, %lo(g+4)(a2)
; CHECK-RV32IF-NEXT: sw a0, %lo(g)(a2)
; CHECK-RV32IF-NEXT: lw ra, 140(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t0, 136(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t1, 132(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t2, 128(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a0, 124(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a1, 120(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a2, 116(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a3, 112(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a4, 108(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a5, 104(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a6, 100(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a7, 96(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t3, 92(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t4, 88(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t5, 84(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t6, 80(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft0, 76(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft1, 72(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft2, 68(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft3, 64(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft4, 60(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft5, 56(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft6, 52(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft7, 48(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa0, 44(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa1, 40(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa2, 36(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa3, 32(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa4, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa5, 24(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa6, 20(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa7, 16(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft8, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft9, 8(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft10, 4(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft11, 0(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: addi sp, sp, 144
; CHECK-RV32IF-NEXT: mret
;
; CHECK-RV32IFD-LABEL: foo_double:
; CHECK-RV32IFD: # %bb.0:
; CHECK-RV32IFD-NEXT: addi sp, sp, -32
; CHECK-RV32IFD-NEXT: sw a0, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa4, 16(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa5, 8(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: lui a0, %hi(h)
; CHECK-RV32IFD-NEXT: fld fa5, %lo(h)(a0)
; CHECK-RV32IFD-NEXT: lui a0, %hi(i)
; CHECK-RV32IFD-NEXT: fld fa4, %lo(i)(a0)
; CHECK-RV32IFD-NEXT: fadd.d fa5, fa5, fa4
; CHECK-RV32IFD-NEXT: lui a0, %hi(g)
; CHECK-RV32IFD-NEXT: fsd fa5, %lo(g)(a0)
; CHECK-RV32IFD-NEXT: lw a0, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa4, 16(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa5, 8(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: addi sp, sp, 32
; CHECK-RV32IFD-NEXT: mret
%1 = load double, ptr @h
%2 = load double, ptr @i
%add = fadd double %1, %2
store double %add, ptr @g
ret void
}
;
; Additionally check frame pointer and return address are properly saved.
;
define void @foo_fp_double() nounwind #1 {
; CHECK-RV32-LABEL: foo_fp_double:
; CHECK-RV32: # %bb.0:
; CHECK-RV32-NEXT: addi sp, sp, -80
; CHECK-RV32-NEXT: sw ra, 76(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t0, 72(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t1, 68(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t2, 64(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw s0, 60(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a0, 56(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a1, 52(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a2, 48(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a3, 44(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a4, 40(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a5, 36(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a6, 32(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw a7, 28(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t3, 24(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t4, 20(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t5, 16(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: sw t6, 12(sp) # 4-byte Folded Spill
; CHECK-RV32-NEXT: addi s0, sp, 80
; CHECK-RV32-NEXT: lui a1, %hi(h)
; CHECK-RV32-NEXT: lw a0, %lo(h)(a1)
; CHECK-RV32-NEXT: lw a1, %lo(h+4)(a1)
; CHECK-RV32-NEXT: lui a3, %hi(i)
; CHECK-RV32-NEXT: lw a2, %lo(i)(a3)
; CHECK-RV32-NEXT: lw a3, %lo(i+4)(a3)
; CHECK-RV32-NEXT: call __adddf3
; CHECK-RV32-NEXT: lui a2, %hi(g)
; CHECK-RV32-NEXT: sw a1, %lo(g+4)(a2)
; CHECK-RV32-NEXT: sw a0, %lo(g)(a2)
; CHECK-RV32-NEXT: lw ra, 76(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t0, 72(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t1, 68(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t2, 64(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw s0, 60(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a0, 56(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a1, 52(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a2, 48(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a3, 44(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a4, 40(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a5, 36(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a6, 32(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw a7, 28(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t3, 24(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t4, 20(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t5, 16(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: lw t6, 12(sp) # 4-byte Folded Reload
; CHECK-RV32-NEXT: addi sp, sp, 80
; CHECK-RV32-NEXT: mret
;
; CHECK-RV32IF-LABEL: foo_fp_double:
; CHECK-RV32IF: # %bb.0:
; CHECK-RV32IF-NEXT: addi sp, sp, -160
; CHECK-RV32IF-NEXT: sw ra, 156(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t0, 152(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t1, 148(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t2, 144(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw s0, 140(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a0, 136(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a1, 132(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a2, 128(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a3, 124(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a4, 120(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a5, 116(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a6, 112(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw a7, 108(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t3, 104(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t4, 100(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t5, 96(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: sw t6, 92(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft0, 88(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft1, 84(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft2, 80(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft3, 76(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft4, 72(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft5, 68(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft6, 64(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft7, 60(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa0, 56(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa1, 52(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa2, 48(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa3, 44(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa4, 40(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa5, 36(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa6, 32(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw fa7, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft8, 24(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft9, 20(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft10, 16(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: fsw ft11, 12(sp) # 4-byte Folded Spill
; CHECK-RV32IF-NEXT: addi s0, sp, 160
; CHECK-RV32IF-NEXT: lui a1, %hi(h)
; CHECK-RV32IF-NEXT: lw a0, %lo(h)(a1)
; CHECK-RV32IF-NEXT: lw a1, %lo(h+4)(a1)
; CHECK-RV32IF-NEXT: lui a3, %hi(i)
; CHECK-RV32IF-NEXT: lw a2, %lo(i)(a3)
; CHECK-RV32IF-NEXT: lw a3, %lo(i+4)(a3)
; CHECK-RV32IF-NEXT: call __adddf3
; CHECK-RV32IF-NEXT: lui a2, %hi(g)
; CHECK-RV32IF-NEXT: sw a1, %lo(g+4)(a2)
; CHECK-RV32IF-NEXT: sw a0, %lo(g)(a2)
; CHECK-RV32IF-NEXT: lw ra, 156(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t0, 152(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t1, 148(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t2, 144(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw s0, 140(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a0, 136(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a1, 132(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a2, 128(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a3, 124(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a4, 120(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a5, 116(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a6, 112(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw a7, 108(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t3, 104(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t4, 100(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t5, 96(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: lw t6, 92(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft0, 88(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft1, 84(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft2, 80(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft3, 76(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft4, 72(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft5, 68(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft6, 64(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft7, 60(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa0, 56(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa1, 52(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa2, 48(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa3, 44(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa4, 40(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa5, 36(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa6, 32(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw fa7, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft8, 24(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft9, 20(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft10, 16(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: flw ft11, 12(sp) # 4-byte Folded Reload
; CHECK-RV32IF-NEXT: addi sp, sp, 160
; CHECK-RV32IF-NEXT: mret
;
; CHECK-RV32IFD-LABEL: foo_fp_double:
; CHECK-RV32IFD: # %bb.0:
; CHECK-RV32IFD-NEXT: addi sp, sp, -32
; CHECK-RV32IFD-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: sw a0, 20(sp) # 4-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa4, 8(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: fsd fa5, 0(sp) # 8-byte Folded Spill
; CHECK-RV32IFD-NEXT: addi s0, sp, 32
; CHECK-RV32IFD-NEXT: lui a0, %hi(h)
; CHECK-RV32IFD-NEXT: fld fa5, %lo(h)(a0)
; CHECK-RV32IFD-NEXT: lui a0, %hi(i)
; CHECK-RV32IFD-NEXT: fld fa4, %lo(i)(a0)
; CHECK-RV32IFD-NEXT: fadd.d fa5, fa5, fa4
; CHECK-RV32IFD-NEXT: lui a0, %hi(g)
; CHECK-RV32IFD-NEXT: fsd fa5, %lo(g)(a0)
; CHECK-RV32IFD-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: lw a0, 20(sp) # 4-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa4, 8(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: fld fa5, 0(sp) # 8-byte Folded Reload
; CHECK-RV32IFD-NEXT: addi sp, sp, 32
; CHECK-RV32IFD-NEXT: mret
%1 = load double, ptr @h
%2 = load double, ptr @i
%add = fadd double %1, %2
store double %add, ptr @g
ret void
}
attributes #0 = { "interrupt"="machine" }
attributes #1 = { "interrupt"="machine" "frame-pointer"="all" }