Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / RISCV / double-arith.ll
blobced6ff66ef6783739d39d8666175f58507ab7445
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:   -target-abi=ilp32d | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
5 ; RUN:   -target-abi=lp64d | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs < %s \
7 ; RUN:   -target-abi=ilp32 | FileCheck -check-prefix=RV32IZFINXZDINX %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+zdinx -verify-machineinstrs < %s \
9 ; RUN:   -target-abi=lp64 | FileCheck -check-prefix=RV64IZFINXZDINX %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 double-fcmp.ll and double-convert.ll
17 ; respectively. Some other double-*.ll files in this folder exercise LLVM IR
18 ; instructions that don't directly match a RISC-V instruction.
20 define double @fadd_d(double %a, double %b) nounwind {
21 ; CHECKIFD-LABEL: fadd_d:
22 ; CHECKIFD:       # %bb.0:
23 ; CHECKIFD-NEXT:    fadd.d fa0, fa0, fa1
24 ; CHECKIFD-NEXT:    ret
26 ; RV32IZFINXZDINX-LABEL: fadd_d:
27 ; RV32IZFINXZDINX:       # %bb.0:
28 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a2
29 ; RV32IZFINXZDINX-NEXT:    ret
31 ; RV64IZFINXZDINX-LABEL: fadd_d:
32 ; RV64IZFINXZDINX:       # %bb.0:
33 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, a1
34 ; RV64IZFINXZDINX-NEXT:    ret
36 ; RV32I-LABEL: fadd_d:
37 ; RV32I:       # %bb.0:
38 ; RV32I-NEXT:    addi sp, sp, -16
39 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
40 ; RV32I-NEXT:    call __adddf3
41 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
42 ; RV32I-NEXT:    addi sp, sp, 16
43 ; RV32I-NEXT:    ret
45 ; RV64I-LABEL: fadd_d:
46 ; RV64I:       # %bb.0:
47 ; RV64I-NEXT:    addi sp, sp, -16
48 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
49 ; RV64I-NEXT:    call __adddf3
50 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
51 ; RV64I-NEXT:    addi sp, sp, 16
52 ; RV64I-NEXT:    ret
53   %1 = fadd double %a, %b
54   ret double %1
57 define double @fsub_d(double %a, double %b) nounwind {
58 ; CHECKIFD-LABEL: fsub_d:
59 ; CHECKIFD:       # %bb.0:
60 ; CHECKIFD-NEXT:    fsub.d fa0, fa0, fa1
61 ; CHECKIFD-NEXT:    ret
63 ; RV32IZFINXZDINX-LABEL: fsub_d:
64 ; RV32IZFINXZDINX:       # %bb.0:
65 ; RV32IZFINXZDINX-NEXT:    fsub.d a0, a0, a2
66 ; RV32IZFINXZDINX-NEXT:    ret
68 ; RV64IZFINXZDINX-LABEL: fsub_d:
69 ; RV64IZFINXZDINX:       # %bb.0:
70 ; RV64IZFINXZDINX-NEXT:    fsub.d a0, a0, a1
71 ; RV64IZFINXZDINX-NEXT:    ret
73 ; RV32I-LABEL: fsub_d:
74 ; RV32I:       # %bb.0:
75 ; RV32I-NEXT:    addi sp, sp, -16
76 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
77 ; RV32I-NEXT:    call __subdf3
78 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
79 ; RV32I-NEXT:    addi sp, sp, 16
80 ; RV32I-NEXT:    ret
82 ; RV64I-LABEL: fsub_d:
83 ; RV64I:       # %bb.0:
84 ; RV64I-NEXT:    addi sp, sp, -16
85 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
86 ; RV64I-NEXT:    call __subdf3
87 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
88 ; RV64I-NEXT:    addi sp, sp, 16
89 ; RV64I-NEXT:    ret
90   %1 = fsub double %a, %b
91   ret double %1
94 define double @fmul_d(double %a, double %b) nounwind {
95 ; CHECKIFD-LABEL: fmul_d:
96 ; CHECKIFD:       # %bb.0:
97 ; CHECKIFD-NEXT:    fmul.d fa0, fa0, fa1
98 ; CHECKIFD-NEXT:    ret
100 ; RV32IZFINXZDINX-LABEL: fmul_d:
101 ; RV32IZFINXZDINX:       # %bb.0:
102 ; RV32IZFINXZDINX-NEXT:    fmul.d a0, a0, a2
103 ; RV32IZFINXZDINX-NEXT:    ret
105 ; RV64IZFINXZDINX-LABEL: fmul_d:
106 ; RV64IZFINXZDINX:       # %bb.0:
107 ; RV64IZFINXZDINX-NEXT:    fmul.d a0, a0, a1
108 ; RV64IZFINXZDINX-NEXT:    ret
110 ; RV32I-LABEL: fmul_d:
111 ; RV32I:       # %bb.0:
112 ; RV32I-NEXT:    addi sp, sp, -16
113 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
114 ; RV32I-NEXT:    call __muldf3
115 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
116 ; RV32I-NEXT:    addi sp, sp, 16
117 ; RV32I-NEXT:    ret
119 ; RV64I-LABEL: fmul_d:
120 ; RV64I:       # %bb.0:
121 ; RV64I-NEXT:    addi sp, sp, -16
122 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
123 ; RV64I-NEXT:    call __muldf3
124 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
125 ; RV64I-NEXT:    addi sp, sp, 16
126 ; RV64I-NEXT:    ret
127   %1 = fmul double %a, %b
128   ret double %1
131 define double @fdiv_d(double %a, double %b) nounwind {
132 ; CHECKIFD-LABEL: fdiv_d:
133 ; CHECKIFD:       # %bb.0:
134 ; CHECKIFD-NEXT:    fdiv.d fa0, fa0, fa1
135 ; CHECKIFD-NEXT:    ret
137 ; RV32IZFINXZDINX-LABEL: fdiv_d:
138 ; RV32IZFINXZDINX:       # %bb.0:
139 ; RV32IZFINXZDINX-NEXT:    fdiv.d a0, a0, a2
140 ; RV32IZFINXZDINX-NEXT:    ret
142 ; RV64IZFINXZDINX-LABEL: fdiv_d:
143 ; RV64IZFINXZDINX:       # %bb.0:
144 ; RV64IZFINXZDINX-NEXT:    fdiv.d a0, a0, a1
145 ; RV64IZFINXZDINX-NEXT:    ret
147 ; RV32I-LABEL: fdiv_d:
148 ; RV32I:       # %bb.0:
149 ; RV32I-NEXT:    addi sp, sp, -16
150 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
151 ; RV32I-NEXT:    call __divdf3
152 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
153 ; RV32I-NEXT:    addi sp, sp, 16
154 ; RV32I-NEXT:    ret
156 ; RV64I-LABEL: fdiv_d:
157 ; RV64I:       # %bb.0:
158 ; RV64I-NEXT:    addi sp, sp, -16
159 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
160 ; RV64I-NEXT:    call __divdf3
161 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
162 ; RV64I-NEXT:    addi sp, sp, 16
163 ; RV64I-NEXT:    ret
164   %1 = fdiv double %a, %b
165   ret double %1
168 declare double @llvm.sqrt.f64(double)
170 define double @fsqrt_d(double %a) nounwind {
171 ; CHECKIFD-LABEL: fsqrt_d:
172 ; CHECKIFD:       # %bb.0:
173 ; CHECKIFD-NEXT:    fsqrt.d fa0, fa0
174 ; CHECKIFD-NEXT:    ret
176 ; RV32IZFINXZDINX-LABEL: fsqrt_d:
177 ; RV32IZFINXZDINX:       # %bb.0:
178 ; RV32IZFINXZDINX-NEXT:    fsqrt.d a0, a0
179 ; RV32IZFINXZDINX-NEXT:    ret
181 ; RV64IZFINXZDINX-LABEL: fsqrt_d:
182 ; RV64IZFINXZDINX:       # %bb.0:
183 ; RV64IZFINXZDINX-NEXT:    fsqrt.d a0, a0
184 ; RV64IZFINXZDINX-NEXT:    ret
186 ; RV32I-LABEL: fsqrt_d:
187 ; RV32I:       # %bb.0:
188 ; RV32I-NEXT:    addi sp, sp, -16
189 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
190 ; RV32I-NEXT:    call sqrt
191 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
192 ; RV32I-NEXT:    addi sp, sp, 16
193 ; RV32I-NEXT:    ret
195 ; RV64I-LABEL: fsqrt_d:
196 ; RV64I:       # %bb.0:
197 ; RV64I-NEXT:    addi sp, sp, -16
198 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
199 ; RV64I-NEXT:    call sqrt
200 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
201 ; RV64I-NEXT:    addi sp, sp, 16
202 ; RV64I-NEXT:    ret
203   %1 = call double @llvm.sqrt.f64(double %a)
204   ret double %1
207 declare double @llvm.copysign.f64(double, double)
209 define double @fsgnj_d(double %a, double %b) nounwind {
210 ; CHECKIFD-LABEL: fsgnj_d:
211 ; CHECKIFD:       # %bb.0:
212 ; CHECKIFD-NEXT:    fsgnj.d fa0, fa0, fa1
213 ; CHECKIFD-NEXT:    ret
215 ; RV32IZFINXZDINX-LABEL: fsgnj_d:
216 ; RV32IZFINXZDINX:       # %bb.0:
217 ; RV32IZFINXZDINX-NEXT:    fsgnj.d a0, a0, a2
218 ; RV32IZFINXZDINX-NEXT:    ret
220 ; RV64IZFINXZDINX-LABEL: fsgnj_d:
221 ; RV64IZFINXZDINX:       # %bb.0:
222 ; RV64IZFINXZDINX-NEXT:    fsgnj.d a0, a0, a1
223 ; RV64IZFINXZDINX-NEXT:    ret
225 ; RV32I-LABEL: fsgnj_d:
226 ; RV32I:       # %bb.0:
227 ; RV32I-NEXT:    lui a2, 524288
228 ; RV32I-NEXT:    and a2, a3, a2
229 ; RV32I-NEXT:    slli a1, a1, 1
230 ; RV32I-NEXT:    srli a1, a1, 1
231 ; RV32I-NEXT:    or a1, a1, a2
232 ; RV32I-NEXT:    ret
234 ; RV64I-LABEL: fsgnj_d:
235 ; RV64I:       # %bb.0:
236 ; RV64I-NEXT:    srli a1, a1, 63
237 ; RV64I-NEXT:    slli a1, a1, 63
238 ; RV64I-NEXT:    slli a0, a0, 1
239 ; RV64I-NEXT:    srli a0, a0, 1
240 ; RV64I-NEXT:    or a0, a0, a1
241 ; RV64I-NEXT:    ret
242   %1 = call double @llvm.copysign.f64(double %a, double %b)
243   ret double %1
246 ; This function performs extra work to ensure that
247 ; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
248 define i32 @fneg_d(double %a, double %b) nounwind {
249 ; CHECKIFD-LABEL: fneg_d:
250 ; CHECKIFD:       # %bb.0:
251 ; CHECKIFD-NEXT:    fadd.d fa5, fa0, fa0
252 ; CHECKIFD-NEXT:    fneg.d fa4, fa5
253 ; CHECKIFD-NEXT:    feq.d a0, fa5, fa4
254 ; CHECKIFD-NEXT:    ret
256 ; RV32IZFINXZDINX-LABEL: fneg_d:
257 ; RV32IZFINXZDINX:       # %bb.0:
258 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a0
259 ; RV32IZFINXZDINX-NEXT:    fneg.d a2, a0
260 ; RV32IZFINXZDINX-NEXT:    feq.d a0, a0, a2
261 ; RV32IZFINXZDINX-NEXT:    ret
263 ; RV64IZFINXZDINX-LABEL: fneg_d:
264 ; RV64IZFINXZDINX:       # %bb.0:
265 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, a0
266 ; RV64IZFINXZDINX-NEXT:    fneg.d a1, a0
267 ; RV64IZFINXZDINX-NEXT:    feq.d a0, a0, a1
268 ; RV64IZFINXZDINX-NEXT:    ret
270 ; RV32I-LABEL: fneg_d:
271 ; RV32I:       # %bb.0:
272 ; RV32I-NEXT:    addi sp, sp, -16
273 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
274 ; RV32I-NEXT:    mv a2, a0
275 ; RV32I-NEXT:    mv a3, a1
276 ; RV32I-NEXT:    call __adddf3
277 ; RV32I-NEXT:    lui a3, 524288
278 ; RV32I-NEXT:    xor a3, a1, a3
279 ; RV32I-NEXT:    mv a2, a0
280 ; RV32I-NEXT:    call __eqdf2
281 ; RV32I-NEXT:    seqz a0, a0
282 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
283 ; RV32I-NEXT:    addi sp, sp, 16
284 ; RV32I-NEXT:    ret
286 ; RV64I-LABEL: fneg_d:
287 ; RV64I:       # %bb.0:
288 ; RV64I-NEXT:    addi sp, sp, -16
289 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
290 ; RV64I-NEXT:    mv a1, a0
291 ; RV64I-NEXT:    call __adddf3
292 ; RV64I-NEXT:    li a1, -1
293 ; RV64I-NEXT:    slli a1, a1, 63
294 ; RV64I-NEXT:    xor a1, a0, a1
295 ; RV64I-NEXT:    call __eqdf2
296 ; RV64I-NEXT:    seqz a0, a0
297 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
298 ; RV64I-NEXT:    addi sp, sp, 16
299 ; RV64I-NEXT:    ret
300   %1 = fadd double %a, %a
301   %2 = fneg double %1
302   %3 = fcmp oeq double %1, %2
303   %4 = zext i1 %3 to i32
304   ret i32 %4
307 define double @fsgnjn_d(double %a, double %b) nounwind {
308 ; TODO: fsgnjn.s isn't selected on RV64 because DAGCombiner::visitBITCAST will
309 ; convert (bitconvert (fneg x)) to a xor.
311 ; CHECKIFD-LABEL: fsgnjn_d:
312 ; CHECKIFD:       # %bb.0:
313 ; CHECKIFD-NEXT:    fsgnjn.d fa0, fa0, fa1
314 ; CHECKIFD-NEXT:    ret
316 ; RV32IZFINXZDINX-LABEL: fsgnjn_d:
317 ; RV32IZFINXZDINX:       # %bb.0:
318 ; RV32IZFINXZDINX-NEXT:    fsgnjn.d a0, a0, a2
319 ; RV32IZFINXZDINX-NEXT:    ret
321 ; RV64IZFINXZDINX-LABEL: fsgnjn_d:
322 ; RV64IZFINXZDINX:       # %bb.0:
323 ; RV64IZFINXZDINX-NEXT:    not a1, a1
324 ; RV64IZFINXZDINX-NEXT:    fsgnj.d a0, a0, a1
325 ; RV64IZFINXZDINX-NEXT:    ret
327 ; RV32I-LABEL: fsgnjn_d:
328 ; RV32I:       # %bb.0:
329 ; RV32I-NEXT:    not a2, a3
330 ; RV32I-NEXT:    lui a3, 524288
331 ; RV32I-NEXT:    and a2, a2, a3
332 ; RV32I-NEXT:    slli a1, a1, 1
333 ; RV32I-NEXT:    srli a1, a1, 1
334 ; RV32I-NEXT:    or a1, a1, a2
335 ; RV32I-NEXT:    ret
337 ; RV64I-LABEL: fsgnjn_d:
338 ; RV64I:       # %bb.0:
339 ; RV64I-NEXT:    not a1, a1
340 ; RV64I-NEXT:    slli a0, a0, 1
341 ; RV64I-NEXT:    srli a0, a0, 1
342 ; RV64I-NEXT:    srli a1, a1, 63
343 ; RV64I-NEXT:    slli a1, a1, 63
344 ; RV64I-NEXT:    or a0, a0, a1
345 ; RV64I-NEXT:    ret
346   %1 = fsub double -0.0, %b
347   %2 = call double @llvm.copysign.f64(double %a, double %1)
348   ret double %2
351 declare double @llvm.fabs.f64(double)
353 ; This function performs extra work to ensure that
354 ; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
355 define double @fabs_d(double %a, double %b) nounwind {
356 ; CHECKIFD-LABEL: fabs_d:
357 ; CHECKIFD:       # %bb.0:
358 ; CHECKIFD-NEXT:    fadd.d fa5, fa0, fa1
359 ; CHECKIFD-NEXT:    fabs.d fa4, fa5
360 ; CHECKIFD-NEXT:    fadd.d fa0, fa4, fa5
361 ; CHECKIFD-NEXT:    ret
363 ; RV32IZFINXZDINX-LABEL: fabs_d:
364 ; RV32IZFINXZDINX:       # %bb.0:
365 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a2
366 ; RV32IZFINXZDINX-NEXT:    fabs.d a2, a0
367 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a2, a0
368 ; RV32IZFINXZDINX-NEXT:    ret
370 ; RV64IZFINXZDINX-LABEL: fabs_d:
371 ; RV64IZFINXZDINX:       # %bb.0:
372 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, a1
373 ; RV64IZFINXZDINX-NEXT:    fabs.d a1, a0
374 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a1, a0
375 ; RV64IZFINXZDINX-NEXT:    ret
377 ; RV32I-LABEL: fabs_d:
378 ; RV32I:       # %bb.0:
379 ; RV32I-NEXT:    addi sp, sp, -16
380 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
381 ; RV32I-NEXT:    call __adddf3
382 ; RV32I-NEXT:    mv a3, a1
383 ; RV32I-NEXT:    slli a1, a1, 1
384 ; RV32I-NEXT:    srli a1, a1, 1
385 ; RV32I-NEXT:    mv a2, a0
386 ; RV32I-NEXT:    call __adddf3
387 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
388 ; RV32I-NEXT:    addi sp, sp, 16
389 ; RV32I-NEXT:    ret
391 ; RV64I-LABEL: fabs_d:
392 ; RV64I:       # %bb.0:
393 ; RV64I-NEXT:    addi sp, sp, -16
394 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
395 ; RV64I-NEXT:    call __adddf3
396 ; RV64I-NEXT:    mv a1, a0
397 ; RV64I-NEXT:    slli a0, a0, 1
398 ; RV64I-NEXT:    srli a0, a0, 1
399 ; RV64I-NEXT:    call __adddf3
400 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
401 ; RV64I-NEXT:    addi sp, sp, 16
402 ; RV64I-NEXT:    ret
403   %1 = fadd double %a, %b
404   %2 = call double @llvm.fabs.f64(double %1)
405   %3 = fadd double %2, %1
406   ret double %3
409 declare double @llvm.minnum.f64(double, double)
411 define double @fmin_d(double %a, double %b) nounwind {
412 ; CHECKIFD-LABEL: fmin_d:
413 ; CHECKIFD:       # %bb.0:
414 ; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa1
415 ; CHECKIFD-NEXT:    ret
417 ; RV32IZFINXZDINX-LABEL: fmin_d:
418 ; RV32IZFINXZDINX:       # %bb.0:
419 ; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a2
420 ; RV32IZFINXZDINX-NEXT:    ret
422 ; RV64IZFINXZDINX-LABEL: fmin_d:
423 ; RV64IZFINXZDINX:       # %bb.0:
424 ; RV64IZFINXZDINX-NEXT:    fmin.d a0, a0, a1
425 ; RV64IZFINXZDINX-NEXT:    ret
427 ; RV32I-LABEL: fmin_d:
428 ; RV32I:       # %bb.0:
429 ; RV32I-NEXT:    addi sp, sp, -16
430 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
431 ; RV32I-NEXT:    call fmin
432 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
433 ; RV32I-NEXT:    addi sp, sp, 16
434 ; RV32I-NEXT:    ret
436 ; RV64I-LABEL: fmin_d:
437 ; RV64I:       # %bb.0:
438 ; RV64I-NEXT:    addi sp, sp, -16
439 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
440 ; RV64I-NEXT:    call fmin
441 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
442 ; RV64I-NEXT:    addi sp, sp, 16
443 ; RV64I-NEXT:    ret
444   %1 = call double @llvm.minnum.f64(double %a, double %b)
445   ret double %1
448 declare double @llvm.maxnum.f64(double, double)
450 define double @fmax_d(double %a, double %b) nounwind {
451 ; CHECKIFD-LABEL: fmax_d:
452 ; CHECKIFD:       # %bb.0:
453 ; CHECKIFD-NEXT:    fmax.d fa0, fa0, fa1
454 ; CHECKIFD-NEXT:    ret
456 ; RV32IZFINXZDINX-LABEL: fmax_d:
457 ; RV32IZFINXZDINX:       # %bb.0:
458 ; RV32IZFINXZDINX-NEXT:    fmax.d a0, a0, a2
459 ; RV32IZFINXZDINX-NEXT:    ret
461 ; RV64IZFINXZDINX-LABEL: fmax_d:
462 ; RV64IZFINXZDINX:       # %bb.0:
463 ; RV64IZFINXZDINX-NEXT:    fmax.d a0, a0, a1
464 ; RV64IZFINXZDINX-NEXT:    ret
466 ; RV32I-LABEL: fmax_d:
467 ; RV32I:       # %bb.0:
468 ; RV32I-NEXT:    addi sp, sp, -16
469 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
470 ; RV32I-NEXT:    call fmax
471 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
472 ; RV32I-NEXT:    addi sp, sp, 16
473 ; RV32I-NEXT:    ret
475 ; RV64I-LABEL: fmax_d:
476 ; RV64I:       # %bb.0:
477 ; RV64I-NEXT:    addi sp, sp, -16
478 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
479 ; RV64I-NEXT:    call fmax
480 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
481 ; RV64I-NEXT:    addi sp, sp, 16
482 ; RV64I-NEXT:    ret
483   %1 = call double @llvm.maxnum.f64(double %a, double %b)
484   ret double %1
487 declare double @llvm.fma.f64(double, double, double)
489 define double @fmadd_d(double %a, double %b, double %c) nounwind {
490 ; CHECKIFD-LABEL: fmadd_d:
491 ; CHECKIFD:       # %bb.0:
492 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
493 ; CHECKIFD-NEXT:    ret
495 ; RV32IZFINXZDINX-LABEL: fmadd_d:
496 ; RV32IZFINXZDINX:       # %bb.0:
497 ; RV32IZFINXZDINX-NEXT:    fmadd.d a0, a0, a2, a4
498 ; RV32IZFINXZDINX-NEXT:    ret
500 ; RV64IZFINXZDINX-LABEL: fmadd_d:
501 ; RV64IZFINXZDINX:       # %bb.0:
502 ; RV64IZFINXZDINX-NEXT:    fmadd.d a0, a0, a1, a2
503 ; RV64IZFINXZDINX-NEXT:    ret
505 ; RV32I-LABEL: fmadd_d:
506 ; RV32I:       # %bb.0:
507 ; RV32I-NEXT:    addi sp, sp, -16
508 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
509 ; RV32I-NEXT:    call fma
510 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
511 ; RV32I-NEXT:    addi sp, sp, 16
512 ; RV32I-NEXT:    ret
514 ; RV64I-LABEL: fmadd_d:
515 ; RV64I:       # %bb.0:
516 ; RV64I-NEXT:    addi sp, sp, -16
517 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
518 ; RV64I-NEXT:    call fma
519 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
520 ; RV64I-NEXT:    addi sp, sp, 16
521 ; RV64I-NEXT:    ret
522   %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
523   ret double %1
526 define double @fmsub_d(double %a, double %b, double %c) nounwind {
527 ; RV32IFD-LABEL: fmsub_d:
528 ; RV32IFD:       # %bb.0:
529 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
530 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
531 ; RV32IFD-NEXT:    fmsub.d fa0, fa0, fa1, fa5
532 ; RV32IFD-NEXT:    ret
534 ; RV64IFD-LABEL: fmsub_d:
535 ; RV64IFD:       # %bb.0:
536 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
537 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
538 ; RV64IFD-NEXT:    fmsub.d fa0, fa0, fa1, fa5
539 ; RV64IFD-NEXT:    ret
541 ; RV32IZFINXZDINX-LABEL: fmsub_d:
542 ; RV32IZFINXZDINX:       # %bb.0:
543 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
544 ; RV32IZFINXZDINX-NEXT:    fadd.d a4, a4, a6
545 ; RV32IZFINXZDINX-NEXT:    fmsub.d a0, a0, a2, a4
546 ; RV32IZFINXZDINX-NEXT:    ret
548 ; RV64IZFINXZDINX-LABEL: fmsub_d:
549 ; RV64IZFINXZDINX:       # %bb.0:
550 ; RV64IZFINXZDINX-NEXT:    fadd.d a2, a2, zero
551 ; RV64IZFINXZDINX-NEXT:    fmsub.d a0, a0, a1, a2
552 ; RV64IZFINXZDINX-NEXT:    ret
554 ; RV32I-LABEL: fmsub_d:
555 ; RV32I:       # %bb.0:
556 ; RV32I-NEXT:    addi sp, sp, -32
557 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
558 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
559 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
560 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
561 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
562 ; RV32I-NEXT:    mv s0, a3
563 ; RV32I-NEXT:    mv s1, a2
564 ; RV32I-NEXT:    mv s2, a1
565 ; RV32I-NEXT:    mv s3, a0
566 ; RV32I-NEXT:    mv a0, a4
567 ; RV32I-NEXT:    mv a1, a5
568 ; RV32I-NEXT:    li a2, 0
569 ; RV32I-NEXT:    li a3, 0
570 ; RV32I-NEXT:    call __adddf3
571 ; RV32I-NEXT:    mv a4, a0
572 ; RV32I-NEXT:    lui a5, 524288
573 ; RV32I-NEXT:    xor a5, a1, a5
574 ; RV32I-NEXT:    mv a0, s3
575 ; RV32I-NEXT:    mv a1, s2
576 ; RV32I-NEXT:    mv a2, s1
577 ; RV32I-NEXT:    mv a3, s0
578 ; RV32I-NEXT:    call fma
579 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
580 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
581 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
582 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
583 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
584 ; RV32I-NEXT:    addi sp, sp, 32
585 ; RV32I-NEXT:    ret
587 ; RV64I-LABEL: fmsub_d:
588 ; RV64I:       # %bb.0:
589 ; RV64I-NEXT:    addi sp, sp, -32
590 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
591 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
592 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
593 ; RV64I-NEXT:    mv s0, a1
594 ; RV64I-NEXT:    mv s1, a0
595 ; RV64I-NEXT:    mv a0, a2
596 ; RV64I-NEXT:    li a1, 0
597 ; RV64I-NEXT:    call __adddf3
598 ; RV64I-NEXT:    li a1, -1
599 ; RV64I-NEXT:    slli a1, a1, 63
600 ; RV64I-NEXT:    xor a2, a0, a1
601 ; RV64I-NEXT:    mv a0, s1
602 ; RV64I-NEXT:    mv a1, s0
603 ; RV64I-NEXT:    call fma
604 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
605 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
606 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
607 ; RV64I-NEXT:    addi sp, sp, 32
608 ; RV64I-NEXT:    ret
609   %c_ = fadd double 0.0, %c ; avoid negation using xor
610   %negc = fsub double -0.0, %c_
611   %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
612   ret double %1
615 define double @fnmadd_d(double %a, double %b, double %c) nounwind {
616 ; RV32IFD-LABEL: fnmadd_d:
617 ; RV32IFD:       # %bb.0:
618 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
619 ; RV32IFD-NEXT:    fadd.d fa4, fa0, fa5
620 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
621 ; RV32IFD-NEXT:    fnmadd.d fa0, fa4, fa1, fa5
622 ; RV32IFD-NEXT:    ret
624 ; RV64IFD-LABEL: fnmadd_d:
625 ; RV64IFD:       # %bb.0:
626 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
627 ; RV64IFD-NEXT:    fadd.d fa4, fa0, fa5
628 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
629 ; RV64IFD-NEXT:    fnmadd.d fa0, fa4, fa1, fa5
630 ; RV64IFD-NEXT:    ret
632 ; RV32IZFINXZDINX-LABEL: fnmadd_d:
633 ; RV32IZFINXZDINX:       # %bb.0:
634 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
635 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a6
636 ; RV32IZFINXZDINX-NEXT:    fadd.d a4, a4, a6
637 ; RV32IZFINXZDINX-NEXT:    fnmadd.d a0, a0, a2, a4
638 ; RV32IZFINXZDINX-NEXT:    ret
640 ; RV64IZFINXZDINX-LABEL: fnmadd_d:
641 ; RV64IZFINXZDINX:       # %bb.0:
642 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, zero
643 ; RV64IZFINXZDINX-NEXT:    fadd.d a2, a2, zero
644 ; RV64IZFINXZDINX-NEXT:    fnmadd.d a0, a0, a1, a2
645 ; RV64IZFINXZDINX-NEXT:    ret
647 ; RV32I-LABEL: fnmadd_d:
648 ; RV32I:       # %bb.0:
649 ; RV32I-NEXT:    addi sp, sp, -32
650 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
651 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
652 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
653 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
654 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
655 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
656 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
657 ; RV32I-NEXT:    mv s0, a5
658 ; RV32I-NEXT:    mv s1, a4
659 ; RV32I-NEXT:    mv s2, a3
660 ; RV32I-NEXT:    mv s3, a2
661 ; RV32I-NEXT:    li a2, 0
662 ; RV32I-NEXT:    li a3, 0
663 ; RV32I-NEXT:    call __adddf3
664 ; RV32I-NEXT:    mv s4, a0
665 ; RV32I-NEXT:    mv s5, a1
666 ; RV32I-NEXT:    mv a0, s1
667 ; RV32I-NEXT:    mv a1, s0
668 ; RV32I-NEXT:    li a2, 0
669 ; RV32I-NEXT:    li a3, 0
670 ; RV32I-NEXT:    call __adddf3
671 ; RV32I-NEXT:    mv a4, a0
672 ; RV32I-NEXT:    lui a5, 524288
673 ; RV32I-NEXT:    xor a2, s5, a5
674 ; RV32I-NEXT:    xor a5, a1, a5
675 ; RV32I-NEXT:    mv a0, s4
676 ; RV32I-NEXT:    mv a1, a2
677 ; RV32I-NEXT:    mv a2, s3
678 ; RV32I-NEXT:    mv a3, s2
679 ; RV32I-NEXT:    call fma
680 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
681 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
682 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
683 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
684 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
685 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
686 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
687 ; RV32I-NEXT:    addi sp, sp, 32
688 ; RV32I-NEXT:    ret
690 ; RV64I-LABEL: fnmadd_d:
691 ; RV64I:       # %bb.0:
692 ; RV64I-NEXT:    addi sp, sp, -32
693 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
694 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
695 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
696 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
697 ; RV64I-NEXT:    mv s0, a2
698 ; RV64I-NEXT:    mv s1, a1
699 ; RV64I-NEXT:    li a1, 0
700 ; RV64I-NEXT:    call __adddf3
701 ; RV64I-NEXT:    mv s2, a0
702 ; RV64I-NEXT:    mv a0, s0
703 ; RV64I-NEXT:    li a1, 0
704 ; RV64I-NEXT:    call __adddf3
705 ; RV64I-NEXT:    li a1, -1
706 ; RV64I-NEXT:    slli a2, a1, 63
707 ; RV64I-NEXT:    xor a1, s2, a2
708 ; RV64I-NEXT:    xor a2, a0, a2
709 ; RV64I-NEXT:    mv a0, a1
710 ; RV64I-NEXT:    mv a1, s1
711 ; RV64I-NEXT:    call fma
712 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
713 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
714 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
715 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
716 ; RV64I-NEXT:    addi sp, sp, 32
717 ; RV64I-NEXT:    ret
718   %a_ = fadd double 0.0, %a
719   %c_ = fadd double 0.0, %c
720   %nega = fsub double -0.0, %a_
721   %negc = fsub double -0.0, %c_
722   %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
723   ret double %1
726 define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
727 ; RV32IFD-LABEL: fnmadd_d_2:
728 ; RV32IFD:       # %bb.0:
729 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
730 ; RV32IFD-NEXT:    fadd.d fa4, fa1, fa5
731 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
732 ; RV32IFD-NEXT:    fnmadd.d fa0, fa4, fa0, fa5
733 ; RV32IFD-NEXT:    ret
735 ; RV64IFD-LABEL: fnmadd_d_2:
736 ; RV64IFD:       # %bb.0:
737 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
738 ; RV64IFD-NEXT:    fadd.d fa4, fa1, fa5
739 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
740 ; RV64IFD-NEXT:    fnmadd.d fa0, fa4, fa0, fa5
741 ; RV64IFD-NEXT:    ret
743 ; RV32IZFINXZDINX-LABEL: fnmadd_d_2:
744 ; RV32IZFINXZDINX:       # %bb.0:
745 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
746 ; RV32IZFINXZDINX-NEXT:    fadd.d a2, a2, a6
747 ; RV32IZFINXZDINX-NEXT:    fadd.d a4, a4, a6
748 ; RV32IZFINXZDINX-NEXT:    fnmadd.d a0, a2, a0, a4
749 ; RV32IZFINXZDINX-NEXT:    ret
751 ; RV64IZFINXZDINX-LABEL: fnmadd_d_2:
752 ; RV64IZFINXZDINX:       # %bb.0:
753 ; RV64IZFINXZDINX-NEXT:    fadd.d a1, a1, zero
754 ; RV64IZFINXZDINX-NEXT:    fadd.d a2, a2, zero
755 ; RV64IZFINXZDINX-NEXT:    fnmadd.d a0, a1, a0, a2
756 ; RV64IZFINXZDINX-NEXT:    ret
758 ; RV32I-LABEL: fnmadd_d_2:
759 ; RV32I:       # %bb.0:
760 ; RV32I-NEXT:    addi sp, sp, -32
761 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
762 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
763 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
764 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
765 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
766 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
767 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
768 ; RV32I-NEXT:    mv s0, a5
769 ; RV32I-NEXT:    mv s1, a4
770 ; RV32I-NEXT:    mv s2, a1
771 ; RV32I-NEXT:    mv s3, a0
772 ; RV32I-NEXT:    mv a0, a2
773 ; RV32I-NEXT:    mv a1, a3
774 ; RV32I-NEXT:    li a2, 0
775 ; RV32I-NEXT:    li a3, 0
776 ; RV32I-NEXT:    call __adddf3
777 ; RV32I-NEXT:    mv s4, a0
778 ; RV32I-NEXT:    mv s5, a1
779 ; RV32I-NEXT:    mv a0, s1
780 ; RV32I-NEXT:    mv a1, s0
781 ; RV32I-NEXT:    li a2, 0
782 ; RV32I-NEXT:    li a3, 0
783 ; RV32I-NEXT:    call __adddf3
784 ; RV32I-NEXT:    mv a4, a0
785 ; RV32I-NEXT:    lui a5, 524288
786 ; RV32I-NEXT:    xor a3, s5, a5
787 ; RV32I-NEXT:    xor a5, a1, a5
788 ; RV32I-NEXT:    mv a0, s3
789 ; RV32I-NEXT:    mv a1, s2
790 ; RV32I-NEXT:    mv a2, s4
791 ; RV32I-NEXT:    call fma
792 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
793 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
794 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
795 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
796 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
797 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
798 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
799 ; RV32I-NEXT:    addi sp, sp, 32
800 ; RV32I-NEXT:    ret
802 ; RV64I-LABEL: fnmadd_d_2:
803 ; RV64I:       # %bb.0:
804 ; RV64I-NEXT:    addi sp, sp, -32
805 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
806 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
807 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
808 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
809 ; RV64I-NEXT:    mv s0, a2
810 ; RV64I-NEXT:    mv s1, a0
811 ; RV64I-NEXT:    mv a0, a1
812 ; RV64I-NEXT:    li a1, 0
813 ; RV64I-NEXT:    call __adddf3
814 ; RV64I-NEXT:    mv s2, a0
815 ; RV64I-NEXT:    mv a0, s0
816 ; RV64I-NEXT:    li a1, 0
817 ; RV64I-NEXT:    call __adddf3
818 ; RV64I-NEXT:    li a1, -1
819 ; RV64I-NEXT:    slli a2, a1, 63
820 ; RV64I-NEXT:    xor a1, s2, a2
821 ; RV64I-NEXT:    xor a2, a0, a2
822 ; RV64I-NEXT:    mv a0, s1
823 ; RV64I-NEXT:    call fma
824 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
825 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
826 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
827 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
828 ; RV64I-NEXT:    addi sp, sp, 32
829 ; RV64I-NEXT:    ret
830   %b_ = fadd double 0.0, %b
831   %c_ = fadd double 0.0, %c
832   %negb = fsub double -0.0, %b_
833   %negc = fsub double -0.0, %c_
834   %1 = call double @llvm.fma.f64(double %a, double %negb, double %negc)
835   ret double %1
838 define double @fnmadd_d_3(double %a, double %b, double %c) nounwind {
839 ; CHECKIFD-LABEL: fnmadd_d_3:
840 ; CHECKIFD:       # %bb.0:
841 ; CHECKIFD-NEXT:    fmadd.d fa5, fa0, fa1, fa2
842 ; CHECKIFD-NEXT:    fneg.d fa0, fa5
843 ; CHECKIFD-NEXT:    ret
845 ; RV32IZFINXZDINX-LABEL: fnmadd_d_3:
846 ; RV32IZFINXZDINX:       # %bb.0:
847 ; RV32IZFINXZDINX-NEXT:    fmadd.d a0, a0, a2, a4
848 ; RV32IZFINXZDINX-NEXT:    lui a2, 524288
849 ; RV32IZFINXZDINX-NEXT:    xor a1, a1, a2
850 ; RV32IZFINXZDINX-NEXT:    ret
852 ; RV64IZFINXZDINX-LABEL: fnmadd_d_3:
853 ; RV64IZFINXZDINX:       # %bb.0:
854 ; RV64IZFINXZDINX-NEXT:    fmadd.d a0, a0, a1, a2
855 ; RV64IZFINXZDINX-NEXT:    li a1, -1
856 ; RV64IZFINXZDINX-NEXT:    slli a1, a1, 63
857 ; RV64IZFINXZDINX-NEXT:    xor a0, a0, a1
858 ; RV64IZFINXZDINX-NEXT:    ret
860 ; RV32I-LABEL: fnmadd_d_3:
861 ; RV32I:       # %bb.0:
862 ; RV32I-NEXT:    addi sp, sp, -16
863 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
864 ; RV32I-NEXT:    call fma
865 ; RV32I-NEXT:    lui a2, 524288
866 ; RV32I-NEXT:    xor a1, a1, a2
867 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
868 ; RV32I-NEXT:    addi sp, sp, 16
869 ; RV32I-NEXT:    ret
871 ; RV64I-LABEL: fnmadd_d_3:
872 ; RV64I:       # %bb.0:
873 ; RV64I-NEXT:    addi sp, sp, -16
874 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
875 ; RV64I-NEXT:    call fma
876 ; RV64I-NEXT:    li a1, -1
877 ; RV64I-NEXT:    slli a1, a1, 63
878 ; RV64I-NEXT:    xor a0, a0, a1
879 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
880 ; RV64I-NEXT:    addi sp, sp, 16
881 ; RV64I-NEXT:    ret
882   %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
883   %neg = fneg double %1
884   ret double %neg
888 define double @fnmadd_nsz(double %a, double %b, double %c) nounwind {
889 ; CHECKIFD-LABEL: fnmadd_nsz:
890 ; CHECKIFD:       # %bb.0:
891 ; CHECKIFD-NEXT:    fnmadd.d fa0, fa0, fa1, fa2
892 ; CHECKIFD-NEXT:    ret
894 ; RV32IZFINXZDINX-LABEL: fnmadd_nsz:
895 ; RV32IZFINXZDINX:       # %bb.0:
896 ; RV32IZFINXZDINX-NEXT:    fmadd.d a0, a0, a2, a4
897 ; RV32IZFINXZDINX-NEXT:    lui a2, 524288
898 ; RV32IZFINXZDINX-NEXT:    xor a1, a1, a2
899 ; RV32IZFINXZDINX-NEXT:    ret
901 ; RV64IZFINXZDINX-LABEL: fnmadd_nsz:
902 ; RV64IZFINXZDINX:       # %bb.0:
903 ; RV64IZFINXZDINX-NEXT:    fmadd.d a0, a0, a1, a2
904 ; RV64IZFINXZDINX-NEXT:    li a1, -1
905 ; RV64IZFINXZDINX-NEXT:    slli a1, a1, 63
906 ; RV64IZFINXZDINX-NEXT:    xor a0, a0, a1
907 ; RV64IZFINXZDINX-NEXT:    ret
909 ; RV32I-LABEL: fnmadd_nsz:
910 ; RV32I:       # %bb.0:
911 ; RV32I-NEXT:    addi sp, sp, -16
912 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
913 ; RV32I-NEXT:    call fma
914 ; RV32I-NEXT:    lui a2, 524288
915 ; RV32I-NEXT:    xor a1, a1, a2
916 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
917 ; RV32I-NEXT:    addi sp, sp, 16
918 ; RV32I-NEXT:    ret
920 ; RV64I-LABEL: fnmadd_nsz:
921 ; RV64I:       # %bb.0:
922 ; RV64I-NEXT:    addi sp, sp, -16
923 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
924 ; RV64I-NEXT:    call fma
925 ; RV64I-NEXT:    li a1, -1
926 ; RV64I-NEXT:    slli a1, a1, 63
927 ; RV64I-NEXT:    xor a0, a0, a1
928 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
929 ; RV64I-NEXT:    addi sp, sp, 16
930 ; RV64I-NEXT:    ret
931   %1 = call nsz double @llvm.fma.f64(double %a, double %b, double %c)
932   %neg = fneg nsz double %1
933   ret double %neg
936 define double @fnmsub_d(double %a, double %b, double %c) nounwind {
937 ; RV32IFD-LABEL: fnmsub_d:
938 ; RV32IFD:       # %bb.0:
939 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
940 ; RV32IFD-NEXT:    fadd.d fa5, fa0, fa5
941 ; RV32IFD-NEXT:    fnmsub.d fa0, fa5, fa1, fa2
942 ; RV32IFD-NEXT:    ret
944 ; RV64IFD-LABEL: fnmsub_d:
945 ; RV64IFD:       # %bb.0:
946 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
947 ; RV64IFD-NEXT:    fadd.d fa5, fa0, fa5
948 ; RV64IFD-NEXT:    fnmsub.d fa0, fa5, fa1, fa2
949 ; RV64IFD-NEXT:    ret
951 ; RV32IZFINXZDINX-LABEL: fnmsub_d:
952 ; RV32IZFINXZDINX:       # %bb.0:
953 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
954 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a6
955 ; RV32IZFINXZDINX-NEXT:    fnmsub.d a0, a0, a2, a4
956 ; RV32IZFINXZDINX-NEXT:    ret
958 ; RV64IZFINXZDINX-LABEL: fnmsub_d:
959 ; RV64IZFINXZDINX:       # %bb.0:
960 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, zero
961 ; RV64IZFINXZDINX-NEXT:    fnmsub.d a0, a0, a1, a2
962 ; RV64IZFINXZDINX-NEXT:    ret
964 ; RV32I-LABEL: fnmsub_d:
965 ; RV32I:       # %bb.0:
966 ; RV32I-NEXT:    addi sp, sp, -32
967 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
968 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
969 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
970 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
971 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
972 ; RV32I-NEXT:    mv s0, a5
973 ; RV32I-NEXT:    mv s1, a4
974 ; RV32I-NEXT:    mv s2, a3
975 ; RV32I-NEXT:    mv s3, a2
976 ; RV32I-NEXT:    li a2, 0
977 ; RV32I-NEXT:    li a3, 0
978 ; RV32I-NEXT:    call __adddf3
979 ; RV32I-NEXT:    lui a2, 524288
980 ; RV32I-NEXT:    xor a1, a1, a2
981 ; RV32I-NEXT:    mv a2, s3
982 ; RV32I-NEXT:    mv a3, s2
983 ; RV32I-NEXT:    mv a4, s1
984 ; RV32I-NEXT:    mv a5, s0
985 ; RV32I-NEXT:    call fma
986 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
987 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
988 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
989 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
990 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
991 ; RV32I-NEXT:    addi sp, sp, 32
992 ; RV32I-NEXT:    ret
994 ; RV64I-LABEL: fnmsub_d:
995 ; RV64I:       # %bb.0:
996 ; RV64I-NEXT:    addi sp, sp, -32
997 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
998 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
999 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1000 ; RV64I-NEXT:    mv s0, a2
1001 ; RV64I-NEXT:    mv s1, a1
1002 ; RV64I-NEXT:    li a1, 0
1003 ; RV64I-NEXT:    call __adddf3
1004 ; RV64I-NEXT:    li a1, -1
1005 ; RV64I-NEXT:    slli a1, a1, 63
1006 ; RV64I-NEXT:    xor a0, a0, a1
1007 ; RV64I-NEXT:    mv a1, s1
1008 ; RV64I-NEXT:    mv a2, s0
1009 ; RV64I-NEXT:    call fma
1010 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1011 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1012 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1013 ; RV64I-NEXT:    addi sp, sp, 32
1014 ; RV64I-NEXT:    ret
1015   %a_ = fadd double 0.0, %a
1016   %nega = fsub double -0.0, %a_
1017   %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
1018   ret double %1
1021 define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
1022 ; RV32IFD-LABEL: fnmsub_d_2:
1023 ; RV32IFD:       # %bb.0:
1024 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
1025 ; RV32IFD-NEXT:    fadd.d fa5, fa1, fa5
1026 ; RV32IFD-NEXT:    fnmsub.d fa0, fa5, fa0, fa2
1027 ; RV32IFD-NEXT:    ret
1029 ; RV64IFD-LABEL: fnmsub_d_2:
1030 ; RV64IFD:       # %bb.0:
1031 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
1032 ; RV64IFD-NEXT:    fadd.d fa5, fa1, fa5
1033 ; RV64IFD-NEXT:    fnmsub.d fa0, fa5, fa0, fa2
1034 ; RV64IFD-NEXT:    ret
1036 ; RV32IZFINXZDINX-LABEL: fnmsub_d_2:
1037 ; RV32IZFINXZDINX:       # %bb.0:
1038 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
1039 ; RV32IZFINXZDINX-NEXT:    fadd.d a2, a2, a6
1040 ; RV32IZFINXZDINX-NEXT:    fnmsub.d a0, a2, a0, a4
1041 ; RV32IZFINXZDINX-NEXT:    ret
1043 ; RV64IZFINXZDINX-LABEL: fnmsub_d_2:
1044 ; RV64IZFINXZDINX:       # %bb.0:
1045 ; RV64IZFINXZDINX-NEXT:    fadd.d a1, a1, zero
1046 ; RV64IZFINXZDINX-NEXT:    fnmsub.d a0, a1, a0, a2
1047 ; RV64IZFINXZDINX-NEXT:    ret
1049 ; RV32I-LABEL: fnmsub_d_2:
1050 ; RV32I:       # %bb.0:
1051 ; RV32I-NEXT:    addi sp, sp, -32
1052 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1053 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1054 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1055 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1056 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1057 ; RV32I-NEXT:    mv s0, a5
1058 ; RV32I-NEXT:    mv s1, a4
1059 ; RV32I-NEXT:    mv s2, a1
1060 ; RV32I-NEXT:    mv s3, a0
1061 ; RV32I-NEXT:    mv a0, a2
1062 ; RV32I-NEXT:    mv a1, a3
1063 ; RV32I-NEXT:    li a2, 0
1064 ; RV32I-NEXT:    li a3, 0
1065 ; RV32I-NEXT:    call __adddf3
1066 ; RV32I-NEXT:    mv a2, a0
1067 ; RV32I-NEXT:    lui a3, 524288
1068 ; RV32I-NEXT:    xor a3, a1, a3
1069 ; RV32I-NEXT:    mv a0, s3
1070 ; RV32I-NEXT:    mv a1, s2
1071 ; RV32I-NEXT:    mv a4, s1
1072 ; RV32I-NEXT:    mv a5, s0
1073 ; RV32I-NEXT:    call fma
1074 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1075 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1076 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1077 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1078 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1079 ; RV32I-NEXT:    addi sp, sp, 32
1080 ; RV32I-NEXT:    ret
1082 ; RV64I-LABEL: fnmsub_d_2:
1083 ; RV64I:       # %bb.0:
1084 ; RV64I-NEXT:    addi sp, sp, -32
1085 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1086 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1087 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1088 ; RV64I-NEXT:    mv s0, a2
1089 ; RV64I-NEXT:    mv s1, a0
1090 ; RV64I-NEXT:    mv a0, a1
1091 ; RV64I-NEXT:    li a1, 0
1092 ; RV64I-NEXT:    call __adddf3
1093 ; RV64I-NEXT:    li a1, -1
1094 ; RV64I-NEXT:    slli a1, a1, 63
1095 ; RV64I-NEXT:    xor a1, a0, a1
1096 ; RV64I-NEXT:    mv a0, s1
1097 ; RV64I-NEXT:    mv a2, s0
1098 ; RV64I-NEXT:    call fma
1099 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1100 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1101 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1102 ; RV64I-NEXT:    addi sp, sp, 32
1103 ; RV64I-NEXT:    ret
1104   %b_ = fadd double 0.0, %b
1105   %negb = fsub double -0.0, %b_
1106   %1 = call double @llvm.fma.f64(double %a, double %negb, double %c)
1107   ret double %1
1110 define double @fmadd_d_contract(double %a, double %b, double %c) nounwind {
1111 ; CHECKIFD-LABEL: fmadd_d_contract:
1112 ; CHECKIFD:       # %bb.0:
1113 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
1114 ; CHECKIFD-NEXT:    ret
1116 ; RV32IZFINXZDINX-LABEL: fmadd_d_contract:
1117 ; RV32IZFINXZDINX:       # %bb.0:
1118 ; RV32IZFINXZDINX-NEXT:    fmadd.d a0, a0, a2, a4
1119 ; RV32IZFINXZDINX-NEXT:    ret
1121 ; RV64IZFINXZDINX-LABEL: fmadd_d_contract:
1122 ; RV64IZFINXZDINX:       # %bb.0:
1123 ; RV64IZFINXZDINX-NEXT:    fmadd.d a0, a0, a1, a2
1124 ; RV64IZFINXZDINX-NEXT:    ret
1126 ; RV32I-LABEL: fmadd_d_contract:
1127 ; RV32I:       # %bb.0:
1128 ; RV32I-NEXT:    addi sp, sp, -16
1129 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1130 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
1131 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
1132 ; RV32I-NEXT:    mv s0, a5
1133 ; RV32I-NEXT:    mv s1, a4
1134 ; RV32I-NEXT:    call __muldf3
1135 ; RV32I-NEXT:    mv a2, s1
1136 ; RV32I-NEXT:    mv a3, s0
1137 ; RV32I-NEXT:    call __adddf3
1138 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1139 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1140 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1141 ; RV32I-NEXT:    addi sp, sp, 16
1142 ; RV32I-NEXT:    ret
1144 ; RV64I-LABEL: fmadd_d_contract:
1145 ; RV64I:       # %bb.0:
1146 ; RV64I-NEXT:    addi sp, sp, -16
1147 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1148 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
1149 ; RV64I-NEXT:    mv s0, a2
1150 ; RV64I-NEXT:    call __muldf3
1151 ; RV64I-NEXT:    mv a1, s0
1152 ; RV64I-NEXT:    call __adddf3
1153 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1154 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
1155 ; RV64I-NEXT:    addi sp, sp, 16
1156 ; RV64I-NEXT:    ret
1157   %1 = fmul contract double %a, %b
1158   %2 = fadd contract double %1, %c
1159   ret double %2
1162 define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
1163 ; RV32IFD-LABEL: fmsub_d_contract:
1164 ; RV32IFD:       # %bb.0:
1165 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
1166 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
1167 ; RV32IFD-NEXT:    fmsub.d fa0, fa0, fa1, fa5
1168 ; RV32IFD-NEXT:    ret
1170 ; RV64IFD-LABEL: fmsub_d_contract:
1171 ; RV64IFD:       # %bb.0:
1172 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
1173 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
1174 ; RV64IFD-NEXT:    fmsub.d fa0, fa0, fa1, fa5
1175 ; RV64IFD-NEXT:    ret
1177 ; RV32IZFINXZDINX-LABEL: fmsub_d_contract:
1178 ; RV32IZFINXZDINX:       # %bb.0:
1179 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
1180 ; RV32IZFINXZDINX-NEXT:    fadd.d a4, a4, a6
1181 ; RV32IZFINXZDINX-NEXT:    fmsub.d a0, a0, a2, a4
1182 ; RV32IZFINXZDINX-NEXT:    ret
1184 ; RV64IZFINXZDINX-LABEL: fmsub_d_contract:
1185 ; RV64IZFINXZDINX:       # %bb.0:
1186 ; RV64IZFINXZDINX-NEXT:    fadd.d a2, a2, zero
1187 ; RV64IZFINXZDINX-NEXT:    fmsub.d a0, a0, a1, a2
1188 ; RV64IZFINXZDINX-NEXT:    ret
1190 ; RV32I-LABEL: fmsub_d_contract:
1191 ; RV32I:       # %bb.0:
1192 ; RV32I-NEXT:    addi sp, sp, -32
1193 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1194 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1195 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1196 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1197 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1198 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1199 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
1200 ; RV32I-NEXT:    mv s0, a3
1201 ; RV32I-NEXT:    mv s1, a2
1202 ; RV32I-NEXT:    mv s2, a1
1203 ; RV32I-NEXT:    mv s3, a0
1204 ; RV32I-NEXT:    mv a0, a4
1205 ; RV32I-NEXT:    mv a1, a5
1206 ; RV32I-NEXT:    li a2, 0
1207 ; RV32I-NEXT:    li a3, 0
1208 ; RV32I-NEXT:    call __adddf3
1209 ; RV32I-NEXT:    mv s4, a0
1210 ; RV32I-NEXT:    mv s5, a1
1211 ; RV32I-NEXT:    mv a0, s3
1212 ; RV32I-NEXT:    mv a1, s2
1213 ; RV32I-NEXT:    mv a2, s1
1214 ; RV32I-NEXT:    mv a3, s0
1215 ; RV32I-NEXT:    call __muldf3
1216 ; RV32I-NEXT:    mv a2, s4
1217 ; RV32I-NEXT:    mv a3, s5
1218 ; RV32I-NEXT:    call __subdf3
1219 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1220 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1221 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1222 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1223 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1224 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1225 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
1226 ; RV32I-NEXT:    addi sp, sp, 32
1227 ; RV32I-NEXT:    ret
1229 ; RV64I-LABEL: fmsub_d_contract:
1230 ; RV64I:       # %bb.0:
1231 ; RV64I-NEXT:    addi sp, sp, -32
1232 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1233 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1234 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1235 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1236 ; RV64I-NEXT:    mv s0, a1
1237 ; RV64I-NEXT:    mv s1, a0
1238 ; RV64I-NEXT:    mv a0, a2
1239 ; RV64I-NEXT:    li a1, 0
1240 ; RV64I-NEXT:    call __adddf3
1241 ; RV64I-NEXT:    mv s2, a0
1242 ; RV64I-NEXT:    mv a0, s1
1243 ; RV64I-NEXT:    mv a1, s0
1244 ; RV64I-NEXT:    call __muldf3
1245 ; RV64I-NEXT:    mv a1, s2
1246 ; RV64I-NEXT:    call __subdf3
1247 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1248 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1249 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1250 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1251 ; RV64I-NEXT:    addi sp, sp, 32
1252 ; RV64I-NEXT:    ret
1253   %c_ = fadd double 0.0, %c ; avoid negation using xor
1254   %1 = fmul contract double %a, %b
1255   %2 = fsub contract double %1, %c_
1256   ret double %2
1259 define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
1260 ; RV32IFD-LABEL: fnmadd_d_contract:
1261 ; RV32IFD:       # %bb.0:
1262 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
1263 ; RV32IFD-NEXT:    fadd.d fa4, fa0, fa5
1264 ; RV32IFD-NEXT:    fadd.d fa3, fa1, fa5
1265 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
1266 ; RV32IFD-NEXT:    fnmadd.d fa0, fa4, fa3, fa5
1267 ; RV32IFD-NEXT:    ret
1269 ; RV64IFD-LABEL: fnmadd_d_contract:
1270 ; RV64IFD:       # %bb.0:
1271 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
1272 ; RV64IFD-NEXT:    fadd.d fa4, fa0, fa5
1273 ; RV64IFD-NEXT:    fadd.d fa3, fa1, fa5
1274 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
1275 ; RV64IFD-NEXT:    fnmadd.d fa0, fa4, fa3, fa5
1276 ; RV64IFD-NEXT:    ret
1278 ; RV32IZFINXZDINX-LABEL: fnmadd_d_contract:
1279 ; RV32IZFINXZDINX:       # %bb.0:
1280 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
1281 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a6
1282 ; RV32IZFINXZDINX-NEXT:    fadd.d a2, a2, a6
1283 ; RV32IZFINXZDINX-NEXT:    fadd.d a4, a4, a6
1284 ; RV32IZFINXZDINX-NEXT:    fnmadd.d a0, a0, a2, a4
1285 ; RV32IZFINXZDINX-NEXT:    ret
1287 ; RV64IZFINXZDINX-LABEL: fnmadd_d_contract:
1288 ; RV64IZFINXZDINX:       # %bb.0:
1289 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, zero
1290 ; RV64IZFINXZDINX-NEXT:    fadd.d a1, a1, zero
1291 ; RV64IZFINXZDINX-NEXT:    fadd.d a2, a2, zero
1292 ; RV64IZFINXZDINX-NEXT:    fnmadd.d a0, a0, a1, a2
1293 ; RV64IZFINXZDINX-NEXT:    ret
1295 ; RV32I-LABEL: fnmadd_d_contract:
1296 ; RV32I:       # %bb.0:
1297 ; RV32I-NEXT:    addi sp, sp, -32
1298 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1299 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1300 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1301 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1302 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1303 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1304 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
1305 ; RV32I-NEXT:    mv s0, a5
1306 ; RV32I-NEXT:    mv s1, a4
1307 ; RV32I-NEXT:    mv s2, a3
1308 ; RV32I-NEXT:    mv s3, a2
1309 ; RV32I-NEXT:    li a2, 0
1310 ; RV32I-NEXT:    li a3, 0
1311 ; RV32I-NEXT:    call __adddf3
1312 ; RV32I-NEXT:    mv s4, a0
1313 ; RV32I-NEXT:    mv s5, a1
1314 ; RV32I-NEXT:    mv a0, s3
1315 ; RV32I-NEXT:    mv a1, s2
1316 ; RV32I-NEXT:    li a2, 0
1317 ; RV32I-NEXT:    li a3, 0
1318 ; RV32I-NEXT:    call __adddf3
1319 ; RV32I-NEXT:    mv s2, a0
1320 ; RV32I-NEXT:    mv s3, a1
1321 ; RV32I-NEXT:    mv a0, s1
1322 ; RV32I-NEXT:    mv a1, s0
1323 ; RV32I-NEXT:    li a2, 0
1324 ; RV32I-NEXT:    li a3, 0
1325 ; RV32I-NEXT:    call __adddf3
1326 ; RV32I-NEXT:    mv s0, a0
1327 ; RV32I-NEXT:    mv s1, a1
1328 ; RV32I-NEXT:    mv a0, s4
1329 ; RV32I-NEXT:    mv a1, s5
1330 ; RV32I-NEXT:    mv a2, s2
1331 ; RV32I-NEXT:    mv a3, s3
1332 ; RV32I-NEXT:    call __muldf3
1333 ; RV32I-NEXT:    lui a2, 524288
1334 ; RV32I-NEXT:    xor a1, a1, a2
1335 ; RV32I-NEXT:    mv a2, s0
1336 ; RV32I-NEXT:    mv a3, s1
1337 ; RV32I-NEXT:    call __subdf3
1338 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1339 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1340 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1341 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1342 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1343 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1344 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
1345 ; RV32I-NEXT:    addi sp, sp, 32
1346 ; RV32I-NEXT:    ret
1348 ; RV64I-LABEL: fnmadd_d_contract:
1349 ; RV64I:       # %bb.0:
1350 ; RV64I-NEXT:    addi sp, sp, -32
1351 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1352 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1353 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1354 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1355 ; RV64I-NEXT:    mv s0, a2
1356 ; RV64I-NEXT:    mv s1, a1
1357 ; RV64I-NEXT:    li a1, 0
1358 ; RV64I-NEXT:    call __adddf3
1359 ; RV64I-NEXT:    mv s2, a0
1360 ; RV64I-NEXT:    mv a0, s1
1361 ; RV64I-NEXT:    li a1, 0
1362 ; RV64I-NEXT:    call __adddf3
1363 ; RV64I-NEXT:    mv s1, a0
1364 ; RV64I-NEXT:    mv a0, s0
1365 ; RV64I-NEXT:    li a1, 0
1366 ; RV64I-NEXT:    call __adddf3
1367 ; RV64I-NEXT:    mv s0, a0
1368 ; RV64I-NEXT:    mv a0, s2
1369 ; RV64I-NEXT:    mv a1, s1
1370 ; RV64I-NEXT:    call __muldf3
1371 ; RV64I-NEXT:    li a1, -1
1372 ; RV64I-NEXT:    slli a1, a1, 63
1373 ; RV64I-NEXT:    xor a0, a0, a1
1374 ; RV64I-NEXT:    mv a1, s0
1375 ; RV64I-NEXT:    call __subdf3
1376 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1377 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1378 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1379 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1380 ; RV64I-NEXT:    addi sp, sp, 32
1381 ; RV64I-NEXT:    ret
1382   %a_ = fadd double 0.0, %a ; avoid negation using xor
1383   %b_ = fadd double 0.0, %b ; avoid negation using xor
1384   %c_ = fadd double 0.0, %c ; avoid negation using xor
1385   %1 = fmul contract double %a_, %b_
1386   %2 = fneg double %1
1387   %3 = fsub contract double %2, %c_
1388   ret double %3
1391 define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
1392 ; RV32IFD-LABEL: fnmsub_d_contract:
1393 ; RV32IFD:       # %bb.0:
1394 ; RV32IFD-NEXT:    fcvt.d.w fa5, zero
1395 ; RV32IFD-NEXT:    fadd.d fa4, fa0, fa5
1396 ; RV32IFD-NEXT:    fadd.d fa5, fa1, fa5
1397 ; RV32IFD-NEXT:    fnmsub.d fa0, fa4, fa5, fa2
1398 ; RV32IFD-NEXT:    ret
1400 ; RV64IFD-LABEL: fnmsub_d_contract:
1401 ; RV64IFD:       # %bb.0:
1402 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
1403 ; RV64IFD-NEXT:    fadd.d fa4, fa0, fa5
1404 ; RV64IFD-NEXT:    fadd.d fa5, fa1, fa5
1405 ; RV64IFD-NEXT:    fnmsub.d fa0, fa4, fa5, fa2
1406 ; RV64IFD-NEXT:    ret
1408 ; RV32IZFINXZDINX-LABEL: fnmsub_d_contract:
1409 ; RV32IZFINXZDINX:       # %bb.0:
1410 ; RV32IZFINXZDINX-NEXT:    fcvt.d.w a6, zero
1411 ; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a6
1412 ; RV32IZFINXZDINX-NEXT:    fadd.d a2, a2, a6
1413 ; RV32IZFINXZDINX-NEXT:    fnmsub.d a0, a0, a2, a4
1414 ; RV32IZFINXZDINX-NEXT:    ret
1416 ; RV64IZFINXZDINX-LABEL: fnmsub_d_contract:
1417 ; RV64IZFINXZDINX:       # %bb.0:
1418 ; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, zero
1419 ; RV64IZFINXZDINX-NEXT:    fadd.d a1, a1, zero
1420 ; RV64IZFINXZDINX-NEXT:    fnmsub.d a0, a0, a1, a2
1421 ; RV64IZFINXZDINX-NEXT:    ret
1423 ; RV32I-LABEL: fnmsub_d_contract:
1424 ; RV32I:       # %bb.0:
1425 ; RV32I-NEXT:    addi sp, sp, -32
1426 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1427 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1428 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1429 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1430 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1431 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1432 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
1433 ; RV32I-NEXT:    mv s0, a5
1434 ; RV32I-NEXT:    mv s1, a4
1435 ; RV32I-NEXT:    mv s2, a3
1436 ; RV32I-NEXT:    mv s3, a2
1437 ; RV32I-NEXT:    li a2, 0
1438 ; RV32I-NEXT:    li a3, 0
1439 ; RV32I-NEXT:    call __adddf3
1440 ; RV32I-NEXT:    mv s4, a0
1441 ; RV32I-NEXT:    mv s5, a1
1442 ; RV32I-NEXT:    mv a0, s3
1443 ; RV32I-NEXT:    mv a1, s2
1444 ; RV32I-NEXT:    li a2, 0
1445 ; RV32I-NEXT:    li a3, 0
1446 ; RV32I-NEXT:    call __adddf3
1447 ; RV32I-NEXT:    mv a2, a0
1448 ; RV32I-NEXT:    mv a3, a1
1449 ; RV32I-NEXT:    mv a0, s4
1450 ; RV32I-NEXT:    mv a1, s5
1451 ; RV32I-NEXT:    call __muldf3
1452 ; RV32I-NEXT:    mv a2, a0
1453 ; RV32I-NEXT:    mv a3, a1
1454 ; RV32I-NEXT:    mv a0, s1
1455 ; RV32I-NEXT:    mv a1, s0
1456 ; RV32I-NEXT:    call __subdf3
1457 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1458 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1459 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1460 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1461 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1462 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1463 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
1464 ; RV32I-NEXT:    addi sp, sp, 32
1465 ; RV32I-NEXT:    ret
1467 ; RV64I-LABEL: fnmsub_d_contract:
1468 ; RV64I:       # %bb.0:
1469 ; RV64I-NEXT:    addi sp, sp, -32
1470 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1471 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1472 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1473 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1474 ; RV64I-NEXT:    mv s0, a2
1475 ; RV64I-NEXT:    mv s1, a1
1476 ; RV64I-NEXT:    li a1, 0
1477 ; RV64I-NEXT:    call __adddf3
1478 ; RV64I-NEXT:    mv s2, a0
1479 ; RV64I-NEXT:    mv a0, s1
1480 ; RV64I-NEXT:    li a1, 0
1481 ; RV64I-NEXT:    call __adddf3
1482 ; RV64I-NEXT:    mv a1, a0
1483 ; RV64I-NEXT:    mv a0, s2
1484 ; RV64I-NEXT:    call __muldf3
1485 ; RV64I-NEXT:    mv a1, a0
1486 ; RV64I-NEXT:    mv a0, s0
1487 ; RV64I-NEXT:    call __subdf3
1488 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1489 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1490 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1491 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1492 ; RV64I-NEXT:    addi sp, sp, 32
1493 ; RV64I-NEXT:    ret
1494   %a_ = fadd double 0.0, %a ; avoid negation using xor
1495   %b_ = fadd double 0.0, %b ; avoid negation using xor
1496   %1 = fmul contract double %a_, %b_
1497   %2 = fsub contract double %c, %1
1498   ret double %2