Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / RISCV / float-arith.ll
blob7a7ebe651c08e127b514095836e62944207d6ce6
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:
22 ; CHECKIF:       # %bb.0:
23 ; CHECKIF-NEXT:    fadd.s fa0, fa0, fa1
24 ; CHECKIF-NEXT:    ret
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:
32 ; RV32I:       # %bb.0:
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
38 ; RV32I-NEXT:    ret
40 ; RV64I-LABEL: fadd_s:
41 ; RV64I:       # %bb.0:
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
47 ; RV64I-NEXT:    ret
48   %1 = fadd float %a, %b
49   ret float %1
52 define float @fsub_s(float %a, float %b) nounwind {
53 ; CHECKIF-LABEL: fsub_s:
54 ; CHECKIF:       # %bb.0:
55 ; CHECKIF-NEXT:    fsub.s fa0, fa0, fa1
56 ; CHECKIF-NEXT:    ret
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:
64 ; RV32I:       # %bb.0:
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
70 ; RV32I-NEXT:    ret
72 ; RV64I-LABEL: fsub_s:
73 ; RV64I:       # %bb.0:
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
79 ; RV64I-NEXT:    ret
80   %1 = fsub float %a, %b
81   ret float %1
84 define float @fmul_s(float %a, float %b) nounwind {
85 ; CHECKIF-LABEL: fmul_s:
86 ; CHECKIF:       # %bb.0:
87 ; CHECKIF-NEXT:    fmul.s fa0, fa0, fa1
88 ; CHECKIF-NEXT:    ret
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:
96 ; RV32I:       # %bb.0:
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
102 ; RV32I-NEXT:    ret
104 ; RV64I-LABEL: fmul_s:
105 ; RV64I:       # %bb.0:
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
111 ; RV64I-NEXT:    ret
112   %1 = fmul float %a, %b
113   ret float %1
116 define float @fdiv_s(float %a, float %b) nounwind {
117 ; CHECKIF-LABEL: fdiv_s:
118 ; CHECKIF:       # %bb.0:
119 ; CHECKIF-NEXT:    fdiv.s fa0, fa0, fa1
120 ; CHECKIF-NEXT:    ret
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:
128 ; RV32I:       # %bb.0:
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
134 ; RV32I-NEXT:    ret
136 ; RV64I-LABEL: fdiv_s:
137 ; RV64I:       # %bb.0:
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
143 ; RV64I-NEXT:    ret
144   %1 = fdiv float %a, %b
145   ret float %1
148 declare float @llvm.sqrt.f32(float)
150 define float @fsqrt_s(float %a) nounwind {
151 ; CHECKIF-LABEL: fsqrt_s:
152 ; CHECKIF:       # %bb.0:
153 ; CHECKIF-NEXT:    fsqrt.s fa0, fa0
154 ; CHECKIF-NEXT:    ret
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:
162 ; RV32I:       # %bb.0:
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
168 ; RV32I-NEXT:    ret
170 ; RV64I-LABEL: fsqrt_s:
171 ; RV64I:       # %bb.0:
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
177 ; RV64I-NEXT:    ret
178   %1 = call float @llvm.sqrt.f32(float %a)
179   ret float %1
182 declare float @llvm.copysign.f32(float, float)
184 define float @fsgnj_s(float %a, float %b) nounwind {
185 ; CHECKIF-LABEL: fsgnj_s:
186 ; CHECKIF:       # %bb.0:
187 ; CHECKIF-NEXT:    fsgnj.s fa0, fa0, fa1
188 ; CHECKIF-NEXT:    ret
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:
196 ; RV32I:       # %bb.0:
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
202 ; RV32I-NEXT:    ret
204 ; RV64I-LABEL: fsgnj_s:
205 ; RV64I:       # %bb.0:
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
211 ; RV64I-NEXT:    ret
212   %1 = call float @llvm.copysign.f32(float %a, float %b)
213   ret float %1
216 define i32 @fneg_s(float %a, float %b) nounwind {
217 ; CHECKIF-LABEL: fneg_s:
218 ; CHECKIF:       # %bb.0:
219 ; CHECKIF-NEXT:    fadd.s fa5, fa0, fa0
220 ; CHECKIF-NEXT:    fneg.s fa4, fa5
221 ; CHECKIF-NEXT:    feq.s a0, fa5, fa4
222 ; CHECKIF-NEXT:    ret
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:
232 ; RV32I:       # %bb.0:
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
243 ; RV32I-NEXT:    ret
245 ; RV64I-LABEL: fneg_s:
246 ; RV64I:       # %bb.0:
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
257 ; RV64I-NEXT:    ret
258   %1 = fadd float %a, %a
259   %2 = fneg float %1
260   %3 = fcmp oeq float %1, %2
261   %4 = zext i1 %3 to i32
262   ret i32 %4
265 define float @fsgnjn_s(float %a, float %b) nounwind {
266 ; CHECKIF-LABEL: fsgnjn_s:
267 ; CHECKIF:       # %bb.0:
268 ; CHECKIF-NEXT:    fadd.s fa5, fa0, fa1
269 ; CHECKIF-NEXT:    fsgnjn.s fa0, fa0, fa5
270 ; CHECKIF-NEXT:    ret
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:
279 ; RV32I:       # %bb.0:
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
294 ; RV32I-NEXT:    ret
296 ; RV64I-LABEL: fsgnjn_s:
297 ; RV64I:       # %bb.0:
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
312 ; RV64I-NEXT:    ret
313   %1 = fadd float %a, %b
314   %2 = fneg float %1
315   %3 = call float @llvm.copysign.f32(float %a, float %2)
316   ret float %3
319 declare float @llvm.fabs.f32(float)
321 define float @fabs_s(float %a, float %b) nounwind {
322 ; CHECKIF-LABEL: fabs_s:
323 ; CHECKIF:       # %bb.0:
324 ; CHECKIF-NEXT:    fadd.s fa5, fa0, fa1
325 ; CHECKIF-NEXT:    fabs.s fa4, fa5
326 ; CHECKIF-NEXT:    fadd.s fa0, fa4, fa5
327 ; CHECKIF-NEXT:    ret
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:
337 ; RV32I:       # %bb.0:
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
347 ; RV32I-NEXT:    ret
349 ; RV64I-LABEL: fabs_s:
350 ; RV64I:       # %bb.0:
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
360 ; RV64I-NEXT:    ret
361   %1 = fadd float %a, %b
362   %2 = call float @llvm.fabs.f32(float %1)
363   %3 = fadd float %2, %1
364   ret float %3
367 declare float @llvm.minnum.f32(float, float)
369 define float @fmin_s(float %a, float %b) nounwind {
370 ; CHECKIF-LABEL: fmin_s:
371 ; CHECKIF:       # %bb.0:
372 ; CHECKIF-NEXT:    fmin.s fa0, fa0, fa1
373 ; CHECKIF-NEXT:    ret
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:
381 ; RV32I:       # %bb.0:
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
387 ; RV32I-NEXT:    ret
389 ; RV64I-LABEL: fmin_s:
390 ; RV64I:       # %bb.0:
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
396 ; RV64I-NEXT:    ret
397   %1 = call float @llvm.minnum.f32(float %a, float %b)
398   ret float %1
401 declare float @llvm.maxnum.f32(float, float)
403 define float @fmax_s(float %a, float %b) nounwind {
404 ; CHECKIF-LABEL: fmax_s:
405 ; CHECKIF:       # %bb.0:
406 ; CHECKIF-NEXT:    fmax.s fa0, fa0, fa1
407 ; CHECKIF-NEXT:    ret
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:
415 ; RV32I:       # %bb.0:
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
421 ; RV32I-NEXT:    ret
423 ; RV64I-LABEL: fmax_s:
424 ; RV64I:       # %bb.0:
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
430 ; RV64I-NEXT:    ret
431   %1 = call float @llvm.maxnum.f32(float %a, float %b)
432   ret float %1
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:
439 ; CHECKIF:       # %bb.0:
440 ; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
441 ; CHECKIF-NEXT:    ret
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:
449 ; RV32I:       # %bb.0:
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
455 ; RV32I-NEXT:    ret
457 ; RV64I-LABEL: fmadd_s:
458 ; RV64I:       # %bb.0:
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
464 ; RV64I-NEXT:    ret
465   %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
466   ret float %1
469 define float @fmsub_s(float %a, float %b, float %c) nounwind {
470 ; CHECKIF-LABEL: fmsub_s:
471 ; CHECKIF:       # %bb.0:
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
475 ; CHECKIF-NEXT:    ret
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:
484 ; RV32I:       # %bb.0:
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
503 ; RV32I-NEXT:    ret
505 ; RV64I-LABEL: fmsub_s:
506 ; RV64I:       # %bb.0:
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
525 ; RV64I-NEXT:    ret
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)
529   ret float %1
532 define float @fnmadd_s(float %a, float %b, float %c) nounwind {
533 ; CHECKIF-LABEL: fnmadd_s:
534 ; CHECKIF:       # %bb.0:
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
539 ; CHECKIF-NEXT:    ret
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:
549 ; RV32I:       # %bb.0:
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
574 ; RV32I-NEXT:    ret
576 ; RV64I-LABEL: fnmadd_s:
577 ; RV64I:       # %bb.0:
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
602 ; RV64I-NEXT:    ret
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)
608   ret float %1
611 define float @fnmadd_s_2(float %a, float %b, float %c) nounwind {
612 ; CHECKIF-LABEL: fnmadd_s_2:
613 ; CHECKIF:       # %bb.0:
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
618 ; CHECKIF-NEXT:    ret
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:
628 ; RV32I:       # %bb.0:
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
653 ; RV32I-NEXT:    ret
655 ; RV64I-LABEL: fnmadd_s_2:
656 ; RV64I:       # %bb.0:
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
681 ; RV64I-NEXT:    ret
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)
687   ret float %1
690 define float @fnmadd_s_3(float %a, float %b, float %c) nounwind {
691 ; RV32IF-LABEL: fnmadd_s_3:
692 ; RV32IF:       # %bb.0:
693 ; RV32IF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
694 ; RV32IF-NEXT:    fneg.s fa0, ft0
695 ; RV32IF-NEXT:    ret
697 ; RV64IF-LABEL: fnmadd_s_3:
698 ; RV64IF:       # %bb.0:
699 ; RV64IF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
700 ; RV64IF-NEXT:    fneg.s fa0, ft0
701 ; RV64IF-NEXT:    ret
703 ; CHECKIF-LABEL: fnmadd_s_3:
704 ; CHECKIF:       # %bb.0:
705 ; CHECKIF-NEXT:    fmadd.s fa5, fa0, fa1, fa2
706 ; CHECKIF-NEXT:    fneg.s fa0, fa5
707 ; CHECKIF-NEXT:    ret
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:
717 ; RV32I:       # %bb.0:
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
725 ; RV32I-NEXT:    ret
727 ; RV64I-LABEL: fnmadd_s_3:
728 ; RV64I:       # %bb.0:
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
736 ; RV64I-NEXT:    ret
737   %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
738   %neg = fneg float %1
739   ret float %neg
742 define float @fnmadd_nsz(float %a, float %b, float %c) nounwind {
743 ; RV32IF-LABEL: fnmadd_nsz:
744 ; RV32IF:       # %bb.0:
745 ; RV32IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
746 ; RV32IF-NEXT:    ret
748 ; RV64IF-LABEL: fnmadd_nsz:
749 ; RV64IF:       # %bb.0:
750 ; RV64IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
751 ; RV64IF-NEXT:    ret
753 ; CHECKIF-LABEL: fnmadd_nsz:
754 ; CHECKIF:       # %bb.0:
755 ; CHECKIF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
756 ; CHECKIF-NEXT:    ret
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:
766 ; RV32I:       # %bb.0:
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
774 ; RV32I-NEXT:    ret
776 ; RV64I-LABEL: fnmadd_nsz:
777 ; RV64I:       # %bb.0:
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
785 ; RV64I-NEXT:    ret
786   %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c)
787   %neg = fneg nsz float %1
788   ret float %neg
791 define float @fnmsub_s(float %a, float %b, float %c) nounwind {
792 ; CHECKIF-LABEL: fnmsub_s:
793 ; CHECKIF:       # %bb.0:
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
797 ; CHECKIF-NEXT:    ret
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:
806 ; RV32I:       # %bb.0:
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
824 ; RV32I-NEXT:    ret
826 ; RV64I-LABEL: fnmsub_s:
827 ; RV64I:       # %bb.0:
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
845 ; RV64I-NEXT:    ret
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)
849   ret float %1
852 define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
853 ; CHECKIF-LABEL: fnmsub_s_2:
854 ; CHECKIF:       # %bb.0:
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
858 ; CHECKIF-NEXT:    ret
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:
867 ; RV32I:       # %bb.0:
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
886 ; RV32I-NEXT:    ret
888 ; RV64I-LABEL: fnmsub_s_2:
889 ; RV64I:       # %bb.0:
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
908 ; RV64I-NEXT:    ret
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)
912   ret float %1
915 define float @fmadd_s_contract(float %a, float %b, float %c) nounwind {
916 ; CHECKIF-LABEL: fmadd_s_contract:
917 ; CHECKIF:       # %bb.0:
918 ; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
919 ; CHECKIF-NEXT:    ret
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:
927 ; RV32I:       # %bb.0:
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
938 ; RV32I-NEXT:    ret
940 ; RV64I-LABEL: fmadd_s_contract:
941 ; RV64I:       # %bb.0:
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
952 ; RV64I-NEXT:    ret
953   %1 = fmul contract float %a, %b
954   %2 = fadd contract float %1, %c
955   ret float %2
958 define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
959 ; CHECKIF-LABEL: fmsub_s_contract:
960 ; CHECKIF:       # %bb.0:
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
964 ; CHECKIF-NEXT:    ret
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:
973 ; RV32I:       # %bb.0:
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
995 ; RV32I-NEXT:    ret
997 ; RV64I-LABEL: fmsub_s_contract:
998 ; RV64I:       # %bb.0:
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
1020 ; RV64I-NEXT:    ret
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_
1024   ret float %2
1027 define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind {
1028 ; CHECKIF-LABEL: fnmadd_s_contract:
1029 ; CHECKIF:       # %bb.0:
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
1035 ; CHECKIF-NEXT:    ret
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:
1046 ; RV32I:       # %bb.0:
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
1077 ; RV32I-NEXT:    ret
1079 ; RV64I-LABEL: fnmadd_s_contract:
1080 ; RV64I:       # %bb.0:
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
1111 ; RV64I-NEXT:    ret
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_
1116   %2 = fneg float %1
1117   %3 = fsub contract float %2, %c_
1118   ret float %3
1121 define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind {
1122 ; CHECKIF-LABEL: fnmsub_s_contract:
1123 ; CHECKIF:       # %bb.0:
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
1128 ; CHECKIF-NEXT:    ret
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:
1138 ; RV32I:       # %bb.0:
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
1163 ; RV32I-NEXT:    ret
1165 ; RV64I-LABEL: fnmsub_s_contract:
1166 ; RV64I:       # %bb.0:
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
1191 ; RV64I-NEXT:    ret
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
1196   ret float %2