1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV64I-FPELIM %s
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -frame-pointer=all < %s \
5 ; RUN: | FileCheck -check-prefix=RV64I-WITHFP %s
7 ; As well as calling convention details, we check that ra and fp are
8 ; consistently stored to fp-8 and fp-16.
10 ; Any tests that would have identical output for some combination of the lp64*
11 ; ABIs belong in calling-conv-*-common.ll. This file contains tests that will
12 ; have different output across those ABIs. i.e. where some arguments would be
13 ; passed according to the floating point ABI.
15 ; TODO: softened float values can be passed anyext.
17 define i64 @callee_float_in_regs(i64 %a, float %b) nounwind {
18 ; RV64I-FPELIM-LABEL: callee_float_in_regs:
19 ; RV64I-FPELIM: # %bb.0:
20 ; RV64I-FPELIM-NEXT: addi sp, sp, -16
21 ; RV64I-FPELIM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
22 ; RV64I-FPELIM-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
23 ; RV64I-FPELIM-NEXT: mv s0, a0
24 ; RV64I-FPELIM-NEXT: mv a0, a1
25 ; RV64I-FPELIM-NEXT: call __fixsfdi@plt
26 ; RV64I-FPELIM-NEXT: add a0, s0, a0
27 ; RV64I-FPELIM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
28 ; RV64I-FPELIM-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
29 ; RV64I-FPELIM-NEXT: addi sp, sp, 16
30 ; RV64I-FPELIM-NEXT: ret
32 ; RV64I-WITHFP-LABEL: callee_float_in_regs:
33 ; RV64I-WITHFP: # %bb.0:
34 ; RV64I-WITHFP-NEXT: addi sp, sp, -32
35 ; RV64I-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
36 ; RV64I-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
37 ; RV64I-WITHFP-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
38 ; RV64I-WITHFP-NEXT: addi s0, sp, 32
39 ; RV64I-WITHFP-NEXT: mv s1, a0
40 ; RV64I-WITHFP-NEXT: mv a0, a1
41 ; RV64I-WITHFP-NEXT: call __fixsfdi@plt
42 ; RV64I-WITHFP-NEXT: add a0, s1, a0
43 ; RV64I-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
44 ; RV64I-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
45 ; RV64I-WITHFP-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
46 ; RV64I-WITHFP-NEXT: addi sp, sp, 32
47 ; RV64I-WITHFP-NEXT: ret
48 %b_fptosi = fptosi float %b to i64
49 %1 = add i64 %a, %b_fptosi
53 define i64 @caller_float_in_regs() nounwind {
54 ; RV64I-FPELIM-LABEL: caller_float_in_regs:
55 ; RV64I-FPELIM: # %bb.0:
56 ; RV64I-FPELIM-NEXT: addi sp, sp, -16
57 ; RV64I-FPELIM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
58 ; RV64I-FPELIM-NEXT: li a0, 1
59 ; RV64I-FPELIM-NEXT: lui a1, 262144
60 ; RV64I-FPELIM-NEXT: call callee_float_in_regs@plt
61 ; RV64I-FPELIM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
62 ; RV64I-FPELIM-NEXT: addi sp, sp, 16
63 ; RV64I-FPELIM-NEXT: ret
65 ; RV64I-WITHFP-LABEL: caller_float_in_regs:
66 ; RV64I-WITHFP: # %bb.0:
67 ; RV64I-WITHFP-NEXT: addi sp, sp, -16
68 ; RV64I-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
69 ; RV64I-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
70 ; RV64I-WITHFP-NEXT: addi s0, sp, 16
71 ; RV64I-WITHFP-NEXT: li a0, 1
72 ; RV64I-WITHFP-NEXT: lui a1, 262144
73 ; RV64I-WITHFP-NEXT: call callee_float_in_regs@plt
74 ; RV64I-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
75 ; RV64I-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
76 ; RV64I-WITHFP-NEXT: addi sp, sp, 16
77 ; RV64I-WITHFP-NEXT: ret
78 %1 = call i64 @callee_float_in_regs(i64 1, float 2.0)
82 define i64 @callee_float_on_stack(i128 %a, i128 %b, i128 %c, i128 %d, float %e) nounwind {
83 ; RV64I-FPELIM-LABEL: callee_float_on_stack:
84 ; RV64I-FPELIM: # %bb.0:
85 ; RV64I-FPELIM-NEXT: lw a0, 0(sp)
86 ; RV64I-FPELIM-NEXT: ret
88 ; RV64I-WITHFP-LABEL: callee_float_on_stack:
89 ; RV64I-WITHFP: # %bb.0:
90 ; RV64I-WITHFP-NEXT: addi sp, sp, -16
91 ; RV64I-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
92 ; RV64I-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
93 ; RV64I-WITHFP-NEXT: addi s0, sp, 16
94 ; RV64I-WITHFP-NEXT: lw a0, 0(s0)
95 ; RV64I-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
96 ; RV64I-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
97 ; RV64I-WITHFP-NEXT: addi sp, sp, 16
98 ; RV64I-WITHFP-NEXT: ret
99 %1 = trunc i128 %d to i64
100 %2 = bitcast float %e to i32
101 %3 = sext i32 %2 to i64
106 define i64 @caller_float_on_stack() nounwind {
107 ; RV64I-FPELIM-LABEL: caller_float_on_stack:
108 ; RV64I-FPELIM: # %bb.0:
109 ; RV64I-FPELIM-NEXT: addi sp, sp, -16
110 ; RV64I-FPELIM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
111 ; RV64I-FPELIM-NEXT: lui a1, 264704
112 ; RV64I-FPELIM-NEXT: li a0, 1
113 ; RV64I-FPELIM-NEXT: li a2, 2
114 ; RV64I-FPELIM-NEXT: li a4, 3
115 ; RV64I-FPELIM-NEXT: li a6, 4
116 ; RV64I-FPELIM-NEXT: sd a1, 0(sp)
117 ; RV64I-FPELIM-NEXT: li a1, 0
118 ; RV64I-FPELIM-NEXT: li a3, 0
119 ; RV64I-FPELIM-NEXT: li a5, 0
120 ; RV64I-FPELIM-NEXT: li a7, 0
121 ; RV64I-FPELIM-NEXT: call callee_float_on_stack@plt
122 ; RV64I-FPELIM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
123 ; RV64I-FPELIM-NEXT: addi sp, sp, 16
124 ; RV64I-FPELIM-NEXT: ret
126 ; RV64I-WITHFP-LABEL: caller_float_on_stack:
127 ; RV64I-WITHFP: # %bb.0:
128 ; RV64I-WITHFP-NEXT: addi sp, sp, -32
129 ; RV64I-WITHFP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
130 ; RV64I-WITHFP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
131 ; RV64I-WITHFP-NEXT: addi s0, sp, 32
132 ; RV64I-WITHFP-NEXT: lui a1, 264704
133 ; RV64I-WITHFP-NEXT: li a0, 1
134 ; RV64I-WITHFP-NEXT: li a2, 2
135 ; RV64I-WITHFP-NEXT: li a4, 3
136 ; RV64I-WITHFP-NEXT: li a6, 4
137 ; RV64I-WITHFP-NEXT: sd a1, 0(sp)
138 ; RV64I-WITHFP-NEXT: li a1, 0
139 ; RV64I-WITHFP-NEXT: li a3, 0
140 ; RV64I-WITHFP-NEXT: li a5, 0
141 ; RV64I-WITHFP-NEXT: li a7, 0
142 ; RV64I-WITHFP-NEXT: call callee_float_on_stack@plt
143 ; RV64I-WITHFP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
144 ; RV64I-WITHFP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
145 ; RV64I-WITHFP-NEXT: addi sp, sp, 32
146 ; RV64I-WITHFP-NEXT: ret
147 %1 = call i64 @callee_float_on_stack(i128 1, i128 2, i128 3, i128 4, float 5.0)
151 define float @callee_tiny_scalar_ret() nounwind {
152 ; RV64I-FPELIM-LABEL: callee_tiny_scalar_ret:
153 ; RV64I-FPELIM: # %bb.0:
154 ; RV64I-FPELIM-NEXT: lui a0, 260096
155 ; RV64I-FPELIM-NEXT: ret
157 ; RV64I-WITHFP-LABEL: callee_tiny_scalar_ret:
158 ; RV64I-WITHFP: # %bb.0:
159 ; RV64I-WITHFP-NEXT: addi sp, sp, -16
160 ; RV64I-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
161 ; RV64I-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
162 ; RV64I-WITHFP-NEXT: addi s0, sp, 16
163 ; RV64I-WITHFP-NEXT: lui a0, 260096
164 ; RV64I-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
165 ; RV64I-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
166 ; RV64I-WITHFP-NEXT: addi sp, sp, 16
167 ; RV64I-WITHFP-NEXT: ret
171 ; The sign extension of the float return is necessary, as softened floats are
174 define i64 @caller_tiny_scalar_ret() nounwind {
175 ; RV64I-FPELIM-LABEL: caller_tiny_scalar_ret:
176 ; RV64I-FPELIM: # %bb.0:
177 ; RV64I-FPELIM-NEXT: addi sp, sp, -16
178 ; RV64I-FPELIM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
179 ; RV64I-FPELIM-NEXT: call callee_tiny_scalar_ret@plt
180 ; RV64I-FPELIM-NEXT: sext.w a0, a0
181 ; RV64I-FPELIM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
182 ; RV64I-FPELIM-NEXT: addi sp, sp, 16
183 ; RV64I-FPELIM-NEXT: ret
185 ; RV64I-WITHFP-LABEL: caller_tiny_scalar_ret:
186 ; RV64I-WITHFP: # %bb.0:
187 ; RV64I-WITHFP-NEXT: addi sp, sp, -16
188 ; RV64I-WITHFP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
189 ; RV64I-WITHFP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
190 ; RV64I-WITHFP-NEXT: addi s0, sp, 16
191 ; RV64I-WITHFP-NEXT: call callee_tiny_scalar_ret@plt
192 ; RV64I-WITHFP-NEXT: sext.w a0, a0
193 ; RV64I-WITHFP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
194 ; RV64I-WITHFP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
195 ; RV64I-WITHFP-NEXT: addi sp, sp, 16
196 ; RV64I-WITHFP-NEXT: ret
197 %1 = call float @callee_tiny_scalar_ret()
198 %2 = bitcast float %1 to i32
199 %3 = sext i32 %2 to i64