1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32IF %s
4 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV32IF %s
7 declare float @llvm.sqrt.f32(float)
9 define float @sqrt_f32(float %a) nounwind {
10 ; RV32IF-LABEL: sqrt_f32:
12 ; RV32IF-NEXT: fmv.w.x ft0, a0
13 ; RV32IF-NEXT: fsqrt.s ft0, ft0
14 ; RV32IF-NEXT: fmv.x.w a0, ft0
16 %1 = call float @llvm.sqrt.f32(float %a)
20 declare float @llvm.powi.f32(float, i32)
22 define float @powi_f32(float %a, i32 %b) nounwind {
23 ; RV32IF-LABEL: powi_f32:
25 ; RV32IF-NEXT: addi sp, sp, -16
26 ; RV32IF-NEXT: sw ra, 12(sp)
27 ; RV32IF-NEXT: call __powisf2
28 ; RV32IF-NEXT: lw ra, 12(sp)
29 ; RV32IF-NEXT: addi sp, sp, 16
31 %1 = call float @llvm.powi.f32(float %a, i32 %b)
35 declare float @llvm.sin.f32(float)
37 define float @sin_f32(float %a) nounwind {
38 ; RV32IF-LABEL: sin_f32:
40 ; RV32IF-NEXT: addi sp, sp, -16
41 ; RV32IF-NEXT: sw ra, 12(sp)
42 ; RV32IF-NEXT: call sinf
43 ; RV32IF-NEXT: lw ra, 12(sp)
44 ; RV32IF-NEXT: addi sp, sp, 16
46 %1 = call float @llvm.sin.f32(float %a)
50 declare float @llvm.cos.f32(float)
52 define float @cos_f32(float %a) nounwind {
53 ; RV32IF-LABEL: cos_f32:
55 ; RV32IF-NEXT: addi sp, sp, -16
56 ; RV32IF-NEXT: sw ra, 12(sp)
57 ; RV32IF-NEXT: call cosf
58 ; RV32IF-NEXT: lw ra, 12(sp)
59 ; RV32IF-NEXT: addi sp, sp, 16
61 %1 = call float @llvm.cos.f32(float %a)
65 ; The sin+cos combination results in an FSINCOS SelectionDAG node.
66 define float @sincos_f32(float %a) nounwind {
67 ; RV32IF-LABEL: sincos_f32:
69 ; RV32IF-NEXT: addi sp, sp, -16
70 ; RV32IF-NEXT: sw ra, 12(sp)
71 ; RV32IF-NEXT: sw s1, 8(sp)
72 ; RV32IF-NEXT: sw s2, 4(sp)
73 ; RV32IF-NEXT: mv s1, a0
74 ; RV32IF-NEXT: call sinf
75 ; RV32IF-NEXT: mv s2, a0
76 ; RV32IF-NEXT: mv a0, s1
77 ; RV32IF-NEXT: call cosf
78 ; RV32IF-NEXT: fmv.w.x ft0, a0
79 ; RV32IF-NEXT: fmv.w.x ft1, s2
80 ; RV32IF-NEXT: fadd.s ft0, ft1, ft0
81 ; RV32IF-NEXT: fmv.x.w a0, ft0
82 ; RV32IF-NEXT: lw s2, 4(sp)
83 ; RV32IF-NEXT: lw s1, 8(sp)
84 ; RV32IF-NEXT: lw ra, 12(sp)
85 ; RV32IF-NEXT: addi sp, sp, 16
87 %1 = call float @llvm.sin.f32(float %a)
88 %2 = call float @llvm.cos.f32(float %a)
89 %3 = fadd float %1, %2
93 declare float @llvm.pow.f32(float, float)
95 define float @pow_f32(float %a, float %b) nounwind {
96 ; RV32IF-LABEL: pow_f32:
98 ; RV32IF-NEXT: addi sp, sp, -16
99 ; RV32IF-NEXT: sw ra, 12(sp)
100 ; RV32IF-NEXT: call powf
101 ; RV32IF-NEXT: lw ra, 12(sp)
102 ; RV32IF-NEXT: addi sp, sp, 16
104 %1 = call float @llvm.pow.f32(float %a, float %b)
108 declare float @llvm.exp.f32(float)
110 define float @exp_f32(float %a) nounwind {
111 ; RV32IF-LABEL: exp_f32:
113 ; RV32IF-NEXT: addi sp, sp, -16
114 ; RV32IF-NEXT: sw ra, 12(sp)
115 ; RV32IF-NEXT: call expf
116 ; RV32IF-NEXT: lw ra, 12(sp)
117 ; RV32IF-NEXT: addi sp, sp, 16
119 %1 = call float @llvm.exp.f32(float %a)
123 declare float @llvm.exp2.f32(float)
125 define float @exp2_f32(float %a) nounwind {
126 ; RV32IF-LABEL: exp2_f32:
128 ; RV32IF-NEXT: addi sp, sp, -16
129 ; RV32IF-NEXT: sw ra, 12(sp)
130 ; RV32IF-NEXT: call exp2f
131 ; RV32IF-NEXT: lw ra, 12(sp)
132 ; RV32IF-NEXT: addi sp, sp, 16
134 %1 = call float @llvm.exp2.f32(float %a)
138 declare float @llvm.log.f32(float)
140 define float @log_f32(float %a) nounwind {
141 ; RV32IF-LABEL: log_f32:
143 ; RV32IF-NEXT: addi sp, sp, -16
144 ; RV32IF-NEXT: sw ra, 12(sp)
145 ; RV32IF-NEXT: call logf
146 ; RV32IF-NEXT: lw ra, 12(sp)
147 ; RV32IF-NEXT: addi sp, sp, 16
149 %1 = call float @llvm.log.f32(float %a)
153 declare float @llvm.log10.f32(float)
155 define float @log10_f32(float %a) nounwind {
156 ; RV32IF-LABEL: log10_f32:
158 ; RV32IF-NEXT: addi sp, sp, -16
159 ; RV32IF-NEXT: sw ra, 12(sp)
160 ; RV32IF-NEXT: call log10f
161 ; RV32IF-NEXT: lw ra, 12(sp)
162 ; RV32IF-NEXT: addi sp, sp, 16
164 %1 = call float @llvm.log10.f32(float %a)
168 declare float @llvm.log2.f32(float)
170 define float @log2_f32(float %a) nounwind {
171 ; RV32IF-LABEL: log2_f32:
173 ; RV32IF-NEXT: addi sp, sp, -16
174 ; RV32IF-NEXT: sw ra, 12(sp)
175 ; RV32IF-NEXT: call log2f
176 ; RV32IF-NEXT: lw ra, 12(sp)
177 ; RV32IF-NEXT: addi sp, sp, 16
179 %1 = call float @llvm.log2.f32(float %a)
183 declare float @llvm.fma.f32(float, float, float)
185 define float @fma_f32(float %a, float %b, float %c) nounwind {
186 ; RV32IF-LABEL: fma_f32:
188 ; RV32IF-NEXT: fmv.w.x ft0, a2
189 ; RV32IF-NEXT: fmv.w.x ft1, a1
190 ; RV32IF-NEXT: fmv.w.x ft2, a0
191 ; RV32IF-NEXT: fmadd.s ft0, ft2, ft1, ft0
192 ; RV32IF-NEXT: fmv.x.w a0, ft0
194 %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
198 declare float @llvm.fmuladd.f32(float, float, float)
200 define float @fmuladd_f32(float %a, float %b, float %c) nounwind {
201 ; Use of fmadd depends on TargetLowering::isFMAFasterthanFMulAndFAdd
202 ; RV32IF-LABEL: fmuladd_f32:
204 ; RV32IF-NEXT: fmv.w.x ft0, a1
205 ; RV32IF-NEXT: fmv.w.x ft1, a0
206 ; RV32IF-NEXT: fmul.s ft0, ft1, ft0
207 ; RV32IF-NEXT: fmv.w.x ft1, a2
208 ; RV32IF-NEXT: fadd.s ft0, ft0, ft1
209 ; RV32IF-NEXT: fmv.x.w a0, ft0
211 %1 = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
215 declare float @llvm.fabs.f32(float)
217 define float @fabs_f32(float %a) nounwind {
218 ; RV32IF-LABEL: fabs_f32:
220 ; RV32IF-NEXT: lui a1, 524288
221 ; RV32IF-NEXT: addi a1, a1, -1
222 ; RV32IF-NEXT: and a0, a0, a1
224 %1 = call float @llvm.fabs.f32(float %a)
228 declare float @llvm.minnum.f32(float, float)
230 define float @minnum_f32(float %a, float %b) nounwind {
231 ; RV32IF-LABEL: minnum_f32:
233 ; RV32IF-NEXT: fmv.w.x ft0, a1
234 ; RV32IF-NEXT: fmv.w.x ft1, a0
235 ; RV32IF-NEXT: fmin.s ft0, ft1, ft0
236 ; RV32IF-NEXT: fmv.x.w a0, ft0
238 %1 = call float @llvm.minnum.f32(float %a, float %b)
242 declare float @llvm.maxnum.f32(float, float)
244 define float @maxnum_f32(float %a, float %b) nounwind {
245 ; RV32IF-LABEL: maxnum_f32:
247 ; RV32IF-NEXT: fmv.w.x ft0, a1
248 ; RV32IF-NEXT: fmv.w.x ft1, a0
249 ; RV32IF-NEXT: fmax.s ft0, ft1, ft0
250 ; RV32IF-NEXT: fmv.x.w a0, ft0
252 %1 = call float @llvm.maxnum.f32(float %a, float %b)
256 ; TODO: FMINNAN and FMAXNAN aren't handled in
257 ; SelectionDAGLegalize::ExpandNode.
259 ; declare float @llvm.minimum.f32(float, float)
261 ; define float @fminimum_f32(float %a, float %b) nounwind {
262 ; %1 = call float @llvm.minimum.f32(float %a, float %b)
266 ; declare float @llvm.maximum.f32(float, float)
268 ; define float @fmaximum_f32(float %a, float %b) nounwind {
269 ; %1 = call float @llvm.maximum.f32(float %a, float %b)
273 declare float @llvm.copysign.f32(float, float)
275 define float @copysign_f32(float %a, float %b) nounwind {
276 ; RV32IF-LABEL: copysign_f32:
278 ; RV32IF-NEXT: fmv.w.x ft0, a1
279 ; RV32IF-NEXT: fmv.w.x ft1, a0
280 ; RV32IF-NEXT: fsgnj.s ft0, ft1, ft0
281 ; RV32IF-NEXT: fmv.x.w a0, ft0
283 %1 = call float @llvm.copysign.f32(float %a, float %b)
287 declare float @llvm.floor.f32(float)
289 define float @floor_f32(float %a) nounwind {
290 ; RV32IF-LABEL: floor_f32:
292 ; RV32IF-NEXT: addi sp, sp, -16
293 ; RV32IF-NEXT: sw ra, 12(sp)
294 ; RV32IF-NEXT: call floorf
295 ; RV32IF-NEXT: lw ra, 12(sp)
296 ; RV32IF-NEXT: addi sp, sp, 16
298 %1 = call float @llvm.floor.f32(float %a)
302 declare float @llvm.ceil.f32(float)
304 define float @ceil_f32(float %a) nounwind {
305 ; RV32IF-LABEL: ceil_f32:
307 ; RV32IF-NEXT: addi sp, sp, -16
308 ; RV32IF-NEXT: sw ra, 12(sp)
309 ; RV32IF-NEXT: call ceilf
310 ; RV32IF-NEXT: lw ra, 12(sp)
311 ; RV32IF-NEXT: addi sp, sp, 16
313 %1 = call float @llvm.ceil.f32(float %a)
317 declare float @llvm.trunc.f32(float)
319 define float @trunc_f32(float %a) nounwind {
320 ; RV32IF-LABEL: trunc_f32:
322 ; RV32IF-NEXT: addi sp, sp, -16
323 ; RV32IF-NEXT: sw ra, 12(sp)
324 ; RV32IF-NEXT: call truncf
325 ; RV32IF-NEXT: lw ra, 12(sp)
326 ; RV32IF-NEXT: addi sp, sp, 16
328 %1 = call float @llvm.trunc.f32(float %a)
332 declare float @llvm.rint.f32(float)
334 define float @rint_f32(float %a) nounwind {
335 ; RV32IF-LABEL: rint_f32:
337 ; RV32IF-NEXT: addi sp, sp, -16
338 ; RV32IF-NEXT: sw ra, 12(sp)
339 ; RV32IF-NEXT: call rintf
340 ; RV32IF-NEXT: lw ra, 12(sp)
341 ; RV32IF-NEXT: addi sp, sp, 16
343 %1 = call float @llvm.rint.f32(float %a)
347 declare float @llvm.nearbyint.f32(float)
349 define float @nearbyint_f32(float %a) nounwind {
350 ; RV32IF-LABEL: nearbyint_f32:
352 ; RV32IF-NEXT: addi sp, sp, -16
353 ; RV32IF-NEXT: sw ra, 12(sp)
354 ; RV32IF-NEXT: call nearbyintf
355 ; RV32IF-NEXT: lw ra, 12(sp)
356 ; RV32IF-NEXT: addi sp, sp, 16
358 %1 = call float @llvm.nearbyint.f32(float %a)
362 declare float @llvm.round.f32(float)
364 define float @round_f32(float %a) nounwind {
365 ; RV32IF-LABEL: round_f32:
367 ; RV32IF-NEXT: addi sp, sp, -16
368 ; RV32IF-NEXT: sw ra, 12(sp)
369 ; RV32IF-NEXT: call roundf
370 ; RV32IF-NEXT: lw ra, 12(sp)
371 ; RV32IF-NEXT: addi sp, sp, 16
373 %1 = call float @llvm.round.f32(float %a)