Use Align for TFL::TransientStackAlignment
[llvm-core.git] / test / CodeGen / RISCV / double-convert.ll
blobf7abdea68ca296ab0e79f1fba29aae9ec1fe74fb
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV32IFD %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck -check-prefix=RV64IFD %s
7 define float @fcvt_s_d(double %a) nounwind {
8 ; RV32IFD-LABEL: fcvt_s_d:
9 ; RV32IFD:       # %bb.0:
10 ; RV32IFD-NEXT:    addi sp, sp, -16
11 ; RV32IFD-NEXT:    sw a0, 8(sp)
12 ; RV32IFD-NEXT:    sw a1, 12(sp)
13 ; RV32IFD-NEXT:    fld ft0, 8(sp)
14 ; RV32IFD-NEXT:    fcvt.s.d ft0, ft0
15 ; RV32IFD-NEXT:    fmv.x.w a0, ft0
16 ; RV32IFD-NEXT:    addi sp, sp, 16
17 ; RV32IFD-NEXT:    ret
19 ; RV64IFD-LABEL: fcvt_s_d:
20 ; RV64IFD:       # %bb.0:
21 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
22 ; RV64IFD-NEXT:    fcvt.s.d ft0, ft0
23 ; RV64IFD-NEXT:    fmv.x.w a0, ft0
24 ; RV64IFD-NEXT:    ret
25   %1 = fptrunc double %a to float
26   ret float %1
29 define double @fcvt_d_s(float %a) nounwind {
30 ; RV32IFD-LABEL: fcvt_d_s:
31 ; RV32IFD:       # %bb.0:
32 ; RV32IFD-NEXT:    addi sp, sp, -16
33 ; RV32IFD-NEXT:    fmv.w.x ft0, a0
34 ; RV32IFD-NEXT:    fcvt.d.s ft0, ft0
35 ; RV32IFD-NEXT:    fsd ft0, 8(sp)
36 ; RV32IFD-NEXT:    lw a0, 8(sp)
37 ; RV32IFD-NEXT:    lw a1, 12(sp)
38 ; RV32IFD-NEXT:    addi sp, sp, 16
39 ; RV32IFD-NEXT:    ret
41 ; RV64IFD-LABEL: fcvt_d_s:
42 ; RV64IFD:       # %bb.0:
43 ; RV64IFD-NEXT:    fmv.w.x ft0, a0
44 ; RV64IFD-NEXT:    fcvt.d.s ft0, ft0
45 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
46 ; RV64IFD-NEXT:    ret
47   %1 = fpext float %a to double
48   ret double %1
51 ; For RV64D, fcvt.l.d is semantically equivalent to fcvt.w.d in this case
52 ; because fptosi will produce poison if the result doesn't fit into an i32.
53 define i32 @fcvt_w_d(double %a) nounwind {
54 ; RV32IFD-LABEL: fcvt_w_d:
55 ; RV32IFD:       # %bb.0:
56 ; RV32IFD-NEXT:    addi sp, sp, -16
57 ; RV32IFD-NEXT:    sw a0, 8(sp)
58 ; RV32IFD-NEXT:    sw a1, 12(sp)
59 ; RV32IFD-NEXT:    fld ft0, 8(sp)
60 ; RV32IFD-NEXT:    fcvt.w.d a0, ft0, rtz
61 ; RV32IFD-NEXT:    addi sp, sp, 16
62 ; RV32IFD-NEXT:    ret
64 ; RV64IFD-LABEL: fcvt_w_d:
65 ; RV64IFD:       # %bb.0:
66 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
67 ; RV64IFD-NEXT:    fcvt.l.d a0, ft0, rtz
68 ; RV64IFD-NEXT:    ret
69   %1 = fptosi double %a to i32
70   ret i32 %1
73 ; For RV64D, fcvt.lu.d is semantically equivalent to fcvt.wu.d in this case
74 ; because fptosi will produce poison if the result doesn't fit into an i32.
75 define i32 @fcvt_wu_d(double %a) nounwind {
76 ; RV32IFD-LABEL: fcvt_wu_d:
77 ; RV32IFD:       # %bb.0:
78 ; RV32IFD-NEXT:    addi sp, sp, -16
79 ; RV32IFD-NEXT:    sw a0, 8(sp)
80 ; RV32IFD-NEXT:    sw a1, 12(sp)
81 ; RV32IFD-NEXT:    fld ft0, 8(sp)
82 ; RV32IFD-NEXT:    fcvt.wu.d a0, ft0, rtz
83 ; RV32IFD-NEXT:    addi sp, sp, 16
84 ; RV32IFD-NEXT:    ret
86 ; RV64IFD-LABEL: fcvt_wu_d:
87 ; RV64IFD:       # %bb.0:
88 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
89 ; RV64IFD-NEXT:    fcvt.lu.d a0, ft0, rtz
90 ; RV64IFD-NEXT:    ret
91   %1 = fptoui double %a to i32
92   ret i32 %1
95 define double @fcvt_d_w(i32 %a) nounwind {
96 ; RV32IFD-LABEL: fcvt_d_w:
97 ; RV32IFD:       # %bb.0:
98 ; RV32IFD-NEXT:    addi sp, sp, -16
99 ; RV32IFD-NEXT:    fcvt.d.w ft0, a0
100 ; RV32IFD-NEXT:    fsd ft0, 8(sp)
101 ; RV32IFD-NEXT:    lw a0, 8(sp)
102 ; RV32IFD-NEXT:    lw a1, 12(sp)
103 ; RV32IFD-NEXT:    addi sp, sp, 16
104 ; RV32IFD-NEXT:    ret
106 ; RV64IFD-LABEL: fcvt_d_w:
107 ; RV64IFD:       # %bb.0:
108 ; RV64IFD-NEXT:    fcvt.d.w ft0, a0
109 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
110 ; RV64IFD-NEXT:    ret
111   %1 = sitofp i32 %a to double
112   ret double %1
115 define double @fcvt_d_wu(i32 %a) nounwind {
116 ; RV32IFD-LABEL: fcvt_d_wu:
117 ; RV32IFD:       # %bb.0:
118 ; RV32IFD-NEXT:    addi sp, sp, -16
119 ; RV32IFD-NEXT:    fcvt.d.wu ft0, a0
120 ; RV32IFD-NEXT:    fsd ft0, 8(sp)
121 ; RV32IFD-NEXT:    lw a0, 8(sp)
122 ; RV32IFD-NEXT:    lw a1, 12(sp)
123 ; RV32IFD-NEXT:    addi sp, sp, 16
124 ; RV32IFD-NEXT:    ret
126 ; RV64IFD-LABEL: fcvt_d_wu:
127 ; RV64IFD:       # %bb.0:
128 ; RV64IFD-NEXT:    fcvt.d.wu ft0, a0
129 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
130 ; RV64IFD-NEXT:    ret
131   %1 = uitofp i32 %a to double
132   ret double %1
135 define i64 @fcvt_l_d(double %a) nounwind {
136 ; RV32IFD-LABEL: fcvt_l_d:
137 ; RV32IFD:       # %bb.0:
138 ; RV32IFD-NEXT:    addi sp, sp, -16
139 ; RV32IFD-NEXT:    sw ra, 12(sp)
140 ; RV32IFD-NEXT:    call __fixdfdi
141 ; RV32IFD-NEXT:    lw ra, 12(sp)
142 ; RV32IFD-NEXT:    addi sp, sp, 16
143 ; RV32IFD-NEXT:    ret
145 ; RV64IFD-LABEL: fcvt_l_d:
146 ; RV64IFD:       # %bb.0:
147 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
148 ; RV64IFD-NEXT:    fcvt.l.d a0, ft0, rtz
149 ; RV64IFD-NEXT:    ret
150   %1 = fptosi double %a to i64
151   ret i64 %1
154 define i64 @fcvt_lu_d(double %a) nounwind {
155 ; RV32IFD-LABEL: fcvt_lu_d:
156 ; RV32IFD:       # %bb.0:
157 ; RV32IFD-NEXT:    addi sp, sp, -16
158 ; RV32IFD-NEXT:    sw ra, 12(sp)
159 ; RV32IFD-NEXT:    call __fixunsdfdi
160 ; RV32IFD-NEXT:    lw ra, 12(sp)
161 ; RV32IFD-NEXT:    addi sp, sp, 16
162 ; RV32IFD-NEXT:    ret
164 ; RV64IFD-LABEL: fcvt_lu_d:
165 ; RV64IFD:       # %bb.0:
166 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
167 ; RV64IFD-NEXT:    fcvt.lu.d a0, ft0, rtz
168 ; RV64IFD-NEXT:    ret
169   %1 = fptoui double %a to i64
170   ret i64 %1
173 define i64 @fmv_x_d(double %a, double %b) nounwind {
174 ; RV32IFD-LABEL: fmv_x_d:
175 ; RV32IFD:       # %bb.0:
176 ; RV32IFD-NEXT:    addi sp, sp, -16
177 ; RV32IFD-NEXT:    sw a2, 0(sp)
178 ; RV32IFD-NEXT:    sw a3, 4(sp)
179 ; RV32IFD-NEXT:    fld ft0, 0(sp)
180 ; RV32IFD-NEXT:    sw a0, 0(sp)
181 ; RV32IFD-NEXT:    sw a1, 4(sp)
182 ; RV32IFD-NEXT:    fld ft1, 0(sp)
183 ; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
184 ; RV32IFD-NEXT:    fsd ft0, 8(sp)
185 ; RV32IFD-NEXT:    lw a0, 8(sp)
186 ; RV32IFD-NEXT:    lw a1, 12(sp)
187 ; RV32IFD-NEXT:    addi sp, sp, 16
188 ; RV32IFD-NEXT:    ret
190 ; RV64IFD-LABEL: fmv_x_d:
191 ; RV64IFD:       # %bb.0:
192 ; RV64IFD-NEXT:    fmv.d.x ft0, a1
193 ; RV64IFD-NEXT:    fmv.d.x ft1, a0
194 ; RV64IFD-NEXT:    fadd.d ft0, ft1, ft0
195 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
196 ; RV64IFD-NEXT:    ret
197   %1 = fadd double %a, %b
198   %2 = bitcast double %1 to i64
199   ret i64 %2
202 define double @fcvt_d_l(i64 %a) nounwind {
203 ; RV32IFD-LABEL: fcvt_d_l:
204 ; RV32IFD:       # %bb.0:
205 ; RV32IFD-NEXT:    addi sp, sp, -16
206 ; RV32IFD-NEXT:    sw ra, 12(sp)
207 ; RV32IFD-NEXT:    call __floatdidf
208 ; RV32IFD-NEXT:    lw ra, 12(sp)
209 ; RV32IFD-NEXT:    addi sp, sp, 16
210 ; RV32IFD-NEXT:    ret
212 ; RV64IFD-LABEL: fcvt_d_l:
213 ; RV64IFD:       # %bb.0:
214 ; RV64IFD-NEXT:    fcvt.d.l ft0, a0
215 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
216 ; RV64IFD-NEXT:    ret
217   %1 = sitofp i64 %a to double
218   ret double %1
221 define double @fcvt_d_lu(i64 %a) nounwind {
222 ; RV32IFD-LABEL: fcvt_d_lu:
223 ; RV32IFD:       # %bb.0:
224 ; RV32IFD-NEXT:    addi sp, sp, -16
225 ; RV32IFD-NEXT:    sw ra, 12(sp)
226 ; RV32IFD-NEXT:    call __floatundidf
227 ; RV32IFD-NEXT:    lw ra, 12(sp)
228 ; RV32IFD-NEXT:    addi sp, sp, 16
229 ; RV32IFD-NEXT:    ret
231 ; RV64IFD-LABEL: fcvt_d_lu:
232 ; RV64IFD:       # %bb.0:
233 ; RV64IFD-NEXT:    fcvt.d.lu ft0, a0
234 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
235 ; RV64IFD-NEXT:    ret
236   %1 = uitofp i64 %a to double
237   ret double %1
240 define double @fmv_d_x(i64 %a, i64 %b) nounwind {
241 ; Ensure fmv.w.x is generated even for a soft double calling convention
242 ; RV32IFD-LABEL: fmv_d_x:
243 ; RV32IFD:       # %bb.0:
244 ; RV32IFD-NEXT:    addi sp, sp, -32
245 ; RV32IFD-NEXT:    sw a3, 20(sp)
246 ; RV32IFD-NEXT:    sw a2, 16(sp)
247 ; RV32IFD-NEXT:    sw a1, 28(sp)
248 ; RV32IFD-NEXT:    sw a0, 24(sp)
249 ; RV32IFD-NEXT:    fld ft0, 16(sp)
250 ; RV32IFD-NEXT:    fld ft1, 24(sp)
251 ; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
252 ; RV32IFD-NEXT:    fsd ft0, 8(sp)
253 ; RV32IFD-NEXT:    lw a0, 8(sp)
254 ; RV32IFD-NEXT:    lw a1, 12(sp)
255 ; RV32IFD-NEXT:    addi sp, sp, 32
256 ; RV32IFD-NEXT:    ret
258 ; RV64IFD-LABEL: fmv_d_x:
259 ; RV64IFD:       # %bb.0:
260 ; RV64IFD-NEXT:    fmv.d.x ft0, a0
261 ; RV64IFD-NEXT:    fmv.d.x ft1, a1
262 ; RV64IFD-NEXT:    fadd.d ft0, ft0, ft1
263 ; RV64IFD-NEXT:    fmv.x.d a0, ft0
264 ; RV64IFD-NEXT:    ret
265   %1 = bitcast i64 %a to double
266   %2 = bitcast i64 %b to double
267   %3 = fadd double %1, %2
268   ret double %3