1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32IFD %s
; Basic correctness checks for calling convention lowering for RV32D. This can
; be somewhat error-prone for soft-float RV32D due to the fact that f64 is legal
; but i64 is not, and there is no instruction to move values directly between
; the GPRs and 64-bit FPRs.
define double @callee_double_inreg(double %a, double %b) nounwind {
; RV32IFD-LABEL: callee_double_inreg:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: addi sp, sp, -16
; RV32IFD-NEXT: sw a2, 8(sp)
; RV32IFD-NEXT: sw a3, 12(sp)
; RV32IFD-NEXT: fld ft0, 8(sp)
; RV32IFD-NEXT: sw a0, 8(sp)
; RV32IFD-NEXT: sw a1, 12(sp)
; RV32IFD-NEXT: fld ft1, 8(sp)
; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
; RV32IFD-NEXT: fsd ft0, 8(sp)
; RV32IFD-NEXT: lw a0, 8(sp)
; RV32IFD-NEXT: lw a1, 12(sp)
; RV32IFD-NEXT: addi sp, sp, 16
; RV32IFD-NEXT: ret
%1 = fadd double %a, %b
ret double %1
}
; TODO: code quality for loading and then passing f64 constants is poor.
define double @caller_double_inreg() nounwind {
; RV32IFD-LABEL: caller_double_inreg:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: addi sp, sp, -16
; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IFD-NEXT: lui a0, 262236
; RV32IFD-NEXT: addi a1, a0, 655
; RV32IFD-NEXT: lui a0, 377487
; RV32IFD-NEXT: addi a0, a0, 1475
; RV32IFD-NEXT: lui a2, 262364
; RV32IFD-NEXT: addi a3, a2, 655
; RV32IFD-NEXT: mv a2, a0
; RV32IFD-NEXT: call callee_double_inreg@plt
; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IFD-NEXT: addi sp, sp, 16
; RV32IFD-NEXT: ret
%1 = call double @callee_double_inreg(double 2.720000e+00, double 3.720000e+00)
ret double %1
}
define double @callee_double_split_reg_stack(i32 %a, i64 %b, i64 %c, double %d, double %e) nounwind {
; RV32IFD-LABEL: callee_double_split_reg_stack:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: addi sp, sp, -16
; RV32IFD-NEXT: lw a0, 16(sp)
; RV32IFD-NEXT: sw a7, 8(sp)
; RV32IFD-NEXT: sw a0, 12(sp)
; RV32IFD-NEXT: fld ft0, 8(sp)
; RV32IFD-NEXT: sw a5, 8(sp)
; RV32IFD-NEXT: sw a6, 12(sp)
; RV32IFD-NEXT: fld ft1, 8(sp)
; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
; RV32IFD-NEXT: fsd ft0, 8(sp)
; RV32IFD-NEXT: lw a0, 8(sp)
; RV32IFD-NEXT: lw a1, 12(sp)
; RV32IFD-NEXT: addi sp, sp, 16
; RV32IFD-NEXT: ret
%1 = fadd double %d, %e
ret double %1
}
define double @caller_double_split_reg_stack() nounwind {
; RV32IFD-LABEL: caller_double_split_reg_stack:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: addi sp, sp, -16
; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32IFD-NEXT: lui a0, 262510
; RV32IFD-NEXT: addi a2, a0, 327
; RV32IFD-NEXT: lui a0, 262446
; RV32IFD-NEXT: addi a6, a0, 327
; RV32IFD-NEXT: lui a0, 713032
; RV32IFD-NEXT: addi a5, a0, -1311
; RV32IFD-NEXT: li a0, 1
; RV32IFD-NEXT: li a1, 2
; RV32IFD-NEXT: li a3, 3
; RV32IFD-NEXT: sw a2, 0(sp)
; RV32IFD-NEXT: li a2, 0
; RV32IFD-NEXT: li a4, 0
; RV32IFD-NEXT: mv a7, a5
; RV32IFD-NEXT: call callee_double_split_reg_stack@plt
; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32IFD-NEXT: addi sp, sp, 16
; RV32IFD-NEXT: ret
%1 = call double @callee_double_split_reg_stack(i32 1, i64 2, i64 3, double 4.72, double 5.72)
ret double %1
}
define double @callee_double_stack(i64 %a, i64 %b, i64 %c, i64 %d, double %e, double %f) nounwind {
; RV32IFD-LABEL: callee_double_stack:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: addi sp, sp, -16
; RV32IFD-NEXT: fld ft0, 24(sp)
; RV32IFD-NEXT: fld ft1, 16(sp)
; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
; RV32IFD-NEXT: fsd ft0, 8(sp)
; RV32IFD-NEXT: lw a0, 8(sp)
; RV32IFD-NEXT: lw a1, 12(sp)
; RV32IFD-NEXT: addi sp, sp, 16
; RV32IFD-NEXT: ret
%1 = fadd double %e, %f
ret double %1
}
define double @caller_double_stack() nounwind {
; RV32IFD-LABEL: caller_double_stack:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: addi sp, sp, -32
; RV32IFD-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
; RV32IFD-NEXT: lui a0, 262510
; RV32IFD-NEXT: addi a0, a0, 327
; RV32IFD-NEXT: sw a0, 4(sp)
; RV32IFD-NEXT: lui a0, 713032
; RV32IFD-NEXT: addi a1, a0, -1311
; RV32IFD-NEXT: sw a1, 0(sp)
; RV32IFD-NEXT: lui a0, 262574
; RV32IFD-NEXT: addi a0, a0, 327
; RV32IFD-NEXT: sw a0, 12(sp)
; RV32IFD-NEXT: li a0, 1
; RV32IFD-NEXT: li a2, 2
; RV32IFD-NEXT: li a4, 3
; RV32IFD-NEXT: li a6, 4
; RV32IFD-NEXT: sw a1, 8(sp)
; RV32IFD-NEXT: li a1, 0
; RV32IFD-NEXT: li a3, 0
; RV32IFD-NEXT: li a5, 0
; RV32IFD-NEXT: li a7, 0
; RV32IFD-NEXT: call callee_double_stack@plt
; RV32IFD-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
; RV32IFD-NEXT: addi sp, sp, 32
; RV32IFD-NEXT: ret
%1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72)
ret double %1
}
|