[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / CodeGen / RISCV / double-arith.ll
blobf7c4b48b72155b05c7052b59ff9ce46c7e4cde8a
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 -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefix=RV32I %s
8 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
9 ; RUN:   | FileCheck -check-prefix=RV64I %s
11 ; These tests are each targeted at a particular RISC-V FPU instruction.
12 ; Compares and conversions can be found in double-fcmp.ll and double-convert.ll
13 ; respectively. Some other double-*.ll files in this folder exercise LLVM IR
14 ; instructions that don't directly match a RISC-V instruction.
16 define double @fadd_d(double %a, double %b) nounwind {
17 ; CHECKIFD-LABEL: fadd_d:
18 ; CHECKIFD:       # %bb.0:
19 ; CHECKIFD-NEXT:    fadd.d fa0, fa0, fa1
20 ; CHECKIFD-NEXT:    ret
22 ; RV32I-LABEL: fadd_d:
23 ; RV32I:       # %bb.0:
24 ; RV32I-NEXT:    addi sp, sp, -16
25 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
26 ; RV32I-NEXT:    call __adddf3@plt
27 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
28 ; RV32I-NEXT:    addi sp, sp, 16
29 ; RV32I-NEXT:    ret
31 ; RV64I-LABEL: fadd_d:
32 ; RV64I:       # %bb.0:
33 ; RV64I-NEXT:    addi sp, sp, -16
34 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
35 ; RV64I-NEXT:    call __adddf3@plt
36 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
37 ; RV64I-NEXT:    addi sp, sp, 16
38 ; RV64I-NEXT:    ret
39   %1 = fadd double %a, %b
40   ret double %1
43 define double @fsub_d(double %a, double %b) nounwind {
44 ; CHECKIFD-LABEL: fsub_d:
45 ; CHECKIFD:       # %bb.0:
46 ; CHECKIFD-NEXT:    fsub.d fa0, fa0, fa1
47 ; CHECKIFD-NEXT:    ret
49 ; RV32I-LABEL: fsub_d:
50 ; RV32I:       # %bb.0:
51 ; RV32I-NEXT:    addi sp, sp, -16
52 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
53 ; RV32I-NEXT:    call __subdf3@plt
54 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
55 ; RV32I-NEXT:    addi sp, sp, 16
56 ; RV32I-NEXT:    ret
58 ; RV64I-LABEL: fsub_d:
59 ; RV64I:       # %bb.0:
60 ; RV64I-NEXT:    addi sp, sp, -16
61 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
62 ; RV64I-NEXT:    call __subdf3@plt
63 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
64 ; RV64I-NEXT:    addi sp, sp, 16
65 ; RV64I-NEXT:    ret
66   %1 = fsub double %a, %b
67   ret double %1
70 define double @fmul_d(double %a, double %b) nounwind {
71 ; CHECKIFD-LABEL: fmul_d:
72 ; CHECKIFD:       # %bb.0:
73 ; CHECKIFD-NEXT:    fmul.d fa0, fa0, fa1
74 ; CHECKIFD-NEXT:    ret
76 ; RV32I-LABEL: fmul_d:
77 ; RV32I:       # %bb.0:
78 ; RV32I-NEXT:    addi sp, sp, -16
79 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
80 ; RV32I-NEXT:    call __muldf3@plt
81 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
82 ; RV32I-NEXT:    addi sp, sp, 16
83 ; RV32I-NEXT:    ret
85 ; RV64I-LABEL: fmul_d:
86 ; RV64I:       # %bb.0:
87 ; RV64I-NEXT:    addi sp, sp, -16
88 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
89 ; RV64I-NEXT:    call __muldf3@plt
90 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
91 ; RV64I-NEXT:    addi sp, sp, 16
92 ; RV64I-NEXT:    ret
93   %1 = fmul double %a, %b
94   ret double %1
97 define double @fdiv_d(double %a, double %b) nounwind {
98 ; CHECKIFD-LABEL: fdiv_d:
99 ; CHECKIFD:       # %bb.0:
100 ; CHECKIFD-NEXT:    fdiv.d fa0, fa0, fa1
101 ; CHECKIFD-NEXT:    ret
103 ; RV32I-LABEL: fdiv_d:
104 ; RV32I:       # %bb.0:
105 ; RV32I-NEXT:    addi sp, sp, -16
106 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
107 ; RV32I-NEXT:    call __divdf3@plt
108 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
109 ; RV32I-NEXT:    addi sp, sp, 16
110 ; RV32I-NEXT:    ret
112 ; RV64I-LABEL: fdiv_d:
113 ; RV64I:       # %bb.0:
114 ; RV64I-NEXT:    addi sp, sp, -16
115 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
116 ; RV64I-NEXT:    call __divdf3@plt
117 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
118 ; RV64I-NEXT:    addi sp, sp, 16
119 ; RV64I-NEXT:    ret
120   %1 = fdiv double %a, %b
121   ret double %1
124 declare double @llvm.sqrt.f64(double)
126 define double @fsqrt_d(double %a) nounwind {
127 ; CHECKIFD-LABEL: fsqrt_d:
128 ; CHECKIFD:       # %bb.0:
129 ; CHECKIFD-NEXT:    fsqrt.d fa0, fa0
130 ; CHECKIFD-NEXT:    ret
132 ; RV32I-LABEL: fsqrt_d:
133 ; RV32I:       # %bb.0:
134 ; RV32I-NEXT:    addi sp, sp, -16
135 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
136 ; RV32I-NEXT:    call sqrt@plt
137 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
138 ; RV32I-NEXT:    addi sp, sp, 16
139 ; RV32I-NEXT:    ret
141 ; RV64I-LABEL: fsqrt_d:
142 ; RV64I:       # %bb.0:
143 ; RV64I-NEXT:    addi sp, sp, -16
144 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
145 ; RV64I-NEXT:    call sqrt@plt
146 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
147 ; RV64I-NEXT:    addi sp, sp, 16
148 ; RV64I-NEXT:    ret
149   %1 = call double @llvm.sqrt.f64(double %a)
150   ret double %1
153 declare double @llvm.copysign.f64(double, double)
155 define double @fsgnj_d(double %a, double %b) nounwind {
156 ; CHECKIFD-LABEL: fsgnj_d:
157 ; CHECKIFD:       # %bb.0:
158 ; CHECKIFD-NEXT:    fsgnj.d fa0, fa0, fa1
159 ; CHECKIFD-NEXT:    ret
161 ; RV32I-LABEL: fsgnj_d:
162 ; RV32I:       # %bb.0:
163 ; RV32I-NEXT:    lui a2, 524288
164 ; RV32I-NEXT:    and a2, a3, a2
165 ; RV32I-NEXT:    slli a1, a1, 1
166 ; RV32I-NEXT:    srli a1, a1, 1
167 ; RV32I-NEXT:    or a1, a1, a2
168 ; RV32I-NEXT:    ret
170 ; RV64I-LABEL: fsgnj_d:
171 ; RV64I:       # %bb.0:
172 ; RV64I-NEXT:    srli a1, a1, 63
173 ; RV64I-NEXT:    slli a1, a1, 63
174 ; RV64I-NEXT:    slli a0, a0, 1
175 ; RV64I-NEXT:    srli a0, a0, 1
176 ; RV64I-NEXT:    or a0, a0, a1
177 ; RV64I-NEXT:    ret
178   %1 = call double @llvm.copysign.f64(double %a, double %b)
179   ret double %1
182 ; This function performs extra work to ensure that
183 ; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
184 define i32 @fneg_d(double %a, double %b) nounwind {
185 ; CHECKIFD-LABEL: fneg_d:
186 ; CHECKIFD:       # %bb.0:
187 ; CHECKIFD-NEXT:    fadd.d ft0, fa0, fa0
188 ; CHECKIFD-NEXT:    fneg.d ft1, ft0
189 ; CHECKIFD-NEXT:    feq.d a0, ft0, ft1
190 ; CHECKIFD-NEXT:    ret
192 ; RV32I-LABEL: fneg_d:
193 ; RV32I:       # %bb.0:
194 ; RV32I-NEXT:    addi sp, sp, -16
195 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
196 ; RV32I-NEXT:    mv a2, a0
197 ; RV32I-NEXT:    mv a3, a1
198 ; RV32I-NEXT:    call __adddf3@plt
199 ; RV32I-NEXT:    lui a2, 524288
200 ; RV32I-NEXT:    xor a3, a1, a2
201 ; RV32I-NEXT:    mv a2, a0
202 ; RV32I-NEXT:    call __eqdf2@plt
203 ; RV32I-NEXT:    seqz a0, a0
204 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
205 ; RV32I-NEXT:    addi sp, sp, 16
206 ; RV32I-NEXT:    ret
208 ; RV64I-LABEL: fneg_d:
209 ; RV64I:       # %bb.0:
210 ; RV64I-NEXT:    addi sp, sp, -16
211 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
212 ; RV64I-NEXT:    mv a1, a0
213 ; RV64I-NEXT:    call __adddf3@plt
214 ; RV64I-NEXT:    li a1, -1
215 ; RV64I-NEXT:    slli a1, a1, 63
216 ; RV64I-NEXT:    xor a1, a0, a1
217 ; RV64I-NEXT:    call __eqdf2@plt
218 ; RV64I-NEXT:    seqz a0, a0
219 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
220 ; RV64I-NEXT:    addi sp, sp, 16
221 ; RV64I-NEXT:    ret
222   %1 = fadd double %a, %a
223   %2 = fneg double %1
224   %3 = fcmp oeq double %1, %2
225   %4 = zext i1 %3 to i32
226   ret i32 %4
229 define double @fsgnjn_d(double %a, double %b) nounwind {
230 ; TODO: fsgnjn.s isn't selected on RV64 because DAGCombiner::visitBITCAST will
231 ; convert (bitconvert (fneg x)) to a xor.
233 ; CHECKIFD-LABEL: fsgnjn_d:
234 ; CHECKIFD:       # %bb.0:
235 ; CHECKIFD-NEXT:    fsgnjn.d fa0, fa0, fa1
236 ; CHECKIFD-NEXT:    ret
238 ; RV32I-LABEL: fsgnjn_d:
239 ; RV32I:       # %bb.0:
240 ; RV32I-NEXT:    not a2, a3
241 ; RV32I-NEXT:    lui a3, 524288
242 ; RV32I-NEXT:    and a2, a2, a3
243 ; RV32I-NEXT:    slli a1, a1, 1
244 ; RV32I-NEXT:    srli a1, a1, 1
245 ; RV32I-NEXT:    or a1, a1, a2
246 ; RV32I-NEXT:    ret
248 ; RV64I-LABEL: fsgnjn_d:
249 ; RV64I:       # %bb.0:
250 ; RV64I-NEXT:    not a1, a1
251 ; RV64I-NEXT:    slli a0, a0, 1
252 ; RV64I-NEXT:    srli a0, a0, 1
253 ; RV64I-NEXT:    srli a1, a1, 63
254 ; RV64I-NEXT:    slli a1, a1, 63
255 ; RV64I-NEXT:    or a0, a0, a1
256 ; RV64I-NEXT:    ret
257   %1 = fsub double -0.0, %b
258   %2 = call double @llvm.copysign.f64(double %a, double %1)
259   ret double %2
262 declare double @llvm.fabs.f64(double)
264 ; This function performs extra work to ensure that
265 ; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
266 define double @fabs_d(double %a, double %b) nounwind {
267 ; CHECKIFD-LABEL: fabs_d:
268 ; CHECKIFD:       # %bb.0:
269 ; CHECKIFD-NEXT:    fadd.d ft0, fa0, fa1
270 ; CHECKIFD-NEXT:    fabs.d ft1, ft0
271 ; CHECKIFD-NEXT:    fadd.d fa0, ft1, ft0
272 ; CHECKIFD-NEXT:    ret
274 ; RV32I-LABEL: fabs_d:
275 ; RV32I:       # %bb.0:
276 ; RV32I-NEXT:    addi sp, sp, -16
277 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
278 ; RV32I-NEXT:    call __adddf3@plt
279 ; RV32I-NEXT:    mv a3, a1
280 ; RV32I-NEXT:    slli a1, a1, 1
281 ; RV32I-NEXT:    srli a1, a1, 1
282 ; RV32I-NEXT:    mv a2, a0
283 ; RV32I-NEXT:    call __adddf3@plt
284 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
285 ; RV32I-NEXT:    addi sp, sp, 16
286 ; RV32I-NEXT:    ret
288 ; RV64I-LABEL: fabs_d:
289 ; RV64I:       # %bb.0:
290 ; RV64I-NEXT:    addi sp, sp, -16
291 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
292 ; RV64I-NEXT:    call __adddf3@plt
293 ; RV64I-NEXT:    mv a1, a0
294 ; RV64I-NEXT:    slli a0, a0, 1
295 ; RV64I-NEXT:    srli a0, a0, 1
296 ; RV64I-NEXT:    call __adddf3@plt
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, %b
301   %2 = call double @llvm.fabs.f64(double %1)
302   %3 = fadd double %2, %1
303   ret double %3
306 declare double @llvm.minnum.f64(double, double)
308 define double @fmin_d(double %a, double %b) nounwind {
309 ; CHECKIFD-LABEL: fmin_d:
310 ; CHECKIFD:       # %bb.0:
311 ; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa1
312 ; CHECKIFD-NEXT:    ret
314 ; RV32I-LABEL: fmin_d:
315 ; RV32I:       # %bb.0:
316 ; RV32I-NEXT:    addi sp, sp, -16
317 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
318 ; RV32I-NEXT:    call fmin@plt
319 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
320 ; RV32I-NEXT:    addi sp, sp, 16
321 ; RV32I-NEXT:    ret
323 ; RV64I-LABEL: fmin_d:
324 ; RV64I:       # %bb.0:
325 ; RV64I-NEXT:    addi sp, sp, -16
326 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
327 ; RV64I-NEXT:    call fmin@plt
328 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
329 ; RV64I-NEXT:    addi sp, sp, 16
330 ; RV64I-NEXT:    ret
331   %1 = call double @llvm.minnum.f64(double %a, double %b)
332   ret double %1
335 declare double @llvm.maxnum.f64(double, double)
337 define double @fmax_d(double %a, double %b) nounwind {
338 ; CHECKIFD-LABEL: fmax_d:
339 ; CHECKIFD:       # %bb.0:
340 ; CHECKIFD-NEXT:    fmax.d fa0, fa0, fa1
341 ; CHECKIFD-NEXT:    ret
343 ; RV32I-LABEL: fmax_d:
344 ; RV32I:       # %bb.0:
345 ; RV32I-NEXT:    addi sp, sp, -16
346 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
347 ; RV32I-NEXT:    call fmax@plt
348 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
349 ; RV32I-NEXT:    addi sp, sp, 16
350 ; RV32I-NEXT:    ret
352 ; RV64I-LABEL: fmax_d:
353 ; RV64I:       # %bb.0:
354 ; RV64I-NEXT:    addi sp, sp, -16
355 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
356 ; RV64I-NEXT:    call fmax@plt
357 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
358 ; RV64I-NEXT:    addi sp, sp, 16
359 ; RV64I-NEXT:    ret
360   %1 = call double @llvm.maxnum.f64(double %a, double %b)
361   ret double %1
364 declare double @llvm.fma.f64(double, double, double)
366 define double @fmadd_d(double %a, double %b, double %c) nounwind {
367 ; CHECKIFD-LABEL: fmadd_d:
368 ; CHECKIFD:       # %bb.0:
369 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
370 ; CHECKIFD-NEXT:    ret
372 ; RV32I-LABEL: fmadd_d:
373 ; RV32I:       # %bb.0:
374 ; RV32I-NEXT:    addi sp, sp, -16
375 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
376 ; RV32I-NEXT:    call fma@plt
377 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
378 ; RV32I-NEXT:    addi sp, sp, 16
379 ; RV32I-NEXT:    ret
381 ; RV64I-LABEL: fmadd_d:
382 ; RV64I:       # %bb.0:
383 ; RV64I-NEXT:    addi sp, sp, -16
384 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
385 ; RV64I-NEXT:    call fma@plt
386 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
387 ; RV64I-NEXT:    addi sp, sp, 16
388 ; RV64I-NEXT:    ret
389   %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
390   ret double %1
393 define double @fmsub_d(double %a, double %b, double %c) nounwind {
394 ; RV32IFD-LABEL: fmsub_d:
395 ; RV32IFD:       # %bb.0:
396 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
397 ; RV32IFD-NEXT:    fadd.d ft0, fa2, ft0
398 ; RV32IFD-NEXT:    fmsub.d fa0, fa0, fa1, ft0
399 ; RV32IFD-NEXT:    ret
401 ; RV64IFD-LABEL: fmsub_d:
402 ; RV64IFD:       # %bb.0:
403 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
404 ; RV64IFD-NEXT:    fadd.d ft0, fa2, ft0
405 ; RV64IFD-NEXT:    fmsub.d fa0, fa0, fa1, ft0
406 ; RV64IFD-NEXT:    ret
408 ; RV32I-LABEL: fmsub_d:
409 ; RV32I:       # %bb.0:
410 ; RV32I-NEXT:    addi sp, sp, -32
411 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
412 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
413 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
414 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
415 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
416 ; RV32I-NEXT:    mv s0, a3
417 ; RV32I-NEXT:    mv s1, a2
418 ; RV32I-NEXT:    mv s2, a1
419 ; RV32I-NEXT:    mv s3, a0
420 ; RV32I-NEXT:    mv a0, a4
421 ; RV32I-NEXT:    mv a1, a5
422 ; RV32I-NEXT:    li a2, 0
423 ; RV32I-NEXT:    li a3, 0
424 ; RV32I-NEXT:    call __adddf3@plt
425 ; RV32I-NEXT:    mv a4, a0
426 ; RV32I-NEXT:    lui a0, 524288
427 ; RV32I-NEXT:    xor a5, a1, a0
428 ; RV32I-NEXT:    mv a0, s3
429 ; RV32I-NEXT:    mv a1, s2
430 ; RV32I-NEXT:    mv a2, s1
431 ; RV32I-NEXT:    mv a3, s0
432 ; RV32I-NEXT:    call fma@plt
433 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
434 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
435 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
436 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
437 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
438 ; RV32I-NEXT:    addi sp, sp, 32
439 ; RV32I-NEXT:    ret
441 ; RV64I-LABEL: fmsub_d:
442 ; RV64I:       # %bb.0:
443 ; RV64I-NEXT:    addi sp, sp, -32
444 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
445 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
446 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
447 ; RV64I-NEXT:    mv s0, a1
448 ; RV64I-NEXT:    mv s1, a0
449 ; RV64I-NEXT:    mv a0, a2
450 ; RV64I-NEXT:    li a1, 0
451 ; RV64I-NEXT:    call __adddf3@plt
452 ; RV64I-NEXT:    li a1, -1
453 ; RV64I-NEXT:    slli a1, a1, 63
454 ; RV64I-NEXT:    xor a2, a0, a1
455 ; RV64I-NEXT:    mv a0, s1
456 ; RV64I-NEXT:    mv a1, s0
457 ; RV64I-NEXT:    call fma@plt
458 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
459 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
460 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
461 ; RV64I-NEXT:    addi sp, sp, 32
462 ; RV64I-NEXT:    ret
463   %c_ = fadd double 0.0, %c ; avoid negation using xor
464   %negc = fsub double -0.0, %c_
465   %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
466   ret double %1
469 define double @fnmadd_d(double %a, double %b, double %c) nounwind {
470 ; RV32IFD-LABEL: fnmadd_d:
471 ; RV32IFD:       # %bb.0:
472 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
473 ; RV32IFD-NEXT:    fadd.d ft1, fa0, ft0
474 ; RV32IFD-NEXT:    fadd.d ft0, fa2, ft0
475 ; RV32IFD-NEXT:    fnmadd.d fa0, ft1, fa1, ft0
476 ; RV32IFD-NEXT:    ret
478 ; RV64IFD-LABEL: fnmadd_d:
479 ; RV64IFD:       # %bb.0:
480 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
481 ; RV64IFD-NEXT:    fadd.d ft1, fa0, ft0
482 ; RV64IFD-NEXT:    fadd.d ft0, fa2, ft0
483 ; RV64IFD-NEXT:    fnmadd.d fa0, ft1, fa1, ft0
484 ; RV64IFD-NEXT:    ret
486 ; RV32I-LABEL: fnmadd_d:
487 ; RV32I:       # %bb.0:
488 ; RV32I-NEXT:    addi sp, sp, -32
489 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
490 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
491 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
492 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
493 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
494 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
495 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
496 ; RV32I-NEXT:    mv s0, a5
497 ; RV32I-NEXT:    mv s1, a4
498 ; RV32I-NEXT:    mv s2, a3
499 ; RV32I-NEXT:    mv s3, a2
500 ; RV32I-NEXT:    li a2, 0
501 ; RV32I-NEXT:    li a3, 0
502 ; RV32I-NEXT:    call __adddf3@plt
503 ; RV32I-NEXT:    mv s4, a0
504 ; RV32I-NEXT:    mv s5, a1
505 ; RV32I-NEXT:    mv a0, s1
506 ; RV32I-NEXT:    mv a1, s0
507 ; RV32I-NEXT:    li a2, 0
508 ; RV32I-NEXT:    li a3, 0
509 ; RV32I-NEXT:    call __adddf3@plt
510 ; RV32I-NEXT:    mv a4, a0
511 ; RV32I-NEXT:    lui a0, 524288
512 ; RV32I-NEXT:    xor a2, s5, a0
513 ; RV32I-NEXT:    xor a5, a1, a0
514 ; RV32I-NEXT:    mv a0, s4
515 ; RV32I-NEXT:    mv a1, a2
516 ; RV32I-NEXT:    mv a2, s3
517 ; RV32I-NEXT:    mv a3, s2
518 ; RV32I-NEXT:    call fma@plt
519 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
520 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
521 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
522 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
523 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
524 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
525 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
526 ; RV32I-NEXT:    addi sp, sp, 32
527 ; RV32I-NEXT:    ret
529 ; RV64I-LABEL: fnmadd_d:
530 ; RV64I:       # %bb.0:
531 ; RV64I-NEXT:    addi sp, sp, -32
532 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
533 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
534 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
535 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
536 ; RV64I-NEXT:    mv s0, a2
537 ; RV64I-NEXT:    mv s1, a1
538 ; RV64I-NEXT:    li a1, 0
539 ; RV64I-NEXT:    call __adddf3@plt
540 ; RV64I-NEXT:    mv s2, a0
541 ; RV64I-NEXT:    mv a0, s0
542 ; RV64I-NEXT:    li a1, 0
543 ; RV64I-NEXT:    call __adddf3@plt
544 ; RV64I-NEXT:    li a1, -1
545 ; RV64I-NEXT:    slli a2, a1, 63
546 ; RV64I-NEXT:    xor a1, s2, a2
547 ; RV64I-NEXT:    xor a2, a0, a2
548 ; RV64I-NEXT:    mv a0, a1
549 ; RV64I-NEXT:    mv a1, s1
550 ; RV64I-NEXT:    call fma@plt
551 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
552 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
553 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
554 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
555 ; RV64I-NEXT:    addi sp, sp, 32
556 ; RV64I-NEXT:    ret
557   %a_ = fadd double 0.0, %a
558   %c_ = fadd double 0.0, %c
559   %nega = fsub double -0.0, %a_
560   %negc = fsub double -0.0, %c_
561   %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
562   ret double %1
565 define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
566 ; RV32IFD-LABEL: fnmadd_d_2:
567 ; RV32IFD:       # %bb.0:
568 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
569 ; RV32IFD-NEXT:    fadd.d ft1, fa1, ft0
570 ; RV32IFD-NEXT:    fadd.d ft0, fa2, ft0
571 ; RV32IFD-NEXT:    fnmadd.d fa0, ft1, fa0, ft0
572 ; RV32IFD-NEXT:    ret
574 ; RV64IFD-LABEL: fnmadd_d_2:
575 ; RV64IFD:       # %bb.0:
576 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
577 ; RV64IFD-NEXT:    fadd.d ft1, fa1, ft0
578 ; RV64IFD-NEXT:    fadd.d ft0, fa2, ft0
579 ; RV64IFD-NEXT:    fnmadd.d fa0, ft1, fa0, ft0
580 ; RV64IFD-NEXT:    ret
582 ; RV32I-LABEL: fnmadd_d_2:
583 ; RV32I:       # %bb.0:
584 ; RV32I-NEXT:    addi sp, sp, -32
585 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
586 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
587 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
588 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
589 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
590 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
591 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
592 ; RV32I-NEXT:    mv s0, a5
593 ; RV32I-NEXT:    mv s1, a4
594 ; RV32I-NEXT:    mv s2, a1
595 ; RV32I-NEXT:    mv s3, a0
596 ; RV32I-NEXT:    mv a0, a2
597 ; RV32I-NEXT:    mv a1, a3
598 ; RV32I-NEXT:    li a2, 0
599 ; RV32I-NEXT:    li a3, 0
600 ; RV32I-NEXT:    call __adddf3@plt
601 ; RV32I-NEXT:    mv s4, a0
602 ; RV32I-NEXT:    mv s5, a1
603 ; RV32I-NEXT:    mv a0, s1
604 ; RV32I-NEXT:    mv a1, s0
605 ; RV32I-NEXT:    li a2, 0
606 ; RV32I-NEXT:    li a3, 0
607 ; RV32I-NEXT:    call __adddf3@plt
608 ; RV32I-NEXT:    mv a4, a0
609 ; RV32I-NEXT:    lui a0, 524288
610 ; RV32I-NEXT:    xor a3, s5, a0
611 ; RV32I-NEXT:    xor a5, a1, a0
612 ; RV32I-NEXT:    mv a0, s3
613 ; RV32I-NEXT:    mv a1, s2
614 ; RV32I-NEXT:    mv a2, s4
615 ; RV32I-NEXT:    call fma@plt
616 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
617 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
618 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
619 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
620 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
621 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
622 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
623 ; RV32I-NEXT:    addi sp, sp, 32
624 ; RV32I-NEXT:    ret
626 ; RV64I-LABEL: fnmadd_d_2:
627 ; RV64I:       # %bb.0:
628 ; RV64I-NEXT:    addi sp, sp, -32
629 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
630 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
631 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
632 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
633 ; RV64I-NEXT:    mv s0, a2
634 ; RV64I-NEXT:    mv s1, a0
635 ; RV64I-NEXT:    mv a0, a1
636 ; RV64I-NEXT:    li a1, 0
637 ; RV64I-NEXT:    call __adddf3@plt
638 ; RV64I-NEXT:    mv s2, a0
639 ; RV64I-NEXT:    mv a0, s0
640 ; RV64I-NEXT:    li a1, 0
641 ; RV64I-NEXT:    call __adddf3@plt
642 ; RV64I-NEXT:    li a1, -1
643 ; RV64I-NEXT:    slli a2, a1, 63
644 ; RV64I-NEXT:    xor a1, s2, a2
645 ; RV64I-NEXT:    xor a2, a0, a2
646 ; RV64I-NEXT:    mv a0, s1
647 ; RV64I-NEXT:    call fma@plt
648 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
649 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
650 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
651 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
652 ; RV64I-NEXT:    addi sp, sp, 32
653 ; RV64I-NEXT:    ret
654   %b_ = fadd double 0.0, %b
655   %c_ = fadd double 0.0, %c
656   %negb = fsub double -0.0, %b_
657   %negc = fsub double -0.0, %c_
658   %1 = call double @llvm.fma.f64(double %a, double %negb, double %negc)
659   ret double %1
662 define double @fnmadd_d_3(double %a, double %b, double %c) nounwind {
663 ; CHECKIFD-LABEL: fnmadd_d_3:
664 ; CHECKIFD:       # %bb.0:
665 ; CHECKIFD-NEXT:    fmadd.d ft0, fa0, fa1, fa2
666 ; CHECKIFD-NEXT:    fneg.d fa0, ft0
667 ; CHECKIFD-NEXT:    ret
669 ; RV32I-LABEL: fnmadd_d_3:
670 ; RV32I:       # %bb.0:
671 ; RV32I-NEXT:    addi sp, sp, -16
672 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
673 ; RV32I-NEXT:    call fma@plt
674 ; RV32I-NEXT:    lui a2, 524288
675 ; RV32I-NEXT:    xor a1, a1, a2
676 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
677 ; RV32I-NEXT:    addi sp, sp, 16
678 ; RV32I-NEXT:    ret
680 ; RV64I-LABEL: fnmadd_d_3:
681 ; RV64I:       # %bb.0:
682 ; RV64I-NEXT:    addi sp, sp, -16
683 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
684 ; RV64I-NEXT:    call fma@plt
685 ; RV64I-NEXT:    li a1, -1
686 ; RV64I-NEXT:    slli a1, a1, 63
687 ; RV64I-NEXT:    xor a0, a0, a1
688 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
689 ; RV64I-NEXT:    addi sp, sp, 16
690 ; RV64I-NEXT:    ret
691   %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
692   %neg = fneg double %1
693   ret double %neg
697 define double @fnmadd_nsz(double %a, double %b, double %c) nounwind {
698 ; CHECKIFD-LABEL: fnmadd_nsz:
699 ; CHECKIFD:       # %bb.0:
700 ; CHECKIFD-NEXT:    fnmadd.d fa0, fa0, fa1, fa2
701 ; CHECKIFD-NEXT:    ret
703 ; RV32I-LABEL: fnmadd_nsz:
704 ; RV32I:       # %bb.0:
705 ; RV32I-NEXT:    addi sp, sp, -16
706 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
707 ; RV32I-NEXT:    call fma@plt
708 ; RV32I-NEXT:    lui a2, 524288
709 ; RV32I-NEXT:    xor a1, a1, a2
710 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
711 ; RV32I-NEXT:    addi sp, sp, 16
712 ; RV32I-NEXT:    ret
714 ; RV64I-LABEL: fnmadd_nsz:
715 ; RV64I:       # %bb.0:
716 ; RV64I-NEXT:    addi sp, sp, -16
717 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
718 ; RV64I-NEXT:    call fma@plt
719 ; RV64I-NEXT:    li a1, -1
720 ; RV64I-NEXT:    slli a1, a1, 63
721 ; RV64I-NEXT:    xor a0, a0, a1
722 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
723 ; RV64I-NEXT:    addi sp, sp, 16
724 ; RV64I-NEXT:    ret
725   %1 = call nsz double @llvm.fma.f64(double %a, double %b, double %c)
726   %neg = fneg nsz double %1
727   ret double %neg
730 define double @fnmsub_d(double %a, double %b, double %c) nounwind {
731 ; RV32IFD-LABEL: fnmsub_d:
732 ; RV32IFD:       # %bb.0:
733 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
734 ; RV32IFD-NEXT:    fadd.d ft0, fa0, ft0
735 ; RV32IFD-NEXT:    fnmsub.d fa0, ft0, fa1, fa2
736 ; RV32IFD-NEXT:    ret
738 ; RV64IFD-LABEL: fnmsub_d:
739 ; RV64IFD:       # %bb.0:
740 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
741 ; RV64IFD-NEXT:    fadd.d ft0, fa0, ft0
742 ; RV64IFD-NEXT:    fnmsub.d fa0, ft0, fa1, fa2
743 ; RV64IFD-NEXT:    ret
745 ; RV32I-LABEL: fnmsub_d:
746 ; RV32I:       # %bb.0:
747 ; RV32I-NEXT:    addi sp, sp, -32
748 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
749 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
750 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
751 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
752 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
753 ; RV32I-NEXT:    mv s0, a5
754 ; RV32I-NEXT:    mv s1, a4
755 ; RV32I-NEXT:    mv s2, a3
756 ; RV32I-NEXT:    mv s3, a2
757 ; RV32I-NEXT:    li a2, 0
758 ; RV32I-NEXT:    li a3, 0
759 ; RV32I-NEXT:    call __adddf3@plt
760 ; RV32I-NEXT:    lui a2, 524288
761 ; RV32I-NEXT:    xor a1, a1, a2
762 ; RV32I-NEXT:    mv a2, s3
763 ; RV32I-NEXT:    mv a3, s2
764 ; RV32I-NEXT:    mv a4, s1
765 ; RV32I-NEXT:    mv a5, s0
766 ; RV32I-NEXT:    call fma@plt
767 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
768 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
769 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
770 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
771 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
772 ; RV32I-NEXT:    addi sp, sp, 32
773 ; RV32I-NEXT:    ret
775 ; RV64I-LABEL: fnmsub_d:
776 ; RV64I:       # %bb.0:
777 ; RV64I-NEXT:    addi sp, sp, -32
778 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
779 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
780 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
781 ; RV64I-NEXT:    mv s0, a2
782 ; RV64I-NEXT:    mv s1, a1
783 ; RV64I-NEXT:    li a1, 0
784 ; RV64I-NEXT:    call __adddf3@plt
785 ; RV64I-NEXT:    li a1, -1
786 ; RV64I-NEXT:    slli a1, a1, 63
787 ; RV64I-NEXT:    xor a0, a0, a1
788 ; RV64I-NEXT:    mv a1, s1
789 ; RV64I-NEXT:    mv a2, s0
790 ; RV64I-NEXT:    call fma@plt
791 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
792 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
793 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
794 ; RV64I-NEXT:    addi sp, sp, 32
795 ; RV64I-NEXT:    ret
796   %a_ = fadd double 0.0, %a
797   %nega = fsub double -0.0, %a_
798   %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
799   ret double %1
802 define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
803 ; RV32IFD-LABEL: fnmsub_d_2:
804 ; RV32IFD:       # %bb.0:
805 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
806 ; RV32IFD-NEXT:    fadd.d ft0, fa1, ft0
807 ; RV32IFD-NEXT:    fnmsub.d fa0, ft0, fa0, fa2
808 ; RV32IFD-NEXT:    ret
810 ; RV64IFD-LABEL: fnmsub_d_2:
811 ; RV64IFD:       # %bb.0:
812 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
813 ; RV64IFD-NEXT:    fadd.d ft0, fa1, ft0
814 ; RV64IFD-NEXT:    fnmsub.d fa0, ft0, fa0, fa2
815 ; RV64IFD-NEXT:    ret
817 ; RV32I-LABEL: fnmsub_d_2:
818 ; RV32I:       # %bb.0:
819 ; RV32I-NEXT:    addi sp, sp, -32
820 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
821 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
822 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
823 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
824 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
825 ; RV32I-NEXT:    mv s0, a5
826 ; RV32I-NEXT:    mv s1, a4
827 ; RV32I-NEXT:    mv s2, a1
828 ; RV32I-NEXT:    mv s3, a0
829 ; RV32I-NEXT:    mv a0, a2
830 ; RV32I-NEXT:    mv a1, a3
831 ; RV32I-NEXT:    li a2, 0
832 ; RV32I-NEXT:    li a3, 0
833 ; RV32I-NEXT:    call __adddf3@plt
834 ; RV32I-NEXT:    mv a2, a0
835 ; RV32I-NEXT:    lui a0, 524288
836 ; RV32I-NEXT:    xor a3, a1, a0
837 ; RV32I-NEXT:    mv a0, s3
838 ; RV32I-NEXT:    mv a1, s2
839 ; RV32I-NEXT:    mv a4, s1
840 ; RV32I-NEXT:    mv a5, s0
841 ; RV32I-NEXT:    call fma@plt
842 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
843 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
844 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
845 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
846 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
847 ; RV32I-NEXT:    addi sp, sp, 32
848 ; RV32I-NEXT:    ret
850 ; RV64I-LABEL: fnmsub_d_2:
851 ; RV64I:       # %bb.0:
852 ; RV64I-NEXT:    addi sp, sp, -32
853 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
854 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
855 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
856 ; RV64I-NEXT:    mv s0, a2
857 ; RV64I-NEXT:    mv s1, a0
858 ; RV64I-NEXT:    mv a0, a1
859 ; RV64I-NEXT:    li a1, 0
860 ; RV64I-NEXT:    call __adddf3@plt
861 ; RV64I-NEXT:    li a1, -1
862 ; RV64I-NEXT:    slli a1, a1, 63
863 ; RV64I-NEXT:    xor a1, a0, a1
864 ; RV64I-NEXT:    mv a0, s1
865 ; RV64I-NEXT:    mv a2, s0
866 ; RV64I-NEXT:    call fma@plt
867 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
868 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
869 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
870 ; RV64I-NEXT:    addi sp, sp, 32
871 ; RV64I-NEXT:    ret
872   %b_ = fadd double 0.0, %b
873   %negb = fsub double -0.0, %b_
874   %1 = call double @llvm.fma.f64(double %a, double %negb, double %c)
875   ret double %1
878 define double @fmadd_d_contract(double %a, double %b, double %c) nounwind {
879 ; CHECKIFD-LABEL: fmadd_d_contract:
880 ; CHECKIFD:       # %bb.0:
881 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
882 ; CHECKIFD-NEXT:    ret
884 ; RV32I-LABEL: fmadd_d_contract:
885 ; RV32I:       # %bb.0:
886 ; RV32I-NEXT:    addi sp, sp, -16
887 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
888 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
889 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
890 ; RV32I-NEXT:    mv s0, a5
891 ; RV32I-NEXT:    mv s1, a4
892 ; RV32I-NEXT:    call __muldf3@plt
893 ; RV32I-NEXT:    mv a2, s1
894 ; RV32I-NEXT:    mv a3, s0
895 ; RV32I-NEXT:    call __adddf3@plt
896 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
897 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
898 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
899 ; RV32I-NEXT:    addi sp, sp, 16
900 ; RV32I-NEXT:    ret
902 ; RV64I-LABEL: fmadd_d_contract:
903 ; RV64I:       # %bb.0:
904 ; RV64I-NEXT:    addi sp, sp, -16
905 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
906 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
907 ; RV64I-NEXT:    mv s0, a2
908 ; RV64I-NEXT:    call __muldf3@plt
909 ; RV64I-NEXT:    mv a1, s0
910 ; RV64I-NEXT:    call __adddf3@plt
911 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
912 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
913 ; RV64I-NEXT:    addi sp, sp, 16
914 ; RV64I-NEXT:    ret
915   %1 = fmul contract double %a, %b
916   %2 = fadd contract double %1, %c
917   ret double %2
920 define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
921 ; RV32IFD-LABEL: fmsub_d_contract:
922 ; RV32IFD:       # %bb.0:
923 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
924 ; RV32IFD-NEXT:    fadd.d ft0, fa2, ft0
925 ; RV32IFD-NEXT:    fmsub.d fa0, fa0, fa1, ft0
926 ; RV32IFD-NEXT:    ret
928 ; RV64IFD-LABEL: fmsub_d_contract:
929 ; RV64IFD:       # %bb.0:
930 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
931 ; RV64IFD-NEXT:    fadd.d ft0, fa2, ft0
932 ; RV64IFD-NEXT:    fmsub.d fa0, fa0, fa1, ft0
933 ; RV64IFD-NEXT:    ret
935 ; RV32I-LABEL: fmsub_d_contract:
936 ; RV32I:       # %bb.0:
937 ; RV32I-NEXT:    addi sp, sp, -32
938 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
939 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
940 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
941 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
942 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
943 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
944 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
945 ; RV32I-NEXT:    mv s0, a3
946 ; RV32I-NEXT:    mv s1, a2
947 ; RV32I-NEXT:    mv s2, a1
948 ; RV32I-NEXT:    mv s3, a0
949 ; RV32I-NEXT:    mv a0, a4
950 ; RV32I-NEXT:    mv a1, a5
951 ; RV32I-NEXT:    li a2, 0
952 ; RV32I-NEXT:    li a3, 0
953 ; RV32I-NEXT:    call __adddf3@plt
954 ; RV32I-NEXT:    mv s4, a0
955 ; RV32I-NEXT:    mv s5, a1
956 ; RV32I-NEXT:    mv a0, s3
957 ; RV32I-NEXT:    mv a1, s2
958 ; RV32I-NEXT:    mv a2, s1
959 ; RV32I-NEXT:    mv a3, s0
960 ; RV32I-NEXT:    call __muldf3@plt
961 ; RV32I-NEXT:    mv a2, s4
962 ; RV32I-NEXT:    mv a3, s5
963 ; RV32I-NEXT:    call __subdf3@plt
964 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
965 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
966 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
967 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
968 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
969 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
970 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
971 ; RV32I-NEXT:    addi sp, sp, 32
972 ; RV32I-NEXT:    ret
974 ; RV64I-LABEL: fmsub_d_contract:
975 ; RV64I:       # %bb.0:
976 ; RV64I-NEXT:    addi sp, sp, -32
977 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
978 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
979 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
980 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
981 ; RV64I-NEXT:    mv s0, a1
982 ; RV64I-NEXT:    mv s1, a0
983 ; RV64I-NEXT:    mv a0, a2
984 ; RV64I-NEXT:    li a1, 0
985 ; RV64I-NEXT:    call __adddf3@plt
986 ; RV64I-NEXT:    mv s2, a0
987 ; RV64I-NEXT:    mv a0, s1
988 ; RV64I-NEXT:    mv a1, s0
989 ; RV64I-NEXT:    call __muldf3@plt
990 ; RV64I-NEXT:    mv a1, s2
991 ; RV64I-NEXT:    call __subdf3@plt
992 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
993 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
994 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
995 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
996 ; RV64I-NEXT:    addi sp, sp, 32
997 ; RV64I-NEXT:    ret
998   %c_ = fadd double 0.0, %c ; avoid negation using xor
999   %1 = fmul contract double %a, %b
1000   %2 = fsub contract double %1, %c_
1001   ret double %2
1004 define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
1005 ; RV32IFD-LABEL: fnmadd_d_contract:
1006 ; RV32IFD:       # %bb.0:
1007 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
1008 ; RV32IFD-NEXT:    fadd.d ft1, fa0, ft0
1009 ; RV32IFD-NEXT:    fadd.d ft2, fa1, ft0
1010 ; RV32IFD-NEXT:    fadd.d ft0, fa2, ft0
1011 ; RV32IFD-NEXT:    fnmadd.d fa0, ft1, ft2, ft0
1012 ; RV32IFD-NEXT:    ret
1014 ; RV64IFD-LABEL: fnmadd_d_contract:
1015 ; RV64IFD:       # %bb.0:
1016 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
1017 ; RV64IFD-NEXT:    fadd.d ft1, fa0, ft0
1018 ; RV64IFD-NEXT:    fadd.d ft2, fa1, ft0
1019 ; RV64IFD-NEXT:    fadd.d ft0, fa2, ft0
1020 ; RV64IFD-NEXT:    fnmadd.d fa0, ft1, ft2, ft0
1021 ; RV64IFD-NEXT:    ret
1023 ; RV32I-LABEL: fnmadd_d_contract:
1024 ; RV32I:       # %bb.0:
1025 ; RV32I-NEXT:    addi sp, sp, -32
1026 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1027 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1028 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1029 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1030 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1031 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1032 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
1033 ; RV32I-NEXT:    mv s0, a5
1034 ; RV32I-NEXT:    mv s1, a4
1035 ; RV32I-NEXT:    mv s2, a3
1036 ; RV32I-NEXT:    mv s3, a2
1037 ; RV32I-NEXT:    li a2, 0
1038 ; RV32I-NEXT:    li a3, 0
1039 ; RV32I-NEXT:    call __adddf3@plt
1040 ; RV32I-NEXT:    mv s4, a0
1041 ; RV32I-NEXT:    mv s5, a1
1042 ; RV32I-NEXT:    mv a0, s3
1043 ; RV32I-NEXT:    mv a1, s2
1044 ; RV32I-NEXT:    li a2, 0
1045 ; RV32I-NEXT:    li a3, 0
1046 ; RV32I-NEXT:    call __adddf3@plt
1047 ; RV32I-NEXT:    mv s2, a0
1048 ; RV32I-NEXT:    mv s3, a1
1049 ; RV32I-NEXT:    mv a0, s1
1050 ; RV32I-NEXT:    mv a1, s0
1051 ; RV32I-NEXT:    li a2, 0
1052 ; RV32I-NEXT:    li a3, 0
1053 ; RV32I-NEXT:    call __adddf3@plt
1054 ; RV32I-NEXT:    mv s0, a0
1055 ; RV32I-NEXT:    mv s1, a1
1056 ; RV32I-NEXT:    mv a0, s4
1057 ; RV32I-NEXT:    mv a1, s5
1058 ; RV32I-NEXT:    mv a2, s2
1059 ; RV32I-NEXT:    mv a3, s3
1060 ; RV32I-NEXT:    call __muldf3@plt
1061 ; RV32I-NEXT:    lui a2, 524288
1062 ; RV32I-NEXT:    xor a1, a1, a2
1063 ; RV32I-NEXT:    mv a2, s0
1064 ; RV32I-NEXT:    mv a3, s1
1065 ; RV32I-NEXT:    call __subdf3@plt
1066 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1067 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1068 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1069 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1070 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1071 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1072 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
1073 ; RV32I-NEXT:    addi sp, sp, 32
1074 ; RV32I-NEXT:    ret
1076 ; RV64I-LABEL: fnmadd_d_contract:
1077 ; RV64I:       # %bb.0:
1078 ; RV64I-NEXT:    addi sp, sp, -32
1079 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1080 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1081 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1082 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1083 ; RV64I-NEXT:    mv s0, a2
1084 ; RV64I-NEXT:    mv s1, a1
1085 ; RV64I-NEXT:    li a1, 0
1086 ; RV64I-NEXT:    call __adddf3@plt
1087 ; RV64I-NEXT:    mv s2, a0
1088 ; RV64I-NEXT:    mv a0, s1
1089 ; RV64I-NEXT:    li a1, 0
1090 ; RV64I-NEXT:    call __adddf3@plt
1091 ; RV64I-NEXT:    mv s1, a0
1092 ; RV64I-NEXT:    mv a0, s0
1093 ; RV64I-NEXT:    li a1, 0
1094 ; RV64I-NEXT:    call __adddf3@plt
1095 ; RV64I-NEXT:    mv s0, a0
1096 ; RV64I-NEXT:    mv a0, s2
1097 ; RV64I-NEXT:    mv a1, s1
1098 ; RV64I-NEXT:    call __muldf3@plt
1099 ; RV64I-NEXT:    li a1, -1
1100 ; RV64I-NEXT:    slli a1, a1, 63
1101 ; RV64I-NEXT:    xor a0, a0, a1
1102 ; RV64I-NEXT:    mv a1, s0
1103 ; RV64I-NEXT:    call __subdf3@plt
1104 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1105 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1106 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1107 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1108 ; RV64I-NEXT:    addi sp, sp, 32
1109 ; RV64I-NEXT:    ret
1110   %a_ = fadd double 0.0, %a ; avoid negation using xor
1111   %b_ = fadd double 0.0, %b ; avoid negation using xor
1112   %c_ = fadd double 0.0, %c ; avoid negation using xor
1113   %1 = fmul contract double %a_, %b_
1114   %2 = fneg double %1
1115   %3 = fsub contract double %2, %c_
1116   ret double %3
1119 define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
1120 ; RV32IFD-LABEL: fnmsub_d_contract:
1121 ; RV32IFD:       # %bb.0:
1122 ; RV32IFD-NEXT:    fcvt.d.w ft0, zero
1123 ; RV32IFD-NEXT:    fadd.d ft1, fa0, ft0
1124 ; RV32IFD-NEXT:    fadd.d ft0, fa1, ft0
1125 ; RV32IFD-NEXT:    fnmsub.d fa0, ft1, ft0, fa2
1126 ; RV32IFD-NEXT:    ret
1128 ; RV64IFD-LABEL: fnmsub_d_contract:
1129 ; RV64IFD:       # %bb.0:
1130 ; RV64IFD-NEXT:    fmv.d.x ft0, zero
1131 ; RV64IFD-NEXT:    fadd.d ft1, fa0, ft0
1132 ; RV64IFD-NEXT:    fadd.d ft0, fa1, ft0
1133 ; RV64IFD-NEXT:    fnmsub.d fa0, ft1, ft0, fa2
1134 ; RV64IFD-NEXT:    ret
1136 ; RV32I-LABEL: fnmsub_d_contract:
1137 ; RV32I:       # %bb.0:
1138 ; RV32I-NEXT:    addi sp, sp, -32
1139 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1140 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1141 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1142 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1143 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1144 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1145 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
1146 ; RV32I-NEXT:    mv s0, a5
1147 ; RV32I-NEXT:    mv s1, a4
1148 ; RV32I-NEXT:    mv s2, a3
1149 ; RV32I-NEXT:    mv s3, a2
1150 ; RV32I-NEXT:    li a2, 0
1151 ; RV32I-NEXT:    li a3, 0
1152 ; RV32I-NEXT:    call __adddf3@plt
1153 ; RV32I-NEXT:    mv s4, a0
1154 ; RV32I-NEXT:    mv s5, a1
1155 ; RV32I-NEXT:    mv a0, s3
1156 ; RV32I-NEXT:    mv a1, s2
1157 ; RV32I-NEXT:    li a2, 0
1158 ; RV32I-NEXT:    li a3, 0
1159 ; RV32I-NEXT:    call __adddf3@plt
1160 ; RV32I-NEXT:    mv a2, a0
1161 ; RV32I-NEXT:    mv a3, a1
1162 ; RV32I-NEXT:    mv a0, s4
1163 ; RV32I-NEXT:    mv a1, s5
1164 ; RV32I-NEXT:    call __muldf3@plt
1165 ; RV32I-NEXT:    mv a2, a0
1166 ; RV32I-NEXT:    mv a3, a1
1167 ; RV32I-NEXT:    mv a0, s1
1168 ; RV32I-NEXT:    mv a1, s0
1169 ; RV32I-NEXT:    call __subdf3@plt
1170 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1171 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1172 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1173 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1174 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1175 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1176 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
1177 ; RV32I-NEXT:    addi sp, sp, 32
1178 ; RV32I-NEXT:    ret
1180 ; RV64I-LABEL: fnmsub_d_contract:
1181 ; RV64I:       # %bb.0:
1182 ; RV64I-NEXT:    addi sp, sp, -32
1183 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1184 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1185 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1186 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1187 ; RV64I-NEXT:    mv s0, a2
1188 ; RV64I-NEXT:    mv s1, a1
1189 ; RV64I-NEXT:    li a1, 0
1190 ; RV64I-NEXT:    call __adddf3@plt
1191 ; RV64I-NEXT:    mv s2, a0
1192 ; RV64I-NEXT:    mv a0, s1
1193 ; RV64I-NEXT:    li a1, 0
1194 ; RV64I-NEXT:    call __adddf3@plt
1195 ; RV64I-NEXT:    mv a1, a0
1196 ; RV64I-NEXT:    mv a0, s2
1197 ; RV64I-NEXT:    call __muldf3@plt
1198 ; RV64I-NEXT:    mv a1, a0
1199 ; RV64I-NEXT:    mv a0, s0
1200 ; RV64I-NEXT:    call __subdf3@plt
1201 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1202 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1203 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1204 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1205 ; RV64I-NEXT:    addi sp, sp, 32
1206 ; RV64I-NEXT:    ret
1207   %a_ = fadd double 0.0, %a ; avoid negation using xor
1208   %b_ = fadd double 0.0, %b ; avoid negation using xor
1209   %1 = fmul contract double %a_, %b_
1210   %2 = fsub contract double %c, %1
1211   ret double %2