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: -target-abi=ilp32f | FileCheck -check-prefix=CHECKIF %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5 ; RUN: -target-abi=lp64f | FileCheck -check-prefix=CHECKIF %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \
7 ; RUN: -target-abi=ilp32 | FileCheck -check-prefix=CHECKIZFINX %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \
9 ; RUN: -target-abi=lp64 | FileCheck -check-prefix=CHECKIZFINX %s
10 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
11 ; RUN: | FileCheck -check-prefix=RV32I %s
12 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
13 ; RUN: | FileCheck -check-prefix=RV64I %s
15 ; These tests are each targeted at a particular RISC-V FPU instruction.
16 ; Compares and conversions can be found in float-fcmp.ll and float-convert.ll
17 ; respectively. Some other float-*.ll files in this folder exercise LLVM IR
18 ; instructions that don't directly match a RISC-V instruction.
20 define float @fadd_s(float %a, float %b) nounwind {
21 ; CHECKIF-LABEL: fadd_s:
23 ; CHECKIF-NEXT: fadd.s fa0, fa0, fa1
26 ; CHECKIZFINX-LABEL: fadd_s:
27 ; CHECKIZFINX: # %bb.0:
28 ; CHECKIZFINX-NEXT: fadd.s a0, a0, a1
29 ; CHECKIZFINX-NEXT: ret
31 ; RV32I-LABEL: fadd_s:
33 ; RV32I-NEXT: addi sp, sp, -16
34 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
35 ; RV32I-NEXT: call __addsf3
36 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
37 ; RV32I-NEXT: addi sp, sp, 16
40 ; RV64I-LABEL: fadd_s:
42 ; RV64I-NEXT: addi sp, sp, -16
43 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
44 ; RV64I-NEXT: call __addsf3
45 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
46 ; RV64I-NEXT: addi sp, sp, 16
48 %1 = fadd float %a, %b
52 define float @fsub_s(float %a, float %b) nounwind {
53 ; CHECKIF-LABEL: fsub_s:
55 ; CHECKIF-NEXT: fsub.s fa0, fa0, fa1
58 ; CHECKIZFINX-LABEL: fsub_s:
59 ; CHECKIZFINX: # %bb.0:
60 ; CHECKIZFINX-NEXT: fsub.s a0, a0, a1
61 ; CHECKIZFINX-NEXT: ret
63 ; RV32I-LABEL: fsub_s:
65 ; RV32I-NEXT: addi sp, sp, -16
66 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
67 ; RV32I-NEXT: call __subsf3
68 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
69 ; RV32I-NEXT: addi sp, sp, 16
72 ; RV64I-LABEL: fsub_s:
74 ; RV64I-NEXT: addi sp, sp, -16
75 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
76 ; RV64I-NEXT: call __subsf3
77 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
78 ; RV64I-NEXT: addi sp, sp, 16
80 %1 = fsub float %a, %b
84 define float @fmul_s(float %a, float %b) nounwind {
85 ; CHECKIF-LABEL: fmul_s:
87 ; CHECKIF-NEXT: fmul.s fa0, fa0, fa1
90 ; CHECKIZFINX-LABEL: fmul_s:
91 ; CHECKIZFINX: # %bb.0:
92 ; CHECKIZFINX-NEXT: fmul.s a0, a0, a1
93 ; CHECKIZFINX-NEXT: ret
95 ; RV32I-LABEL: fmul_s:
97 ; RV32I-NEXT: addi sp, sp, -16
98 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
99 ; RV32I-NEXT: call __mulsf3
100 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
101 ; RV32I-NEXT: addi sp, sp, 16
104 ; RV64I-LABEL: fmul_s:
106 ; RV64I-NEXT: addi sp, sp, -16
107 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
108 ; RV64I-NEXT: call __mulsf3
109 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
110 ; RV64I-NEXT: addi sp, sp, 16
112 %1 = fmul float %a, %b
116 define float @fdiv_s(float %a, float %b) nounwind {
117 ; CHECKIF-LABEL: fdiv_s:
119 ; CHECKIF-NEXT: fdiv.s fa0, fa0, fa1
122 ; CHECKIZFINX-LABEL: fdiv_s:
123 ; CHECKIZFINX: # %bb.0:
124 ; CHECKIZFINX-NEXT: fdiv.s a0, a0, a1
125 ; CHECKIZFINX-NEXT: ret
127 ; RV32I-LABEL: fdiv_s:
129 ; RV32I-NEXT: addi sp, sp, -16
130 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
131 ; RV32I-NEXT: call __divsf3
132 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
133 ; RV32I-NEXT: addi sp, sp, 16
136 ; RV64I-LABEL: fdiv_s:
138 ; RV64I-NEXT: addi sp, sp, -16
139 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
140 ; RV64I-NEXT: call __divsf3
141 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
142 ; RV64I-NEXT: addi sp, sp, 16
144 %1 = fdiv float %a, %b
148 declare float @llvm.sqrt.f32(float)
150 define float @fsqrt_s(float %a) nounwind {
151 ; CHECKIF-LABEL: fsqrt_s:
153 ; CHECKIF-NEXT: fsqrt.s fa0, fa0
156 ; CHECKIZFINX-LABEL: fsqrt_s:
157 ; CHECKIZFINX: # %bb.0:
158 ; CHECKIZFINX-NEXT: fsqrt.s a0, a0
159 ; CHECKIZFINX-NEXT: ret
161 ; RV32I-LABEL: fsqrt_s:
163 ; RV32I-NEXT: addi sp, sp, -16
164 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
165 ; RV32I-NEXT: call sqrtf
166 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
167 ; RV32I-NEXT: addi sp, sp, 16
170 ; RV64I-LABEL: fsqrt_s:
172 ; RV64I-NEXT: addi sp, sp, -16
173 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
174 ; RV64I-NEXT: call sqrtf
175 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
176 ; RV64I-NEXT: addi sp, sp, 16
178 %1 = call float @llvm.sqrt.f32(float %a)
182 declare float @llvm.copysign.f32(float, float)
184 define float @fsgnj_s(float %a, float %b) nounwind {
185 ; CHECKIF-LABEL: fsgnj_s:
187 ; CHECKIF-NEXT: fsgnj.s fa0, fa0, fa1
190 ; CHECKIZFINX-LABEL: fsgnj_s:
191 ; CHECKIZFINX: # %bb.0:
192 ; CHECKIZFINX-NEXT: fsgnj.s a0, a0, a1
193 ; CHECKIZFINX-NEXT: ret
195 ; RV32I-LABEL: fsgnj_s:
197 ; RV32I-NEXT: lui a2, 524288
198 ; RV32I-NEXT: and a1, a1, a2
199 ; RV32I-NEXT: slli a0, a0, 1
200 ; RV32I-NEXT: srli a0, a0, 1
201 ; RV32I-NEXT: or a0, a0, a1
204 ; RV64I-LABEL: fsgnj_s:
206 ; RV64I-NEXT: lui a2, 524288
207 ; RV64I-NEXT: and a1, a1, a2
208 ; RV64I-NEXT: slli a0, a0, 33
209 ; RV64I-NEXT: srli a0, a0, 33
210 ; RV64I-NEXT: or a0, a0, a1
212 %1 = call float @llvm.copysign.f32(float %a, float %b)
216 define i32 @fneg_s(float %a, float %b) nounwind {
217 ; CHECKIF-LABEL: fneg_s:
219 ; CHECKIF-NEXT: fadd.s fa5, fa0, fa0
220 ; CHECKIF-NEXT: fneg.s fa4, fa5
221 ; CHECKIF-NEXT: feq.s a0, fa5, fa4
224 ; CHECKIZFINX-LABEL: fneg_s:
225 ; CHECKIZFINX: # %bb.0:
226 ; CHECKIZFINX-NEXT: fadd.s a0, a0, a0
227 ; CHECKIZFINX-NEXT: fneg.s a1, a0
228 ; CHECKIZFINX-NEXT: feq.s a0, a0, a1
229 ; CHECKIZFINX-NEXT: ret
231 ; RV32I-LABEL: fneg_s:
233 ; RV32I-NEXT: addi sp, sp, -16
234 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
235 ; RV32I-NEXT: mv a1, a0
236 ; RV32I-NEXT: call __addsf3
237 ; RV32I-NEXT: lui a1, 524288
238 ; RV32I-NEXT: xor a1, a0, a1
239 ; RV32I-NEXT: call __eqsf2
240 ; RV32I-NEXT: seqz a0, a0
241 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
242 ; RV32I-NEXT: addi sp, sp, 16
245 ; RV64I-LABEL: fneg_s:
247 ; RV64I-NEXT: addi sp, sp, -16
248 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
249 ; RV64I-NEXT: mv a1, a0
250 ; RV64I-NEXT: call __addsf3
251 ; RV64I-NEXT: lui a1, 524288
252 ; RV64I-NEXT: xor a1, a0, a1
253 ; RV64I-NEXT: call __eqsf2
254 ; RV64I-NEXT: seqz a0, a0
255 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
256 ; RV64I-NEXT: addi sp, sp, 16
258 %1 = fadd float %a, %a
260 %3 = fcmp oeq float %1, %2
261 %4 = zext i1 %3 to i32
265 define float @fsgnjn_s(float %a, float %b) nounwind {
266 ; CHECKIF-LABEL: fsgnjn_s:
268 ; CHECKIF-NEXT: fadd.s fa5, fa0, fa1
269 ; CHECKIF-NEXT: fsgnjn.s fa0, fa0, fa5
272 ; CHECKIZFINX-LABEL: fsgnjn_s:
273 ; CHECKIZFINX: # %bb.0:
274 ; CHECKIZFINX-NEXT: fadd.s a1, a0, a1
275 ; CHECKIZFINX-NEXT: fsgnjn.s a0, a0, a1
276 ; CHECKIZFINX-NEXT: ret
278 ; RV32I-LABEL: fsgnjn_s:
280 ; RV32I-NEXT: addi sp, sp, -16
281 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
282 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
283 ; RV32I-NEXT: mv s0, a0
284 ; RV32I-NEXT: call __addsf3
285 ; RV32I-NEXT: not a0, a0
286 ; RV32I-NEXT: lui a1, 524288
287 ; RV32I-NEXT: and a0, a0, a1
288 ; RV32I-NEXT: slli s0, s0, 1
289 ; RV32I-NEXT: srli s0, s0, 1
290 ; RV32I-NEXT: or a0, s0, a0
291 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
292 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
293 ; RV32I-NEXT: addi sp, sp, 16
296 ; RV64I-LABEL: fsgnjn_s:
298 ; RV64I-NEXT: addi sp, sp, -16
299 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
300 ; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
301 ; RV64I-NEXT: mv s0, a0
302 ; RV64I-NEXT: call __addsf3
303 ; RV64I-NEXT: not a0, a0
304 ; RV64I-NEXT: lui a1, 524288
305 ; RV64I-NEXT: and a0, a0, a1
306 ; RV64I-NEXT: slli s0, s0, 33
307 ; RV64I-NEXT: srli s0, s0, 33
308 ; RV64I-NEXT: or a0, s0, a0
309 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
310 ; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
311 ; RV64I-NEXT: addi sp, sp, 16
313 %1 = fadd float %a, %b
315 %3 = call float @llvm.copysign.f32(float %a, float %2)
319 declare float @llvm.fabs.f32(float)
321 define float @fabs_s(float %a, float %b) nounwind {
322 ; CHECKIF-LABEL: fabs_s:
324 ; CHECKIF-NEXT: fadd.s fa5, fa0, fa1
325 ; CHECKIF-NEXT: fabs.s fa4, fa5
326 ; CHECKIF-NEXT: fadd.s fa0, fa4, fa5
329 ; CHECKIZFINX-LABEL: fabs_s:
330 ; CHECKIZFINX: # %bb.0:
331 ; CHECKIZFINX-NEXT: fadd.s a0, a0, a1
332 ; CHECKIZFINX-NEXT: fabs.s a1, a0
333 ; CHECKIZFINX-NEXT: fadd.s a0, a1, a0
334 ; CHECKIZFINX-NEXT: ret
336 ; RV32I-LABEL: fabs_s:
338 ; RV32I-NEXT: addi sp, sp, -16
339 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
340 ; RV32I-NEXT: call __addsf3
341 ; RV32I-NEXT: mv a1, a0
342 ; RV32I-NEXT: slli a0, a0, 1
343 ; RV32I-NEXT: srli a0, a0, 1
344 ; RV32I-NEXT: call __addsf3
345 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
346 ; RV32I-NEXT: addi sp, sp, 16
349 ; RV64I-LABEL: fabs_s:
351 ; RV64I-NEXT: addi sp, sp, -16
352 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
353 ; RV64I-NEXT: call __addsf3
354 ; RV64I-NEXT: mv a1, a0
355 ; RV64I-NEXT: slli a0, a0, 33
356 ; RV64I-NEXT: srli a0, a0, 33
357 ; RV64I-NEXT: call __addsf3
358 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
359 ; RV64I-NEXT: addi sp, sp, 16
361 %1 = fadd float %a, %b
362 %2 = call float @llvm.fabs.f32(float %1)
363 %3 = fadd float %2, %1
367 declare float @llvm.minnum.f32(float, float)
369 define float @fmin_s(float %a, float %b) nounwind {
370 ; CHECKIF-LABEL: fmin_s:
372 ; CHECKIF-NEXT: fmin.s fa0, fa0, fa1
375 ; CHECKIZFINX-LABEL: fmin_s:
376 ; CHECKIZFINX: # %bb.0:
377 ; CHECKIZFINX-NEXT: fmin.s a0, a0, a1
378 ; CHECKIZFINX-NEXT: ret
380 ; RV32I-LABEL: fmin_s:
382 ; RV32I-NEXT: addi sp, sp, -16
383 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
384 ; RV32I-NEXT: call fminf
385 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
386 ; RV32I-NEXT: addi sp, sp, 16
389 ; RV64I-LABEL: fmin_s:
391 ; RV64I-NEXT: addi sp, sp, -16
392 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
393 ; RV64I-NEXT: call fminf
394 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
395 ; RV64I-NEXT: addi sp, sp, 16
397 %1 = call float @llvm.minnum.f32(float %a, float %b)
401 declare float @llvm.maxnum.f32(float, float)
403 define float @fmax_s(float %a, float %b) nounwind {
404 ; CHECKIF-LABEL: fmax_s:
406 ; CHECKIF-NEXT: fmax.s fa0, fa0, fa1
409 ; CHECKIZFINX-LABEL: fmax_s:
410 ; CHECKIZFINX: # %bb.0:
411 ; CHECKIZFINX-NEXT: fmax.s a0, a0, a1
412 ; CHECKIZFINX-NEXT: ret
414 ; RV32I-LABEL: fmax_s:
416 ; RV32I-NEXT: addi sp, sp, -16
417 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
418 ; RV32I-NEXT: call fmaxf
419 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
420 ; RV32I-NEXT: addi sp, sp, 16
423 ; RV64I-LABEL: fmax_s:
425 ; RV64I-NEXT: addi sp, sp, -16
426 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
427 ; RV64I-NEXT: call fmaxf
428 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
429 ; RV64I-NEXT: addi sp, sp, 16
431 %1 = call float @llvm.maxnum.f32(float %a, float %b)
435 declare float @llvm.fma.f32(float, float, float)
437 define float @fmadd_s(float %a, float %b, float %c) nounwind {
438 ; CHECKIF-LABEL: fmadd_s:
440 ; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2
443 ; CHECKIZFINX-LABEL: fmadd_s:
444 ; CHECKIZFINX: # %bb.0:
445 ; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2
446 ; CHECKIZFINX-NEXT: ret
448 ; RV32I-LABEL: fmadd_s:
450 ; RV32I-NEXT: addi sp, sp, -16
451 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
452 ; RV32I-NEXT: call fmaf
453 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
454 ; RV32I-NEXT: addi sp, sp, 16
457 ; RV64I-LABEL: fmadd_s:
459 ; RV64I-NEXT: addi sp, sp, -16
460 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
461 ; RV64I-NEXT: call fmaf
462 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
463 ; RV64I-NEXT: addi sp, sp, 16
465 %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
469 define float @fmsub_s(float %a, float %b, float %c) nounwind {
470 ; CHECKIF-LABEL: fmsub_s:
472 ; CHECKIF-NEXT: fmv.w.x fa5, zero
473 ; CHECKIF-NEXT: fadd.s fa5, fa2, fa5
474 ; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, fa5
477 ; CHECKIZFINX-LABEL: fmsub_s:
478 ; CHECKIZFINX: # %bb.0:
479 ; CHECKIZFINX-NEXT: fadd.s a2, a2, zero
480 ; CHECKIZFINX-NEXT: fmsub.s a0, a0, a1, a2
481 ; CHECKIZFINX-NEXT: ret
483 ; RV32I-LABEL: fmsub_s:
485 ; RV32I-NEXT: addi sp, sp, -16
486 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
487 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
488 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
489 ; RV32I-NEXT: mv s0, a1
490 ; RV32I-NEXT: mv s1, a0
491 ; RV32I-NEXT: mv a0, a2
492 ; RV32I-NEXT: li a1, 0
493 ; RV32I-NEXT: call __addsf3
494 ; RV32I-NEXT: lui a2, 524288
495 ; RV32I-NEXT: xor a2, a0, a2
496 ; RV32I-NEXT: mv a0, s1
497 ; RV32I-NEXT: mv a1, s0
498 ; RV32I-NEXT: call fmaf
499 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
500 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
501 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
502 ; RV32I-NEXT: addi sp, sp, 16
505 ; RV64I-LABEL: fmsub_s:
507 ; RV64I-NEXT: addi sp, sp, -32
508 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
509 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
510 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
511 ; RV64I-NEXT: mv s0, a1
512 ; RV64I-NEXT: mv s1, a0
513 ; RV64I-NEXT: mv a0, a2
514 ; RV64I-NEXT: li a1, 0
515 ; RV64I-NEXT: call __addsf3
516 ; RV64I-NEXT: lui a2, 524288
517 ; RV64I-NEXT: xor a2, a0, a2
518 ; RV64I-NEXT: mv a0, s1
519 ; RV64I-NEXT: mv a1, s0
520 ; RV64I-NEXT: call fmaf
521 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
522 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
523 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
524 ; RV64I-NEXT: addi sp, sp, 32
526 %c_ = fadd float 0.0, %c ; avoid negation using xor
527 %negc = fsub float -0.0, %c_
528 %1 = call float @llvm.fma.f32(float %a, float %b, float %negc)
532 define float @fnmadd_s(float %a, float %b, float %c) nounwind {
533 ; CHECKIF-LABEL: fnmadd_s:
535 ; CHECKIF-NEXT: fmv.w.x fa5, zero
536 ; CHECKIF-NEXT: fadd.s fa4, fa0, fa5
537 ; CHECKIF-NEXT: fadd.s fa5, fa2, fa5
538 ; CHECKIF-NEXT: fnmadd.s fa0, fa4, fa1, fa5
541 ; CHECKIZFINX-LABEL: fnmadd_s:
542 ; CHECKIZFINX: # %bb.0:
543 ; CHECKIZFINX-NEXT: fadd.s a0, a0, zero
544 ; CHECKIZFINX-NEXT: fadd.s a2, a2, zero
545 ; CHECKIZFINX-NEXT: fnmadd.s a0, a0, a1, a2
546 ; CHECKIZFINX-NEXT: ret
548 ; RV32I-LABEL: fnmadd_s:
550 ; RV32I-NEXT: addi sp, sp, -16
551 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
552 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
553 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
554 ; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
555 ; RV32I-NEXT: mv s0, a2
556 ; RV32I-NEXT: mv s1, a1
557 ; RV32I-NEXT: li a1, 0
558 ; RV32I-NEXT: call __addsf3
559 ; RV32I-NEXT: mv s2, a0
560 ; RV32I-NEXT: mv a0, s0
561 ; RV32I-NEXT: li a1, 0
562 ; RV32I-NEXT: call __addsf3
563 ; RV32I-NEXT: lui a2, 524288
564 ; RV32I-NEXT: xor a1, s2, a2
565 ; RV32I-NEXT: xor a2, a0, a2
566 ; RV32I-NEXT: mv a0, a1
567 ; RV32I-NEXT: mv a1, s1
568 ; RV32I-NEXT: call fmaf
569 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
570 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
571 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
572 ; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
573 ; RV32I-NEXT: addi sp, sp, 16
576 ; RV64I-LABEL: fnmadd_s:
578 ; RV64I-NEXT: addi sp, sp, -32
579 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
580 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
581 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
582 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
583 ; RV64I-NEXT: mv s0, a2
584 ; RV64I-NEXT: mv s1, a1
585 ; RV64I-NEXT: li a1, 0
586 ; RV64I-NEXT: call __addsf3
587 ; RV64I-NEXT: mv s2, a0
588 ; RV64I-NEXT: mv a0, s0
589 ; RV64I-NEXT: li a1, 0
590 ; RV64I-NEXT: call __addsf3
591 ; RV64I-NEXT: lui a2, 524288
592 ; RV64I-NEXT: xor a1, s2, a2
593 ; RV64I-NEXT: xor a2, a0, a2
594 ; RV64I-NEXT: mv a0, a1
595 ; RV64I-NEXT: mv a1, s1
596 ; RV64I-NEXT: call fmaf
597 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
598 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
599 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
600 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
601 ; RV64I-NEXT: addi sp, sp, 32
603 %a_ = fadd float 0.0, %a
604 %c_ = fadd float 0.0, %c
605 %nega = fsub float -0.0, %a_
606 %negc = fsub float -0.0, %c_
607 %1 = call float @llvm.fma.f32(float %nega, float %b, float %negc)
611 define float @fnmadd_s_2(float %a, float %b, float %c) nounwind {
612 ; CHECKIF-LABEL: fnmadd_s_2:
614 ; CHECKIF-NEXT: fmv.w.x fa5, zero
615 ; CHECKIF-NEXT: fadd.s fa4, fa1, fa5
616 ; CHECKIF-NEXT: fadd.s fa5, fa2, fa5
617 ; CHECKIF-NEXT: fnmadd.s fa0, fa4, fa0, fa5
620 ; CHECKIZFINX-LABEL: fnmadd_s_2:
621 ; CHECKIZFINX: # %bb.0:
622 ; CHECKIZFINX-NEXT: fadd.s a1, a1, zero
623 ; CHECKIZFINX-NEXT: fadd.s a2, a2, zero
624 ; CHECKIZFINX-NEXT: fnmadd.s a0, a1, a0, a2
625 ; CHECKIZFINX-NEXT: ret
627 ; RV32I-LABEL: fnmadd_s_2:
629 ; RV32I-NEXT: addi sp, sp, -16
630 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
631 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
632 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
633 ; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
634 ; RV32I-NEXT: mv s0, a2
635 ; RV32I-NEXT: mv s1, a0
636 ; RV32I-NEXT: mv a0, a1
637 ; RV32I-NEXT: li a1, 0
638 ; RV32I-NEXT: call __addsf3
639 ; RV32I-NEXT: mv s2, a0
640 ; RV32I-NEXT: mv a0, s0
641 ; RV32I-NEXT: li a1, 0
642 ; RV32I-NEXT: call __addsf3
643 ; RV32I-NEXT: lui a2, 524288
644 ; RV32I-NEXT: xor a1, s2, a2
645 ; RV32I-NEXT: xor a2, a0, a2
646 ; RV32I-NEXT: mv a0, s1
647 ; RV32I-NEXT: call fmaf
648 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
649 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
650 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
651 ; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
652 ; RV32I-NEXT: addi sp, sp, 16
655 ; RV64I-LABEL: fnmadd_s_2:
657 ; RV64I-NEXT: addi sp, sp, -32
658 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
659 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
660 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
661 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
662 ; RV64I-NEXT: mv s0, a2
663 ; RV64I-NEXT: mv s1, a0
664 ; RV64I-NEXT: mv a0, a1
665 ; RV64I-NEXT: li a1, 0
666 ; RV64I-NEXT: call __addsf3
667 ; RV64I-NEXT: mv s2, a0
668 ; RV64I-NEXT: mv a0, s0
669 ; RV64I-NEXT: li a1, 0
670 ; RV64I-NEXT: call __addsf3
671 ; RV64I-NEXT: lui a2, 524288
672 ; RV64I-NEXT: xor a1, s2, a2
673 ; RV64I-NEXT: xor a2, a0, a2
674 ; RV64I-NEXT: mv a0, s1
675 ; RV64I-NEXT: call fmaf
676 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
677 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
678 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
679 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
680 ; RV64I-NEXT: addi sp, sp, 32
682 %b_ = fadd float 0.0, %b
683 %c_ = fadd float 0.0, %c
684 %negb = fsub float -0.0, %b_
685 %negc = fsub float -0.0, %c_
686 %1 = call float @llvm.fma.f32(float %a, float %negb, float %negc)
690 define float @fnmadd_s_3(float %a, float %b, float %c) nounwind {
691 ; RV32IF-LABEL: fnmadd_s_3:
693 ; RV32IF-NEXT: fmadd.s ft0, fa0, fa1, fa2
694 ; RV32IF-NEXT: fneg.s fa0, ft0
697 ; RV64IF-LABEL: fnmadd_s_3:
699 ; RV64IF-NEXT: fmadd.s ft0, fa0, fa1, fa2
700 ; RV64IF-NEXT: fneg.s fa0, ft0
703 ; CHECKIF-LABEL: fnmadd_s_3:
705 ; CHECKIF-NEXT: fmadd.s fa5, fa0, fa1, fa2
706 ; CHECKIF-NEXT: fneg.s fa0, fa5
709 ; CHECKIZFINX-LABEL: fnmadd_s_3:
710 ; CHECKIZFINX: # %bb.0:
711 ; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2
712 ; CHECKIZFINX-NEXT: lui a1, 524288
713 ; CHECKIZFINX-NEXT: xor a0, a0, a1
714 ; CHECKIZFINX-NEXT: ret
716 ; RV32I-LABEL: fnmadd_s_3:
718 ; RV32I-NEXT: addi sp, sp, -16
719 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
720 ; RV32I-NEXT: call fmaf
721 ; RV32I-NEXT: lui a1, 524288
722 ; RV32I-NEXT: xor a0, a0, a1
723 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
724 ; RV32I-NEXT: addi sp, sp, 16
727 ; RV64I-LABEL: fnmadd_s_3:
729 ; RV64I-NEXT: addi sp, sp, -16
730 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
731 ; RV64I-NEXT: call fmaf
732 ; RV64I-NEXT: lui a1, 524288
733 ; RV64I-NEXT: xor a0, a0, a1
734 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
735 ; RV64I-NEXT: addi sp, sp, 16
737 %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
742 define float @fnmadd_nsz(float %a, float %b, float %c) nounwind {
743 ; RV32IF-LABEL: fnmadd_nsz:
745 ; RV32IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2
748 ; RV64IF-LABEL: fnmadd_nsz:
750 ; RV64IF-NEXT: fnmadd.s fa0, fa0, fa1, fa2
753 ; CHECKIF-LABEL: fnmadd_nsz:
755 ; CHECKIF-NEXT: fnmadd.s fa0, fa0, fa1, fa2
758 ; CHECKIZFINX-LABEL: fnmadd_nsz:
759 ; CHECKIZFINX: # %bb.0:
760 ; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2
761 ; CHECKIZFINX-NEXT: lui a1, 524288
762 ; CHECKIZFINX-NEXT: xor a0, a0, a1
763 ; CHECKIZFINX-NEXT: ret
765 ; RV32I-LABEL: fnmadd_nsz:
767 ; RV32I-NEXT: addi sp, sp, -16
768 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
769 ; RV32I-NEXT: call fmaf
770 ; RV32I-NEXT: lui a1, 524288
771 ; RV32I-NEXT: xor a0, a0, a1
772 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
773 ; RV32I-NEXT: addi sp, sp, 16
776 ; RV64I-LABEL: fnmadd_nsz:
778 ; RV64I-NEXT: addi sp, sp, -16
779 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
780 ; RV64I-NEXT: call fmaf
781 ; RV64I-NEXT: lui a1, 524288
782 ; RV64I-NEXT: xor a0, a0, a1
783 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
784 ; RV64I-NEXT: addi sp, sp, 16
786 %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c)
787 %neg = fneg nsz float %1
791 define float @fnmsub_s(float %a, float %b, float %c) nounwind {
792 ; CHECKIF-LABEL: fnmsub_s:
794 ; CHECKIF-NEXT: fmv.w.x fa5, zero
795 ; CHECKIF-NEXT: fadd.s fa5, fa0, fa5
796 ; CHECKIF-NEXT: fnmsub.s fa0, fa5, fa1, fa2
799 ; CHECKIZFINX-LABEL: fnmsub_s:
800 ; CHECKIZFINX: # %bb.0:
801 ; CHECKIZFINX-NEXT: fadd.s a0, a0, zero
802 ; CHECKIZFINX-NEXT: fnmsub.s a0, a0, a1, a2
803 ; CHECKIZFINX-NEXT: ret
805 ; RV32I-LABEL: fnmsub_s:
807 ; RV32I-NEXT: addi sp, sp, -16
808 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
809 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
810 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
811 ; RV32I-NEXT: mv s0, a2
812 ; RV32I-NEXT: mv s1, a1
813 ; RV32I-NEXT: li a1, 0
814 ; RV32I-NEXT: call __addsf3
815 ; RV32I-NEXT: lui a1, 524288
816 ; RV32I-NEXT: xor a0, a0, a1
817 ; RV32I-NEXT: mv a1, s1
818 ; RV32I-NEXT: mv a2, s0
819 ; RV32I-NEXT: call fmaf
820 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
821 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
822 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
823 ; RV32I-NEXT: addi sp, sp, 16
826 ; RV64I-LABEL: fnmsub_s:
828 ; RV64I-NEXT: addi sp, sp, -32
829 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
830 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
831 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
832 ; RV64I-NEXT: mv s0, a2
833 ; RV64I-NEXT: mv s1, a1
834 ; RV64I-NEXT: li a1, 0
835 ; RV64I-NEXT: call __addsf3
836 ; RV64I-NEXT: lui a1, 524288
837 ; RV64I-NEXT: xor a0, a0, a1
838 ; RV64I-NEXT: mv a1, s1
839 ; RV64I-NEXT: mv a2, s0
840 ; RV64I-NEXT: call fmaf
841 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
842 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
843 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
844 ; RV64I-NEXT: addi sp, sp, 32
846 %a_ = fadd float 0.0, %a
847 %nega = fsub float -0.0, %a_
848 %1 = call float @llvm.fma.f32(float %nega, float %b, float %c)
852 define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
853 ; CHECKIF-LABEL: fnmsub_s_2:
855 ; CHECKIF-NEXT: fmv.w.x fa5, zero
856 ; CHECKIF-NEXT: fadd.s fa5, fa1, fa5
857 ; CHECKIF-NEXT: fnmsub.s fa0, fa5, fa0, fa2
860 ; CHECKIZFINX-LABEL: fnmsub_s_2:
861 ; CHECKIZFINX: # %bb.0:
862 ; CHECKIZFINX-NEXT: fadd.s a1, a1, zero
863 ; CHECKIZFINX-NEXT: fnmsub.s a0, a1, a0, a2
864 ; CHECKIZFINX-NEXT: ret
866 ; RV32I-LABEL: fnmsub_s_2:
868 ; RV32I-NEXT: addi sp, sp, -16
869 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
870 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
871 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
872 ; RV32I-NEXT: mv s0, a2
873 ; RV32I-NEXT: mv s1, a0
874 ; RV32I-NEXT: mv a0, a1
875 ; RV32I-NEXT: li a1, 0
876 ; RV32I-NEXT: call __addsf3
877 ; RV32I-NEXT: lui a1, 524288
878 ; RV32I-NEXT: xor a1, a0, a1
879 ; RV32I-NEXT: mv a0, s1
880 ; RV32I-NEXT: mv a2, s0
881 ; RV32I-NEXT: call fmaf
882 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
883 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
884 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
885 ; RV32I-NEXT: addi sp, sp, 16
888 ; RV64I-LABEL: fnmsub_s_2:
890 ; RV64I-NEXT: addi sp, sp, -32
891 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
892 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
893 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
894 ; RV64I-NEXT: mv s0, a2
895 ; RV64I-NEXT: mv s1, a0
896 ; RV64I-NEXT: mv a0, a1
897 ; RV64I-NEXT: li a1, 0
898 ; RV64I-NEXT: call __addsf3
899 ; RV64I-NEXT: lui a1, 524288
900 ; RV64I-NEXT: xor a1, a0, a1
901 ; RV64I-NEXT: mv a0, s1
902 ; RV64I-NEXT: mv a2, s0
903 ; RV64I-NEXT: call fmaf
904 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
905 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
906 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
907 ; RV64I-NEXT: addi sp, sp, 32
909 %b_ = fadd float 0.0, %b
910 %negb = fsub float -0.0, %b_
911 %1 = call float @llvm.fma.f32(float %a, float %negb, float %c)
915 define float @fmadd_s_contract(float %a, float %b, float %c) nounwind {
916 ; CHECKIF-LABEL: fmadd_s_contract:
918 ; CHECKIF-NEXT: fmadd.s fa0, fa0, fa1, fa2
921 ; CHECKIZFINX-LABEL: fmadd_s_contract:
922 ; CHECKIZFINX: # %bb.0:
923 ; CHECKIZFINX-NEXT: fmadd.s a0, a0, a1, a2
924 ; CHECKIZFINX-NEXT: ret
926 ; RV32I-LABEL: fmadd_s_contract:
928 ; RV32I-NEXT: addi sp, sp, -16
929 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
930 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
931 ; RV32I-NEXT: mv s0, a2
932 ; RV32I-NEXT: call __mulsf3
933 ; RV32I-NEXT: mv a1, s0
934 ; RV32I-NEXT: call __addsf3
935 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
936 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
937 ; RV32I-NEXT: addi sp, sp, 16
940 ; RV64I-LABEL: fmadd_s_contract:
942 ; RV64I-NEXT: addi sp, sp, -16
943 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
944 ; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
945 ; RV64I-NEXT: mv s0, a2
946 ; RV64I-NEXT: call __mulsf3
947 ; RV64I-NEXT: mv a1, s0
948 ; RV64I-NEXT: call __addsf3
949 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
950 ; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
951 ; RV64I-NEXT: addi sp, sp, 16
953 %1 = fmul contract float %a, %b
954 %2 = fadd contract float %1, %c
958 define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
959 ; CHECKIF-LABEL: fmsub_s_contract:
961 ; CHECKIF-NEXT: fmv.w.x fa5, zero
962 ; CHECKIF-NEXT: fadd.s fa5, fa2, fa5
963 ; CHECKIF-NEXT: fmsub.s fa0, fa0, fa1, fa5
966 ; CHECKIZFINX-LABEL: fmsub_s_contract:
967 ; CHECKIZFINX: # %bb.0:
968 ; CHECKIZFINX-NEXT: fadd.s a2, a2, zero
969 ; CHECKIZFINX-NEXT: fmsub.s a0, a0, a1, a2
970 ; CHECKIZFINX-NEXT: ret
972 ; RV32I-LABEL: fmsub_s_contract:
974 ; RV32I-NEXT: addi sp, sp, -16
975 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
976 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
977 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
978 ; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
979 ; RV32I-NEXT: mv s0, a1
980 ; RV32I-NEXT: mv s1, a0
981 ; RV32I-NEXT: mv a0, a2
982 ; RV32I-NEXT: li a1, 0
983 ; RV32I-NEXT: call __addsf3
984 ; RV32I-NEXT: mv s2, a0
985 ; RV32I-NEXT: mv a0, s1
986 ; RV32I-NEXT: mv a1, s0
987 ; RV32I-NEXT: call __mulsf3
988 ; RV32I-NEXT: mv a1, s2
989 ; RV32I-NEXT: call __subsf3
990 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
991 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
992 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
993 ; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
994 ; RV32I-NEXT: addi sp, sp, 16
997 ; RV64I-LABEL: fmsub_s_contract:
999 ; RV64I-NEXT: addi sp, sp, -32
1000 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1001 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1002 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1003 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1004 ; RV64I-NEXT: mv s0, a1
1005 ; RV64I-NEXT: mv s1, a0
1006 ; RV64I-NEXT: mv a0, a2
1007 ; RV64I-NEXT: li a1, 0
1008 ; RV64I-NEXT: call __addsf3
1009 ; RV64I-NEXT: mv s2, a0
1010 ; RV64I-NEXT: mv a0, s1
1011 ; RV64I-NEXT: mv a1, s0
1012 ; RV64I-NEXT: call __mulsf3
1013 ; RV64I-NEXT: mv a1, s2
1014 ; RV64I-NEXT: call __subsf3
1015 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1016 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1017 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1018 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1019 ; RV64I-NEXT: addi sp, sp, 32
1021 %c_ = fadd float 0.0, %c ; avoid negation using xor
1022 %1 = fmul contract float %a, %b
1023 %2 = fsub contract float %1, %c_
1027 define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind {
1028 ; CHECKIF-LABEL: fnmadd_s_contract:
1030 ; CHECKIF-NEXT: fmv.w.x fa5, zero
1031 ; CHECKIF-NEXT: fadd.s fa4, fa0, fa5
1032 ; CHECKIF-NEXT: fadd.s fa3, fa1, fa5
1033 ; CHECKIF-NEXT: fadd.s fa5, fa2, fa5
1034 ; CHECKIF-NEXT: fnmadd.s fa0, fa4, fa3, fa5
1037 ; CHECKIZFINX-LABEL: fnmadd_s_contract:
1038 ; CHECKIZFINX: # %bb.0:
1039 ; CHECKIZFINX-NEXT: fadd.s a0, a0, zero
1040 ; CHECKIZFINX-NEXT: fadd.s a1, a1, zero
1041 ; CHECKIZFINX-NEXT: fadd.s a2, a2, zero
1042 ; CHECKIZFINX-NEXT: fnmadd.s a0, a0, a1, a2
1043 ; CHECKIZFINX-NEXT: ret
1045 ; RV32I-LABEL: fnmadd_s_contract:
1047 ; RV32I-NEXT: addi sp, sp, -16
1048 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1049 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
1050 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
1051 ; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
1052 ; RV32I-NEXT: mv s0, a2
1053 ; RV32I-NEXT: mv s1, a1
1054 ; RV32I-NEXT: li a1, 0
1055 ; RV32I-NEXT: call __addsf3
1056 ; RV32I-NEXT: mv s2, a0
1057 ; RV32I-NEXT: mv a0, s1
1058 ; RV32I-NEXT: li a1, 0
1059 ; RV32I-NEXT: call __addsf3
1060 ; RV32I-NEXT: mv s1, a0
1061 ; RV32I-NEXT: mv a0, s0
1062 ; RV32I-NEXT: li a1, 0
1063 ; RV32I-NEXT: call __addsf3
1064 ; RV32I-NEXT: mv s0, a0
1065 ; RV32I-NEXT: mv a0, s2
1066 ; RV32I-NEXT: mv a1, s1
1067 ; RV32I-NEXT: call __mulsf3
1068 ; RV32I-NEXT: lui a1, 524288
1069 ; RV32I-NEXT: xor a0, a0, a1
1070 ; RV32I-NEXT: mv a1, s0
1071 ; RV32I-NEXT: call __subsf3
1072 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1073 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
1074 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
1075 ; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
1076 ; RV32I-NEXT: addi sp, sp, 16
1079 ; RV64I-LABEL: fnmadd_s_contract:
1081 ; RV64I-NEXT: addi sp, sp, -32
1082 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1083 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1084 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1085 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1086 ; RV64I-NEXT: mv s0, a2
1087 ; RV64I-NEXT: mv s1, a1
1088 ; RV64I-NEXT: li a1, 0
1089 ; RV64I-NEXT: call __addsf3
1090 ; RV64I-NEXT: mv s2, a0
1091 ; RV64I-NEXT: mv a0, s1
1092 ; RV64I-NEXT: li a1, 0
1093 ; RV64I-NEXT: call __addsf3
1094 ; RV64I-NEXT: mv s1, a0
1095 ; RV64I-NEXT: mv a0, s0
1096 ; RV64I-NEXT: li a1, 0
1097 ; RV64I-NEXT: call __addsf3
1098 ; RV64I-NEXT: mv s0, a0
1099 ; RV64I-NEXT: mv a0, s2
1100 ; RV64I-NEXT: mv a1, s1
1101 ; RV64I-NEXT: call __mulsf3
1102 ; RV64I-NEXT: lui a1, 524288
1103 ; RV64I-NEXT: xor a0, a0, a1
1104 ; RV64I-NEXT: mv a1, s0
1105 ; RV64I-NEXT: call __subsf3
1106 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1107 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1108 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1109 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1110 ; RV64I-NEXT: addi sp, sp, 32
1112 %a_ = fadd float 0.0, %a ; avoid negation using xor
1113 %b_ = fadd float 0.0, %b ; avoid negation using xor
1114 %c_ = fadd float 0.0, %c ; avoid negation using xor
1115 %1 = fmul contract float %a_, %b_
1117 %3 = fsub contract float %2, %c_
1121 define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind {
1122 ; CHECKIF-LABEL: fnmsub_s_contract:
1124 ; CHECKIF-NEXT: fmv.w.x fa5, zero
1125 ; CHECKIF-NEXT: fadd.s fa4, fa0, fa5
1126 ; CHECKIF-NEXT: fadd.s fa5, fa1, fa5
1127 ; CHECKIF-NEXT: fnmsub.s fa0, fa4, fa5, fa2
1130 ; CHECKIZFINX-LABEL: fnmsub_s_contract:
1131 ; CHECKIZFINX: # %bb.0:
1132 ; CHECKIZFINX-NEXT: fadd.s a0, a0, zero
1133 ; CHECKIZFINX-NEXT: fadd.s a1, a1, zero
1134 ; CHECKIZFINX-NEXT: fnmsub.s a0, a0, a1, a2
1135 ; CHECKIZFINX-NEXT: ret
1137 ; RV32I-LABEL: fnmsub_s_contract:
1139 ; RV32I-NEXT: addi sp, sp, -16
1140 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1141 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
1142 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
1143 ; RV32I-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
1144 ; RV32I-NEXT: mv s0, a2
1145 ; RV32I-NEXT: mv s1, a1
1146 ; RV32I-NEXT: li a1, 0
1147 ; RV32I-NEXT: call __addsf3
1148 ; RV32I-NEXT: mv s2, a0
1149 ; RV32I-NEXT: mv a0, s1
1150 ; RV32I-NEXT: li a1, 0
1151 ; RV32I-NEXT: call __addsf3
1152 ; RV32I-NEXT: mv a1, a0
1153 ; RV32I-NEXT: mv a0, s2
1154 ; RV32I-NEXT: call __mulsf3
1155 ; RV32I-NEXT: mv a1, a0
1156 ; RV32I-NEXT: mv a0, s0
1157 ; RV32I-NEXT: call __subsf3
1158 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1159 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
1160 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
1161 ; RV32I-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
1162 ; RV32I-NEXT: addi sp, sp, 16
1165 ; RV64I-LABEL: fnmsub_s_contract:
1167 ; RV64I-NEXT: addi sp, sp, -32
1168 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1169 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1170 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1171 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1172 ; RV64I-NEXT: mv s0, a2
1173 ; RV64I-NEXT: mv s1, a1
1174 ; RV64I-NEXT: li a1, 0
1175 ; RV64I-NEXT: call __addsf3
1176 ; RV64I-NEXT: mv s2, a0
1177 ; RV64I-NEXT: mv a0, s1
1178 ; RV64I-NEXT: li a1, 0
1179 ; RV64I-NEXT: call __addsf3
1180 ; RV64I-NEXT: mv a1, a0
1181 ; RV64I-NEXT: mv a0, s2
1182 ; RV64I-NEXT: call __mulsf3
1183 ; RV64I-NEXT: mv a1, a0
1184 ; RV64I-NEXT: mv a0, s0
1185 ; RV64I-NEXT: call __subsf3
1186 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1187 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1188 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1189 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1190 ; RV64I-NEXT: addi sp, sp, 32
1192 %a_ = fadd float 0.0, %a ; avoid negation using xor
1193 %b_ = fadd float 0.0, %b ; avoid negation using xor
1194 %1 = fmul contract float %a_, %b_
1195 %2 = fsub contract float %c, %1