[MLIR] Prevent invalid IR from being passed outside of RemoveDeadValues (#121079)
[llvm-project.git] / llvm / test / CodeGen / RISCV / GlobalISel / double-arith.ll
blobcb2037f5fb0271ee2e74a4a40cf8e21b888f0c97
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -global-isel -mattr=+d -verify-machineinstrs < %s \
3 ; RUN:   -target-abi=ilp32d | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s
4 ; RUN: llc -mtriple=riscv64 -global-isel -mattr=+d -verify-machineinstrs < %s \
5 ; RUN:   -target-abi=lp64d | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s
6 ; RUN: llc -mtriple=riscv32 -global-isel -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefix=RV32I %s
8 ; RUN: llc -mtriple=riscv64 -global-isel -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
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
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
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
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
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
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
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
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
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
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:    slli a1, a1, 1
165 ; RV32I-NEXT:    srli a1, a1, 1
166 ; RV32I-NEXT:    and a2, a3, a2
167 ; RV32I-NEXT:    or a1, a1, a2
168 ; RV32I-NEXT:    ret
170 ; RV64I-LABEL: fsgnj_d:
171 ; RV64I:       # %bb.0:
172 ; RV64I-NEXT:    slli a0, a0, 1
173 ; RV64I-NEXT:    srli a1, a1, 63
174 ; RV64I-NEXT:    srli a0, a0, 1
175 ; RV64I-NEXT:    slli a1, a1, 63
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 fa5, fa0, fa0
188 ; CHECKIFD-NEXT:    fneg.d fa4, fa5
189 ; CHECKIFD-NEXT:    feq.d a0, fa5, fa4
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
199 ; RV32I-NEXT:    lui a3, 524288
200 ; RV32I-NEXT:    xor a3, a1, a3
201 ; RV32I-NEXT:    mv a2, a0
202 ; RV32I-NEXT:    call __eqdf2
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
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
218 ; RV64I-NEXT:    sext.w a0, a0
219 ; RV64I-NEXT:    seqz a0, a0
220 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
221 ; RV64I-NEXT:    addi sp, sp, 16
222 ; RV64I-NEXT:    ret
223   %1 = fadd double %a, %a
224   %2 = fneg double %1
225   %3 = fcmp oeq double %1, %2
226   %4 = zext i1 %3 to i32
227   ret i32 %4
230 define double @fsgnjn_d(double %a, double %b) nounwind {
231 ; TODO: fsgnjn.s isn't selected on RV64 because DAGCombiner::visitBITCAST will
232 ; convert (bitconvert (fneg x)) to a xor.
234 ; CHECKIFD-LABEL: fsgnjn_d:
235 ; CHECKIFD:       # %bb.0:
236 ; CHECKIFD-NEXT:    fsgnjn.d fa0, fa0, fa1
237 ; CHECKIFD-NEXT:    ret
239 ; RV32I-LABEL: fsgnjn_d:
240 ; RV32I:       # %bb.0:
241 ; RV32I-NEXT:    lui a2, 524288
242 ; RV32I-NEXT:    slli a1, a1, 1
243 ; RV32I-NEXT:    xor a3, a3, a2
244 ; RV32I-NEXT:    srli a1, a1, 1
245 ; RV32I-NEXT:    and a2, a3, a2
246 ; RV32I-NEXT:    or a1, a1, a2
247 ; RV32I-NEXT:    ret
249 ; RV64I-LABEL: fsgnjn_d:
250 ; RV64I:       # %bb.0:
251 ; RV64I-NEXT:    li a2, -1
252 ; RV64I-NEXT:    slli a0, a0, 1
253 ; RV64I-NEXT:    slli a2, a2, 63
254 ; RV64I-NEXT:    xor a1, a1, a2
255 ; RV64I-NEXT:    srli a0, a0, 1
256 ; RV64I-NEXT:    and a1, a1, a2
257 ; RV64I-NEXT:    or a0, a0, a1
258 ; RV64I-NEXT:    ret
259   %1 = fneg double %b
260   %2 = call double @llvm.copysign.f64(double %a, double %1)
261   ret double %2
264 declare double @llvm.fabs.f64(double)
266 ; This function performs extra work to ensure that
267 ; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
268 define double @fabs_d(double %a, double %b) nounwind {
269 ; CHECKIFD-LABEL: fabs_d:
270 ; CHECKIFD:       # %bb.0:
271 ; CHECKIFD-NEXT:    fadd.d fa5, fa0, fa1
272 ; CHECKIFD-NEXT:    fabs.d fa4, fa5
273 ; CHECKIFD-NEXT:    fadd.d fa0, fa4, fa5
274 ; CHECKIFD-NEXT:    ret
276 ; RV32I-LABEL: fabs_d:
277 ; RV32I:       # %bb.0:
278 ; RV32I-NEXT:    addi sp, sp, -16
279 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
280 ; RV32I-NEXT:    call __adddf3
281 ; RV32I-NEXT:    mv a3, a1
282 ; RV32I-NEXT:    slli a1, a1, 1
283 ; RV32I-NEXT:    srli a1, a1, 1
284 ; RV32I-NEXT:    mv a2, a0
285 ; RV32I-NEXT:    call __adddf3
286 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
287 ; RV32I-NEXT:    addi sp, sp, 16
288 ; RV32I-NEXT:    ret
290 ; RV64I-LABEL: fabs_d:
291 ; RV64I:       # %bb.0:
292 ; RV64I-NEXT:    addi sp, sp, -16
293 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
294 ; RV64I-NEXT:    call __adddf3
295 ; RV64I-NEXT:    mv a1, a0
296 ; RV64I-NEXT:    slli a0, a0, 1
297 ; RV64I-NEXT:    srli a0, a0, 1
298 ; RV64I-NEXT:    call __adddf3
299 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
300 ; RV64I-NEXT:    addi sp, sp, 16
301 ; RV64I-NEXT:    ret
302   %1 = fadd double %a, %b
303   %2 = call double @llvm.fabs.f64(double %1)
304   %3 = fadd double %2, %1
305   ret double %3
308 declare double @llvm.minnum.f64(double, double)
310 define double @fmin_d(double %a, double %b) nounwind {
311 ; CHECKIFD-LABEL: fmin_d:
312 ; CHECKIFD:       # %bb.0:
313 ; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa1
314 ; CHECKIFD-NEXT:    ret
316 ; RV32I-LABEL: fmin_d:
317 ; RV32I:       # %bb.0:
318 ; RV32I-NEXT:    addi sp, sp, -16
319 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
320 ; RV32I-NEXT:    call fmin
321 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
322 ; RV32I-NEXT:    addi sp, sp, 16
323 ; RV32I-NEXT:    ret
325 ; RV64I-LABEL: fmin_d:
326 ; RV64I:       # %bb.0:
327 ; RV64I-NEXT:    addi sp, sp, -16
328 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
329 ; RV64I-NEXT:    call fmin
330 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
331 ; RV64I-NEXT:    addi sp, sp, 16
332 ; RV64I-NEXT:    ret
333   %1 = call double @llvm.minnum.f64(double %a, double %b)
334   ret double %1
337 declare double @llvm.maxnum.f64(double, double)
339 define double @fmax_d(double %a, double %b) nounwind {
340 ; CHECKIFD-LABEL: fmax_d:
341 ; CHECKIFD:       # %bb.0:
342 ; CHECKIFD-NEXT:    fmax.d fa0, fa0, fa1
343 ; CHECKIFD-NEXT:    ret
345 ; RV32I-LABEL: fmax_d:
346 ; RV32I:       # %bb.0:
347 ; RV32I-NEXT:    addi sp, sp, -16
348 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
349 ; RV32I-NEXT:    call fmax
350 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
351 ; RV32I-NEXT:    addi sp, sp, 16
352 ; RV32I-NEXT:    ret
354 ; RV64I-LABEL: fmax_d:
355 ; RV64I:       # %bb.0:
356 ; RV64I-NEXT:    addi sp, sp, -16
357 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
358 ; RV64I-NEXT:    call fmax
359 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
360 ; RV64I-NEXT:    addi sp, sp, 16
361 ; RV64I-NEXT:    ret
362   %1 = call double @llvm.maxnum.f64(double %a, double %b)
363   ret double %1
366 declare double @llvm.fma.f64(double, double, double)
368 define double @fmadd_d(double %a, double %b, double %c) nounwind {
369 ; CHECKIFD-LABEL: fmadd_d:
370 ; CHECKIFD:       # %bb.0:
371 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
372 ; CHECKIFD-NEXT:    ret
374 ; RV32I-LABEL: fmadd_d:
375 ; RV32I:       # %bb.0:
376 ; RV32I-NEXT:    addi sp, sp, -16
377 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
378 ; RV32I-NEXT:    call fma
379 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
380 ; RV32I-NEXT:    addi sp, sp, 16
381 ; RV32I-NEXT:    ret
383 ; RV64I-LABEL: fmadd_d:
384 ; RV64I:       # %bb.0:
385 ; RV64I-NEXT:    addi sp, sp, -16
386 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
387 ; RV64I-NEXT:    call fma
388 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
389 ; RV64I-NEXT:    addi sp, sp, 16
390 ; RV64I-NEXT:    ret
391   %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
392   ret double %1
395 define double @fmsub_d(double %a, double %b, double %c) nounwind {
396 ; RV32IFD-LABEL: fmsub_d:
397 ; RV32IFD:       # %bb.0:
398 ; RV32IFD-NEXT:    addi sp, sp, -16
399 ; RV32IFD-NEXT:    sw zero, 8(sp)
400 ; RV32IFD-NEXT:    sw zero, 12(sp)
401 ; RV32IFD-NEXT:    fld fa5, 8(sp)
402 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
403 ; RV32IFD-NEXT:    fmsub.d fa0, fa0, fa1, fa5
404 ; RV32IFD-NEXT:    addi sp, sp, 16
405 ; RV32IFD-NEXT:    ret
407 ; RV64IFD-LABEL: fmsub_d:
408 ; RV64IFD:       # %bb.0:
409 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
410 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
411 ; RV64IFD-NEXT:    fmsub.d fa0, fa0, fa1, fa5
412 ; RV64IFD-NEXT:    ret
414 ; RV32I-LABEL: fmsub_d:
415 ; RV32I:       # %bb.0:
416 ; RV32I-NEXT:    addi sp, sp, -32
417 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
418 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
419 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
420 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
421 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
422 ; RV32I-NEXT:    mv s0, a0
423 ; RV32I-NEXT:    mv s1, a1
424 ; RV32I-NEXT:    mv s2, a2
425 ; RV32I-NEXT:    mv s3, a3
426 ; RV32I-NEXT:    mv a0, a4
427 ; RV32I-NEXT:    lui a1, %hi(.LCPI12_0)
428 ; RV32I-NEXT:    addi a1, a1, %lo(.LCPI12_0)
429 ; RV32I-NEXT:    lw a2, 0(a1)
430 ; RV32I-NEXT:    lw a3, 4(a1)
431 ; RV32I-NEXT:    mv a1, a5
432 ; RV32I-NEXT:    call __adddf3
433 ; RV32I-NEXT:    mv a4, a0
434 ; RV32I-NEXT:    lui a5, 524288
435 ; RV32I-NEXT:    xor a5, a1, a5
436 ; RV32I-NEXT:    mv a0, s0
437 ; RV32I-NEXT:    mv a1, s1
438 ; RV32I-NEXT:    mv a2, s2
439 ; RV32I-NEXT:    mv a3, s3
440 ; RV32I-NEXT:    call fma
441 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
442 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
443 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
444 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
445 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
446 ; RV32I-NEXT:    addi sp, sp, 32
447 ; RV32I-NEXT:    ret
449 ; RV64I-LABEL: fmsub_d:
450 ; RV64I:       # %bb.0:
451 ; RV64I-NEXT:    addi sp, sp, -32
452 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
453 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
454 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
455 ; RV64I-NEXT:    mv s0, a0
456 ; RV64I-NEXT:    mv s1, a1
457 ; RV64I-NEXT:    lui a0, %hi(.LCPI12_0)
458 ; RV64I-NEXT:    ld a1, %lo(.LCPI12_0)(a0)
459 ; RV64I-NEXT:    mv a0, a2
460 ; RV64I-NEXT:    call __adddf3
461 ; RV64I-NEXT:    li a1, -1
462 ; RV64I-NEXT:    slli a1, a1, 63
463 ; RV64I-NEXT:    xor a2, a0, a1
464 ; RV64I-NEXT:    mv a0, s0
465 ; RV64I-NEXT:    mv a1, s1
466 ; RV64I-NEXT:    call fma
467 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
468 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
469 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
470 ; RV64I-NEXT:    addi sp, sp, 32
471 ; RV64I-NEXT:    ret
472   %c_ = fadd double 0.0, %c ; avoid negation using xor
473   %negc = fneg double %c_
474   %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
475   ret double %1
478 define double @fnmadd_d(double %a, double %b, double %c) nounwind {
479 ; RV32IFD-LABEL: fnmadd_d:
480 ; RV32IFD:       # %bb.0:
481 ; RV32IFD-NEXT:    addi sp, sp, -16
482 ; RV32IFD-NEXT:    sw zero, 8(sp)
483 ; RV32IFD-NEXT:    sw zero, 12(sp)
484 ; RV32IFD-NEXT:    fld fa5, 8(sp)
485 ; RV32IFD-NEXT:    fadd.d fa4, fa0, fa5
486 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
487 ; RV32IFD-NEXT:    fnmadd.d fa0, fa4, fa1, fa5
488 ; RV32IFD-NEXT:    addi sp, sp, 16
489 ; RV32IFD-NEXT:    ret
491 ; RV64IFD-LABEL: fnmadd_d:
492 ; RV64IFD:       # %bb.0:
493 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
494 ; RV64IFD-NEXT:    fadd.d fa4, fa0, fa5
495 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
496 ; RV64IFD-NEXT:    fnmadd.d fa0, fa4, fa1, fa5
497 ; RV64IFD-NEXT:    ret
499 ; RV32I-LABEL: fnmadd_d:
500 ; RV32I:       # %bb.0:
501 ; RV32I-NEXT:    addi sp, sp, -48
502 ; RV32I-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
503 ; RV32I-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
504 ; RV32I-NEXT:    sw s1, 36(sp) # 4-byte Folded Spill
505 ; RV32I-NEXT:    sw s2, 32(sp) # 4-byte Folded Spill
506 ; RV32I-NEXT:    sw s3, 28(sp) # 4-byte Folded Spill
507 ; RV32I-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
508 ; RV32I-NEXT:    sw s5, 20(sp) # 4-byte Folded Spill
509 ; RV32I-NEXT:    sw s6, 16(sp) # 4-byte Folded Spill
510 ; RV32I-NEXT:    sw s7, 12(sp) # 4-byte Folded Spill
511 ; RV32I-NEXT:    mv s0, a2
512 ; RV32I-NEXT:    mv s1, a3
513 ; RV32I-NEXT:    mv s2, a4
514 ; RV32I-NEXT:    lui a2, %hi(.LCPI13_0)
515 ; RV32I-NEXT:    addi a2, a2, %lo(.LCPI13_0)
516 ; RV32I-NEXT:    lw s3, 0(a2)
517 ; RV32I-NEXT:    lw s4, 4(a2)
518 ; RV32I-NEXT:    mv s5, a5
519 ; RV32I-NEXT:    mv a2, s3
520 ; RV32I-NEXT:    mv a3, s4
521 ; RV32I-NEXT:    call __adddf3
522 ; RV32I-NEXT:    mv s6, a0
523 ; RV32I-NEXT:    mv s7, a1
524 ; RV32I-NEXT:    mv a0, s2
525 ; RV32I-NEXT:    mv a1, s5
526 ; RV32I-NEXT:    mv a2, s3
527 ; RV32I-NEXT:    mv a3, s4
528 ; RV32I-NEXT:    call __adddf3
529 ; RV32I-NEXT:    mv a4, a0
530 ; RV32I-NEXT:    lui a5, 524288
531 ; RV32I-NEXT:    xor a2, s7, a5
532 ; RV32I-NEXT:    xor a5, a1, a5
533 ; RV32I-NEXT:    mv a0, s6
534 ; RV32I-NEXT:    mv a1, a2
535 ; RV32I-NEXT:    mv a2, s0
536 ; RV32I-NEXT:    mv a3, s1
537 ; RV32I-NEXT:    call fma
538 ; RV32I-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
539 ; RV32I-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
540 ; RV32I-NEXT:    lw s1, 36(sp) # 4-byte Folded Reload
541 ; RV32I-NEXT:    lw s2, 32(sp) # 4-byte Folded Reload
542 ; RV32I-NEXT:    lw s3, 28(sp) # 4-byte Folded Reload
543 ; RV32I-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
544 ; RV32I-NEXT:    lw s5, 20(sp) # 4-byte Folded Reload
545 ; RV32I-NEXT:    lw s6, 16(sp) # 4-byte Folded Reload
546 ; RV32I-NEXT:    lw s7, 12(sp) # 4-byte Folded Reload
547 ; RV32I-NEXT:    addi sp, sp, 48
548 ; RV32I-NEXT:    ret
550 ; RV64I-LABEL: fnmadd_d:
551 ; RV64I:       # %bb.0:
552 ; RV64I-NEXT:    addi sp, sp, -48
553 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
554 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
555 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
556 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
557 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
558 ; RV64I-NEXT:    mv s0, a1
559 ; RV64I-NEXT:    lui a1, %hi(.LCPI13_0)
560 ; RV64I-NEXT:    ld s1, %lo(.LCPI13_0)(a1)
561 ; RV64I-NEXT:    mv s2, a2
562 ; RV64I-NEXT:    mv a1, s1
563 ; RV64I-NEXT:    call __adddf3
564 ; RV64I-NEXT:    mv s3, a0
565 ; RV64I-NEXT:    mv a0, s2
566 ; RV64I-NEXT:    mv a1, s1
567 ; RV64I-NEXT:    call __adddf3
568 ; RV64I-NEXT:    li a1, -1
569 ; RV64I-NEXT:    slli a2, a1, 63
570 ; RV64I-NEXT:    xor a1, s3, a2
571 ; RV64I-NEXT:    xor a2, a0, a2
572 ; RV64I-NEXT:    mv a0, a1
573 ; RV64I-NEXT:    mv a1, s0
574 ; RV64I-NEXT:    call fma
575 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
576 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
577 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
578 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
579 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
580 ; RV64I-NEXT:    addi sp, sp, 48
581 ; RV64I-NEXT:    ret
582   %a_ = fadd double 0.0, %a
583   %c_ = fadd double 0.0, %c
584   %nega = fneg double %a_
585   %negc = fneg double %c_
586   %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
587   ret double %1
590 define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
591 ; RV32IFD-LABEL: fnmadd_d_2:
592 ; RV32IFD:       # %bb.0:
593 ; RV32IFD-NEXT:    addi sp, sp, -16
594 ; RV32IFD-NEXT:    sw zero, 8(sp)
595 ; RV32IFD-NEXT:    sw zero, 12(sp)
596 ; RV32IFD-NEXT:    fld fa5, 8(sp)
597 ; RV32IFD-NEXT:    fadd.d fa4, fa1, fa5
598 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
599 ; RV32IFD-NEXT:    fnmadd.d fa0, fa4, fa0, fa5
600 ; RV32IFD-NEXT:    addi sp, sp, 16
601 ; RV32IFD-NEXT:    ret
603 ; RV64IFD-LABEL: fnmadd_d_2:
604 ; RV64IFD:       # %bb.0:
605 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
606 ; RV64IFD-NEXT:    fadd.d fa4, fa1, fa5
607 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
608 ; RV64IFD-NEXT:    fnmadd.d fa0, fa4, fa0, fa5
609 ; RV64IFD-NEXT:    ret
611 ; RV32I-LABEL: fnmadd_d_2:
612 ; RV32I:       # %bb.0:
613 ; RV32I-NEXT:    addi sp, sp, -48
614 ; RV32I-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
615 ; RV32I-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
616 ; RV32I-NEXT:    sw s1, 36(sp) # 4-byte Folded Spill
617 ; RV32I-NEXT:    sw s2, 32(sp) # 4-byte Folded Spill
618 ; RV32I-NEXT:    sw s3, 28(sp) # 4-byte Folded Spill
619 ; RV32I-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
620 ; RV32I-NEXT:    sw s5, 20(sp) # 4-byte Folded Spill
621 ; RV32I-NEXT:    sw s6, 16(sp) # 4-byte Folded Spill
622 ; RV32I-NEXT:    sw s7, 12(sp) # 4-byte Folded Spill
623 ; RV32I-NEXT:    mv s0, a0
624 ; RV32I-NEXT:    mv s1, a1
625 ; RV32I-NEXT:    mv a0, a2
626 ; RV32I-NEXT:    mv a1, a3
627 ; RV32I-NEXT:    mv s2, a4
628 ; RV32I-NEXT:    lui a2, %hi(.LCPI14_0)
629 ; RV32I-NEXT:    addi a2, a2, %lo(.LCPI14_0)
630 ; RV32I-NEXT:    lw s3, 0(a2)
631 ; RV32I-NEXT:    lw s4, 4(a2)
632 ; RV32I-NEXT:    mv s5, a5
633 ; RV32I-NEXT:    mv a2, s3
634 ; RV32I-NEXT:    mv a3, s4
635 ; RV32I-NEXT:    call __adddf3
636 ; RV32I-NEXT:    mv s6, a0
637 ; RV32I-NEXT:    mv s7, a1
638 ; RV32I-NEXT:    mv a0, s2
639 ; RV32I-NEXT:    mv a1, s5
640 ; RV32I-NEXT:    mv a2, s3
641 ; RV32I-NEXT:    mv a3, s4
642 ; RV32I-NEXT:    call __adddf3
643 ; RV32I-NEXT:    mv a4, a0
644 ; RV32I-NEXT:    lui a5, 524288
645 ; RV32I-NEXT:    xor a3, s7, a5
646 ; RV32I-NEXT:    xor a5, a1, a5
647 ; RV32I-NEXT:    mv a0, s0
648 ; RV32I-NEXT:    mv a1, s1
649 ; RV32I-NEXT:    mv a2, s6
650 ; RV32I-NEXT:    call fma
651 ; RV32I-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
652 ; RV32I-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
653 ; RV32I-NEXT:    lw s1, 36(sp) # 4-byte Folded Reload
654 ; RV32I-NEXT:    lw s2, 32(sp) # 4-byte Folded Reload
655 ; RV32I-NEXT:    lw s3, 28(sp) # 4-byte Folded Reload
656 ; RV32I-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
657 ; RV32I-NEXT:    lw s5, 20(sp) # 4-byte Folded Reload
658 ; RV32I-NEXT:    lw s6, 16(sp) # 4-byte Folded Reload
659 ; RV32I-NEXT:    lw s7, 12(sp) # 4-byte Folded Reload
660 ; RV32I-NEXT:    addi sp, sp, 48
661 ; RV32I-NEXT:    ret
663 ; RV64I-LABEL: fnmadd_d_2:
664 ; RV64I:       # %bb.0:
665 ; RV64I-NEXT:    addi sp, sp, -48
666 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
667 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
668 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
669 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
670 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
671 ; RV64I-NEXT:    mv s0, a0
672 ; RV64I-NEXT:    mv a0, a1
673 ; RV64I-NEXT:    lui a1, %hi(.LCPI14_0)
674 ; RV64I-NEXT:    ld s1, %lo(.LCPI14_0)(a1)
675 ; RV64I-NEXT:    mv s2, a2
676 ; RV64I-NEXT:    mv a1, s1
677 ; RV64I-NEXT:    call __adddf3
678 ; RV64I-NEXT:    mv s3, a0
679 ; RV64I-NEXT:    mv a0, s2
680 ; RV64I-NEXT:    mv a1, s1
681 ; RV64I-NEXT:    call __adddf3
682 ; RV64I-NEXT:    li a1, -1
683 ; RV64I-NEXT:    slli a2, a1, 63
684 ; RV64I-NEXT:    xor a1, s3, a2
685 ; RV64I-NEXT:    xor a2, a0, a2
686 ; RV64I-NEXT:    mv a0, s0
687 ; RV64I-NEXT:    call fma
688 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
689 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
690 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
691 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
692 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
693 ; RV64I-NEXT:    addi sp, sp, 48
694 ; RV64I-NEXT:    ret
695   %b_ = fadd double 0.0, %b
696   %c_ = fadd double 0.0, %c
697   %negb = fneg double %b_
698   %negc = fneg double %c_
699   %1 = call double @llvm.fma.f64(double %a, double %negb, double %negc)
700   ret double %1
703 define double @fnmadd_d_3(double %a, double %b, double %c) nounwind {
704 ; CHECKIFD-LABEL: fnmadd_d_3:
705 ; CHECKIFD:       # %bb.0:
706 ; CHECKIFD-NEXT:    fmadd.d fa5, fa0, fa1, fa2
707 ; CHECKIFD-NEXT:    fneg.d fa0, fa5
708 ; CHECKIFD-NEXT:    ret
710 ; RV32I-LABEL: fnmadd_d_3:
711 ; RV32I:       # %bb.0:
712 ; RV32I-NEXT:    addi sp, sp, -16
713 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
714 ; RV32I-NEXT:    call fma
715 ; RV32I-NEXT:    lui a2, 524288
716 ; RV32I-NEXT:    xor a1, a1, a2
717 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
718 ; RV32I-NEXT:    addi sp, sp, 16
719 ; RV32I-NEXT:    ret
721 ; RV64I-LABEL: fnmadd_d_3:
722 ; RV64I:       # %bb.0:
723 ; RV64I-NEXT:    addi sp, sp, -16
724 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
725 ; RV64I-NEXT:    call fma
726 ; RV64I-NEXT:    li a1, -1
727 ; RV64I-NEXT:    slli a1, a1, 63
728 ; RV64I-NEXT:    xor a0, a0, a1
729 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
730 ; RV64I-NEXT:    addi sp, sp, 16
731 ; RV64I-NEXT:    ret
732   %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
733   %neg = fneg double %1
734   ret double %neg
738 define double @fnmadd_nsz(double %a, double %b, double %c) nounwind {
739 ; CHECKIFD-LABEL: fnmadd_nsz:
740 ; CHECKIFD:       # %bb.0:
741 ; CHECKIFD-NEXT:    fmadd.d fa5, fa0, fa1, fa2
742 ; CHECKIFD-NEXT:    fneg.d fa0, fa5
743 ; CHECKIFD-NEXT:    ret
745 ; RV32I-LABEL: fnmadd_nsz:
746 ; RV32I:       # %bb.0:
747 ; RV32I-NEXT:    addi sp, sp, -16
748 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
749 ; RV32I-NEXT:    call fma
750 ; RV32I-NEXT:    lui a2, 524288
751 ; RV32I-NEXT:    xor a1, a1, a2
752 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
753 ; RV32I-NEXT:    addi sp, sp, 16
754 ; RV32I-NEXT:    ret
756 ; RV64I-LABEL: fnmadd_nsz:
757 ; RV64I:       # %bb.0:
758 ; RV64I-NEXT:    addi sp, sp, -16
759 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
760 ; RV64I-NEXT:    call fma
761 ; RV64I-NEXT:    li a1, -1
762 ; RV64I-NEXT:    slli a1, a1, 63
763 ; RV64I-NEXT:    xor a0, a0, a1
764 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
765 ; RV64I-NEXT:    addi sp, sp, 16
766 ; RV64I-NEXT:    ret
767   %1 = call nsz double @llvm.fma.f64(double %a, double %b, double %c)
768   %neg = fneg nsz double %1
769   ret double %neg
772 define double @fnmsub_d(double %a, double %b, double %c) nounwind {
773 ; RV32IFD-LABEL: fnmsub_d:
774 ; RV32IFD:       # %bb.0:
775 ; RV32IFD-NEXT:    addi sp, sp, -16
776 ; RV32IFD-NEXT:    sw zero, 8(sp)
777 ; RV32IFD-NEXT:    sw zero, 12(sp)
778 ; RV32IFD-NEXT:    fld fa5, 8(sp)
779 ; RV32IFD-NEXT:    fadd.d fa5, fa0, fa5
780 ; RV32IFD-NEXT:    fnmsub.d fa0, fa5, fa1, fa2
781 ; RV32IFD-NEXT:    addi sp, sp, 16
782 ; RV32IFD-NEXT:    ret
784 ; RV64IFD-LABEL: fnmsub_d:
785 ; RV64IFD:       # %bb.0:
786 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
787 ; RV64IFD-NEXT:    fadd.d fa5, fa0, fa5
788 ; RV64IFD-NEXT:    fnmsub.d fa0, fa5, fa1, fa2
789 ; RV64IFD-NEXT:    ret
791 ; RV32I-LABEL: fnmsub_d:
792 ; RV32I:       # %bb.0:
793 ; RV32I-NEXT:    addi sp, sp, -32
794 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
795 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
796 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
797 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
798 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
799 ; RV32I-NEXT:    mv s0, a2
800 ; RV32I-NEXT:    mv s1, a3
801 ; RV32I-NEXT:    mv s2, a4
802 ; RV32I-NEXT:    lui a2, %hi(.LCPI17_0)
803 ; RV32I-NEXT:    addi a3, a2, %lo(.LCPI17_0)
804 ; RV32I-NEXT:    lw a2, 0(a3)
805 ; RV32I-NEXT:    lw a3, 4(a3)
806 ; RV32I-NEXT:    mv s3, a5
807 ; RV32I-NEXT:    call __adddf3
808 ; RV32I-NEXT:    lui a2, 524288
809 ; RV32I-NEXT:    xor a1, a1, a2
810 ; RV32I-NEXT:    mv a2, s0
811 ; RV32I-NEXT:    mv a3, s1
812 ; RV32I-NEXT:    mv a4, s2
813 ; RV32I-NEXT:    mv a5, s3
814 ; RV32I-NEXT:    call fma
815 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
816 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
817 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
818 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
819 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
820 ; RV32I-NEXT:    addi sp, sp, 32
821 ; RV32I-NEXT:    ret
823 ; RV64I-LABEL: fnmsub_d:
824 ; RV64I:       # %bb.0:
825 ; RV64I-NEXT:    addi sp, sp, -32
826 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
827 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
828 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
829 ; RV64I-NEXT:    mv s0, a1
830 ; RV64I-NEXT:    lui a1, %hi(.LCPI17_0)
831 ; RV64I-NEXT:    ld a1, %lo(.LCPI17_0)(a1)
832 ; RV64I-NEXT:    mv s1, a2
833 ; RV64I-NEXT:    call __adddf3
834 ; RV64I-NEXT:    li a1, -1
835 ; RV64I-NEXT:    slli a1, a1, 63
836 ; RV64I-NEXT:    xor a0, a0, a1
837 ; RV64I-NEXT:    mv a1, s0
838 ; RV64I-NEXT:    mv a2, s1
839 ; RV64I-NEXT:    call fma
840 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
841 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
842 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
843 ; RV64I-NEXT:    addi sp, sp, 32
844 ; RV64I-NEXT:    ret
845   %a_ = fadd double 0.0, %a
846   %nega = fneg double %a_
847   %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
848   ret double %1
851 define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
852 ; RV32IFD-LABEL: fnmsub_d_2:
853 ; RV32IFD:       # %bb.0:
854 ; RV32IFD-NEXT:    addi sp, sp, -16
855 ; RV32IFD-NEXT:    sw zero, 8(sp)
856 ; RV32IFD-NEXT:    sw zero, 12(sp)
857 ; RV32IFD-NEXT:    fld fa5, 8(sp)
858 ; RV32IFD-NEXT:    fadd.d fa5, fa1, fa5
859 ; RV32IFD-NEXT:    fnmsub.d fa0, fa5, fa0, fa2
860 ; RV32IFD-NEXT:    addi sp, sp, 16
861 ; RV32IFD-NEXT:    ret
863 ; RV64IFD-LABEL: fnmsub_d_2:
864 ; RV64IFD:       # %bb.0:
865 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
866 ; RV64IFD-NEXT:    fadd.d fa5, fa1, fa5
867 ; RV64IFD-NEXT:    fnmsub.d fa0, fa5, fa0, fa2
868 ; RV64IFD-NEXT:    ret
870 ; RV32I-LABEL: fnmsub_d_2:
871 ; RV32I:       # %bb.0:
872 ; RV32I-NEXT:    addi sp, sp, -32
873 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
874 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
875 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
876 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
877 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
878 ; RV32I-NEXT:    mv s0, a0
879 ; RV32I-NEXT:    mv s1, a1
880 ; RV32I-NEXT:    mv a0, a2
881 ; RV32I-NEXT:    mv a1, a3
882 ; RV32I-NEXT:    mv s2, a4
883 ; RV32I-NEXT:    lui a2, %hi(.LCPI18_0)
884 ; RV32I-NEXT:    addi a3, a2, %lo(.LCPI18_0)
885 ; RV32I-NEXT:    lw a2, 0(a3)
886 ; RV32I-NEXT:    lw a3, 4(a3)
887 ; RV32I-NEXT:    mv s3, a5
888 ; RV32I-NEXT:    call __adddf3
889 ; RV32I-NEXT:    mv a2, a0
890 ; RV32I-NEXT:    lui a3, 524288
891 ; RV32I-NEXT:    xor a3, a1, a3
892 ; RV32I-NEXT:    mv a0, s0
893 ; RV32I-NEXT:    mv a1, s1
894 ; RV32I-NEXT:    mv a4, s2
895 ; RV32I-NEXT:    mv a5, s3
896 ; RV32I-NEXT:    call fma
897 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
898 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
899 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
900 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
901 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
902 ; RV32I-NEXT:    addi sp, sp, 32
903 ; RV32I-NEXT:    ret
905 ; RV64I-LABEL: fnmsub_d_2:
906 ; RV64I:       # %bb.0:
907 ; RV64I-NEXT:    addi sp, sp, -32
908 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
909 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
910 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
911 ; RV64I-NEXT:    mv s0, a0
912 ; RV64I-NEXT:    mv a0, a1
913 ; RV64I-NEXT:    lui a1, %hi(.LCPI18_0)
914 ; RV64I-NEXT:    ld a1, %lo(.LCPI18_0)(a1)
915 ; RV64I-NEXT:    mv s1, a2
916 ; RV64I-NEXT:    call __adddf3
917 ; RV64I-NEXT:    li a1, -1
918 ; RV64I-NEXT:    slli a1, a1, 63
919 ; RV64I-NEXT:    xor a1, a0, a1
920 ; RV64I-NEXT:    mv a0, s0
921 ; RV64I-NEXT:    mv a2, s1
922 ; RV64I-NEXT:    call fma
923 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
924 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
925 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
926 ; RV64I-NEXT:    addi sp, sp, 32
927 ; RV64I-NEXT:    ret
928   %b_ = fadd double 0.0, %b
929   %negb = fneg double %b_
930   %1 = call double @llvm.fma.f64(double %a, double %negb, double %c)
931   ret double %1
934 define double @fmadd_d_contract(double %a, double %b, double %c) nounwind {
935 ; CHECKIFD-LABEL: fmadd_d_contract:
936 ; CHECKIFD:       # %bb.0:
937 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
938 ; CHECKIFD-NEXT:    ret
940 ; RV32I-LABEL: fmadd_d_contract:
941 ; RV32I:       # %bb.0:
942 ; RV32I-NEXT:    addi sp, sp, -16
943 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
944 ; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
945 ; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
946 ; RV32I-NEXT:    mv s0, a4
947 ; RV32I-NEXT:    mv s1, a5
948 ; RV32I-NEXT:    call __muldf3
949 ; RV32I-NEXT:    mv a2, s0
950 ; RV32I-NEXT:    mv a3, s1
951 ; RV32I-NEXT:    call __adddf3
952 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
953 ; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
954 ; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
955 ; RV32I-NEXT:    addi sp, sp, 16
956 ; RV32I-NEXT:    ret
958 ; RV64I-LABEL: fmadd_d_contract:
959 ; RV64I:       # %bb.0:
960 ; RV64I-NEXT:    addi sp, sp, -16
961 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
962 ; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
963 ; RV64I-NEXT:    mv s0, a2
964 ; RV64I-NEXT:    call __muldf3
965 ; RV64I-NEXT:    mv a1, s0
966 ; RV64I-NEXT:    call __adddf3
967 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
968 ; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
969 ; RV64I-NEXT:    addi sp, sp, 16
970 ; RV64I-NEXT:    ret
971   %1 = fmul contract double %a, %b
972   %2 = fadd contract double %1, %c
973   ret double %2
976 define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
977 ; RV32IFD-LABEL: fmsub_d_contract:
978 ; RV32IFD:       # %bb.0:
979 ; RV32IFD-NEXT:    addi sp, sp, -16
980 ; RV32IFD-NEXT:    sw zero, 8(sp)
981 ; RV32IFD-NEXT:    sw zero, 12(sp)
982 ; RV32IFD-NEXT:    fld fa5, 8(sp)
983 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
984 ; RV32IFD-NEXT:    fmul.d fa4, fa0, fa1
985 ; RV32IFD-NEXT:    fsub.d fa0, fa4, fa5
986 ; RV32IFD-NEXT:    addi sp, sp, 16
987 ; RV32IFD-NEXT:    ret
989 ; RV64IFD-LABEL: fmsub_d_contract:
990 ; RV64IFD:       # %bb.0:
991 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
992 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
993 ; RV64IFD-NEXT:    fmul.d fa4, fa0, fa1
994 ; RV64IFD-NEXT:    fsub.d fa0, fa4, fa5
995 ; RV64IFD-NEXT:    ret
997 ; RV32I-LABEL: fmsub_d_contract:
998 ; RV32I:       # %bb.0:
999 ; RV32I-NEXT:    addi sp, sp, -32
1000 ; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1001 ; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1002 ; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1003 ; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1004 ; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1005 ; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1006 ; RV32I-NEXT:    sw s5, 4(sp) # 4-byte Folded Spill
1007 ; RV32I-NEXT:    mv s0, a0
1008 ; RV32I-NEXT:    mv s1, a1
1009 ; RV32I-NEXT:    mv s2, a2
1010 ; RV32I-NEXT:    mv s3, a3
1011 ; RV32I-NEXT:    mv a0, a4
1012 ; RV32I-NEXT:    lui a1, %hi(.LCPI20_0)
1013 ; RV32I-NEXT:    addi a1, a1, %lo(.LCPI20_0)
1014 ; RV32I-NEXT:    lw a2, 0(a1)
1015 ; RV32I-NEXT:    lw a3, 4(a1)
1016 ; RV32I-NEXT:    mv a1, a5
1017 ; RV32I-NEXT:    call __adddf3
1018 ; RV32I-NEXT:    mv s4, a0
1019 ; RV32I-NEXT:    mv s5, a1
1020 ; RV32I-NEXT:    mv a0, s0
1021 ; RV32I-NEXT:    mv a1, s1
1022 ; RV32I-NEXT:    mv a2, s2
1023 ; RV32I-NEXT:    mv a3, s3
1024 ; RV32I-NEXT:    call __muldf3
1025 ; RV32I-NEXT:    mv a2, s4
1026 ; RV32I-NEXT:    mv a3, s5
1027 ; RV32I-NEXT:    call __subdf3
1028 ; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1029 ; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1030 ; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1031 ; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1032 ; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1033 ; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1034 ; RV32I-NEXT:    lw s5, 4(sp) # 4-byte Folded Reload
1035 ; RV32I-NEXT:    addi sp, sp, 32
1036 ; RV32I-NEXT:    ret
1038 ; RV64I-LABEL: fmsub_d_contract:
1039 ; RV64I:       # %bb.0:
1040 ; RV64I-NEXT:    addi sp, sp, -32
1041 ; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1042 ; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1043 ; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1044 ; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1045 ; RV64I-NEXT:    mv s0, a0
1046 ; RV64I-NEXT:    mv s1, a1
1047 ; RV64I-NEXT:    lui a0, %hi(.LCPI20_0)
1048 ; RV64I-NEXT:    ld a1, %lo(.LCPI20_0)(a0)
1049 ; RV64I-NEXT:    mv a0, a2
1050 ; RV64I-NEXT:    call __adddf3
1051 ; RV64I-NEXT:    mv s2, a0
1052 ; RV64I-NEXT:    mv a0, s0
1053 ; RV64I-NEXT:    mv a1, s1
1054 ; RV64I-NEXT:    call __muldf3
1055 ; RV64I-NEXT:    mv a1, s2
1056 ; RV64I-NEXT:    call __subdf3
1057 ; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1058 ; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1059 ; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1060 ; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1061 ; RV64I-NEXT:    addi sp, sp, 32
1062 ; RV64I-NEXT:    ret
1063   %c_ = fadd double 0.0, %c ; avoid negation using xor
1064   %1 = fmul contract double %a, %b
1065   %2 = fsub contract double %1, %c_
1066   ret double %2
1069 define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
1070 ; RV32IFD-LABEL: fnmadd_d_contract:
1071 ; RV32IFD:       # %bb.0:
1072 ; RV32IFD-NEXT:    addi sp, sp, -16
1073 ; RV32IFD-NEXT:    sw zero, 8(sp)
1074 ; RV32IFD-NEXT:    sw zero, 12(sp)
1075 ; RV32IFD-NEXT:    fld fa5, 8(sp)
1076 ; RV32IFD-NEXT:    fadd.d fa4, fa0, fa5
1077 ; RV32IFD-NEXT:    fadd.d fa3, fa1, fa5
1078 ; RV32IFD-NEXT:    fadd.d fa5, fa2, fa5
1079 ; RV32IFD-NEXT:    fmul.d fa4, fa4, fa3
1080 ; RV32IFD-NEXT:    fneg.d fa4, fa4
1081 ; RV32IFD-NEXT:    fsub.d fa0, fa4, fa5
1082 ; RV32IFD-NEXT:    addi sp, sp, 16
1083 ; RV32IFD-NEXT:    ret
1085 ; RV64IFD-LABEL: fnmadd_d_contract:
1086 ; RV64IFD:       # %bb.0:
1087 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
1088 ; RV64IFD-NEXT:    fadd.d fa4, fa0, fa5
1089 ; RV64IFD-NEXT:    fadd.d fa3, fa1, fa5
1090 ; RV64IFD-NEXT:    fadd.d fa5, fa2, fa5
1091 ; RV64IFD-NEXT:    fmul.d fa4, fa4, fa3
1092 ; RV64IFD-NEXT:    fneg.d fa4, fa4
1093 ; RV64IFD-NEXT:    fsub.d fa0, fa4, fa5
1094 ; RV64IFD-NEXT:    ret
1096 ; RV32I-LABEL: fnmadd_d_contract:
1097 ; RV32I:       # %bb.0:
1098 ; RV32I-NEXT:    addi sp, sp, -48
1099 ; RV32I-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
1100 ; RV32I-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
1101 ; RV32I-NEXT:    sw s1, 36(sp) # 4-byte Folded Spill
1102 ; RV32I-NEXT:    sw s2, 32(sp) # 4-byte Folded Spill
1103 ; RV32I-NEXT:    sw s3, 28(sp) # 4-byte Folded Spill
1104 ; RV32I-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
1105 ; RV32I-NEXT:    sw s5, 20(sp) # 4-byte Folded Spill
1106 ; RV32I-NEXT:    sw s6, 16(sp) # 4-byte Folded Spill
1107 ; RV32I-NEXT:    sw s7, 12(sp) # 4-byte Folded Spill
1108 ; RV32I-NEXT:    mv s0, a2
1109 ; RV32I-NEXT:    mv s1, a3
1110 ; RV32I-NEXT:    mv s2, a4
1111 ; RV32I-NEXT:    lui a2, %hi(.LCPI21_0)
1112 ; RV32I-NEXT:    addi a2, a2, %lo(.LCPI21_0)
1113 ; RV32I-NEXT:    lw s3, 0(a2)
1114 ; RV32I-NEXT:    lw s4, 4(a2)
1115 ; RV32I-NEXT:    mv s5, a5
1116 ; RV32I-NEXT:    mv a2, s3
1117 ; RV32I-NEXT:    mv a3, s4
1118 ; RV32I-NEXT:    call __adddf3
1119 ; RV32I-NEXT:    mv s6, a0
1120 ; RV32I-NEXT:    mv s7, a1
1121 ; RV32I-NEXT:    mv a0, s0
1122 ; RV32I-NEXT:    mv a1, s1
1123 ; RV32I-NEXT:    mv a2, s3
1124 ; RV32I-NEXT:    mv a3, s4
1125 ; RV32I-NEXT:    call __adddf3
1126 ; RV32I-NEXT:    mv s0, a0
1127 ; RV32I-NEXT:    mv s1, a1
1128 ; RV32I-NEXT:    mv a0, s2
1129 ; RV32I-NEXT:    mv a1, s5
1130 ; RV32I-NEXT:    mv a2, s3
1131 ; RV32I-NEXT:    mv a3, s4
1132 ; RV32I-NEXT:    call __adddf3
1133 ; RV32I-NEXT:    mv s2, a0
1134 ; RV32I-NEXT:    mv s3, a1
1135 ; RV32I-NEXT:    mv a0, s6
1136 ; RV32I-NEXT:    mv a1, s7
1137 ; RV32I-NEXT:    mv a2, s0
1138 ; RV32I-NEXT:    mv a3, s1
1139 ; RV32I-NEXT:    call __muldf3
1140 ; RV32I-NEXT:    lui a2, 524288
1141 ; RV32I-NEXT:    xor a1, a1, a2
1142 ; RV32I-NEXT:    mv a2, s2
1143 ; RV32I-NEXT:    mv a3, s3
1144 ; RV32I-NEXT:    call __subdf3
1145 ; RV32I-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
1146 ; RV32I-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
1147 ; RV32I-NEXT:    lw s1, 36(sp) # 4-byte Folded Reload
1148 ; RV32I-NEXT:    lw s2, 32(sp) # 4-byte Folded Reload
1149 ; RV32I-NEXT:    lw s3, 28(sp) # 4-byte Folded Reload
1150 ; RV32I-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
1151 ; RV32I-NEXT:    lw s5, 20(sp) # 4-byte Folded Reload
1152 ; RV32I-NEXT:    lw s6, 16(sp) # 4-byte Folded Reload
1153 ; RV32I-NEXT:    lw s7, 12(sp) # 4-byte Folded Reload
1154 ; RV32I-NEXT:    addi sp, sp, 48
1155 ; RV32I-NEXT:    ret
1157 ; RV64I-LABEL: fnmadd_d_contract:
1158 ; RV64I:       # %bb.0:
1159 ; RV64I-NEXT:    addi sp, sp, -48
1160 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1161 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1162 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1163 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1164 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1165 ; RV64I-NEXT:    mv s0, a1
1166 ; RV64I-NEXT:    lui a1, %hi(.LCPI21_0)
1167 ; RV64I-NEXT:    ld s1, %lo(.LCPI21_0)(a1)
1168 ; RV64I-NEXT:    mv s2, a2
1169 ; RV64I-NEXT:    mv a1, s1
1170 ; RV64I-NEXT:    call __adddf3
1171 ; RV64I-NEXT:    mv s3, a0
1172 ; RV64I-NEXT:    mv a0, s0
1173 ; RV64I-NEXT:    mv a1, s1
1174 ; RV64I-NEXT:    call __adddf3
1175 ; RV64I-NEXT:    mv s0, a0
1176 ; RV64I-NEXT:    mv a0, s2
1177 ; RV64I-NEXT:    mv a1, s1
1178 ; RV64I-NEXT:    call __adddf3
1179 ; RV64I-NEXT:    mv s1, a0
1180 ; RV64I-NEXT:    mv a0, s3
1181 ; RV64I-NEXT:    mv a1, s0
1182 ; RV64I-NEXT:    call __muldf3
1183 ; RV64I-NEXT:    li a1, -1
1184 ; RV64I-NEXT:    slli a1, a1, 63
1185 ; RV64I-NEXT:    xor a0, a0, a1
1186 ; RV64I-NEXT:    mv a1, s1
1187 ; RV64I-NEXT:    call __subdf3
1188 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1189 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1190 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1191 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1192 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1193 ; RV64I-NEXT:    addi sp, sp, 48
1194 ; RV64I-NEXT:    ret
1195   %a_ = fadd double 0.0, %a ; avoid negation using xor
1196   %b_ = fadd double 0.0, %b ; avoid negation using xor
1197   %c_ = fadd double 0.0, %c ; avoid negation using xor
1198   %1 = fmul contract double %a_, %b_
1199   %2 = fneg double %1
1200   %3 = fsub contract double %2, %c_
1201   ret double %3
1204 define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
1205 ; RV32IFD-LABEL: fnmsub_d_contract:
1206 ; RV32IFD:       # %bb.0:
1207 ; RV32IFD-NEXT:    addi sp, sp, -16
1208 ; RV32IFD-NEXT:    sw zero, 8(sp)
1209 ; RV32IFD-NEXT:    sw zero, 12(sp)
1210 ; RV32IFD-NEXT:    fld fa5, 8(sp)
1211 ; RV32IFD-NEXT:    fadd.d fa4, fa0, fa5
1212 ; RV32IFD-NEXT:    fadd.d fa5, fa1, fa5
1213 ; RV32IFD-NEXT:    fnmsub.d fa0, fa4, fa5, fa2
1214 ; RV32IFD-NEXT:    addi sp, sp, 16
1215 ; RV32IFD-NEXT:    ret
1217 ; RV64IFD-LABEL: fnmsub_d_contract:
1218 ; RV64IFD:       # %bb.0:
1219 ; RV64IFD-NEXT:    fmv.d.x fa5, zero
1220 ; RV64IFD-NEXT:    fadd.d fa4, fa0, fa5
1221 ; RV64IFD-NEXT:    fadd.d fa5, fa1, fa5
1222 ; RV64IFD-NEXT:    fnmsub.d fa0, fa4, fa5, fa2
1223 ; RV64IFD-NEXT:    ret
1225 ; RV32I-LABEL: fnmsub_d_contract:
1226 ; RV32I:       # %bb.0:
1227 ; RV32I-NEXT:    addi sp, sp, -48
1228 ; RV32I-NEXT:    sw ra, 44(sp) # 4-byte Folded Spill
1229 ; RV32I-NEXT:    sw s0, 40(sp) # 4-byte Folded Spill
1230 ; RV32I-NEXT:    sw s1, 36(sp) # 4-byte Folded Spill
1231 ; RV32I-NEXT:    sw s2, 32(sp) # 4-byte Folded Spill
1232 ; RV32I-NEXT:    sw s3, 28(sp) # 4-byte Folded Spill
1233 ; RV32I-NEXT:    sw s4, 24(sp) # 4-byte Folded Spill
1234 ; RV32I-NEXT:    sw s5, 20(sp) # 4-byte Folded Spill
1235 ; RV32I-NEXT:    sw s6, 16(sp) # 4-byte Folded Spill
1236 ; RV32I-NEXT:    sw s7, 12(sp) # 4-byte Folded Spill
1237 ; RV32I-NEXT:    mv s0, a2
1238 ; RV32I-NEXT:    mv s1, a3
1239 ; RV32I-NEXT:    mv s2, a4
1240 ; RV32I-NEXT:    lui a2, %hi(.LCPI22_0)
1241 ; RV32I-NEXT:    addi a2, a2, %lo(.LCPI22_0)
1242 ; RV32I-NEXT:    lw s3, 0(a2)
1243 ; RV32I-NEXT:    lw s4, 4(a2)
1244 ; RV32I-NEXT:    mv s5, a5
1245 ; RV32I-NEXT:    mv a2, s3
1246 ; RV32I-NEXT:    mv a3, s4
1247 ; RV32I-NEXT:    call __adddf3
1248 ; RV32I-NEXT:    mv s6, a0
1249 ; RV32I-NEXT:    mv s7, a1
1250 ; RV32I-NEXT:    mv a0, s0
1251 ; RV32I-NEXT:    mv a1, s1
1252 ; RV32I-NEXT:    mv a2, s3
1253 ; RV32I-NEXT:    mv a3, s4
1254 ; RV32I-NEXT:    call __adddf3
1255 ; RV32I-NEXT:    mv a2, a0
1256 ; RV32I-NEXT:    mv a3, a1
1257 ; RV32I-NEXT:    mv a0, s6
1258 ; RV32I-NEXT:    mv a1, s7
1259 ; RV32I-NEXT:    call __muldf3
1260 ; RV32I-NEXT:    mv a2, a0
1261 ; RV32I-NEXT:    mv a3, a1
1262 ; RV32I-NEXT:    mv a0, s2
1263 ; RV32I-NEXT:    mv a1, s5
1264 ; RV32I-NEXT:    call __subdf3
1265 ; RV32I-NEXT:    lw ra, 44(sp) # 4-byte Folded Reload
1266 ; RV32I-NEXT:    lw s0, 40(sp) # 4-byte Folded Reload
1267 ; RV32I-NEXT:    lw s1, 36(sp) # 4-byte Folded Reload
1268 ; RV32I-NEXT:    lw s2, 32(sp) # 4-byte Folded Reload
1269 ; RV32I-NEXT:    lw s3, 28(sp) # 4-byte Folded Reload
1270 ; RV32I-NEXT:    lw s4, 24(sp) # 4-byte Folded Reload
1271 ; RV32I-NEXT:    lw s5, 20(sp) # 4-byte Folded Reload
1272 ; RV32I-NEXT:    lw s6, 16(sp) # 4-byte Folded Reload
1273 ; RV32I-NEXT:    lw s7, 12(sp) # 4-byte Folded Reload
1274 ; RV32I-NEXT:    addi sp, sp, 48
1275 ; RV32I-NEXT:    ret
1277 ; RV64I-LABEL: fnmsub_d_contract:
1278 ; RV64I:       # %bb.0:
1279 ; RV64I-NEXT:    addi sp, sp, -48
1280 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1281 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1282 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1283 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1284 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1285 ; RV64I-NEXT:    mv s0, a1
1286 ; RV64I-NEXT:    lui a1, %hi(.LCPI22_0)
1287 ; RV64I-NEXT:    ld s1, %lo(.LCPI22_0)(a1)
1288 ; RV64I-NEXT:    mv s2, a2
1289 ; RV64I-NEXT:    mv a1, s1
1290 ; RV64I-NEXT:    call __adddf3
1291 ; RV64I-NEXT:    mv s3, a0
1292 ; RV64I-NEXT:    mv a0, s0
1293 ; RV64I-NEXT:    mv a1, s1
1294 ; RV64I-NEXT:    call __adddf3
1295 ; RV64I-NEXT:    mv a1, a0
1296 ; RV64I-NEXT:    mv a0, s3
1297 ; RV64I-NEXT:    call __muldf3
1298 ; RV64I-NEXT:    mv a1, a0
1299 ; RV64I-NEXT:    mv a0, s2
1300 ; RV64I-NEXT:    call __subdf3
1301 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1302 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1303 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1304 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1305 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1306 ; RV64I-NEXT:    addi sp, sp, 48
1307 ; RV64I-NEXT:    ret
1308   %a_ = fadd double 0.0, %a ; avoid negation using xor
1309   %b_ = fadd double 0.0, %b ; avoid negation using xor
1310   %1 = fmul contract double %a_, %b_
1311   %2 = fsub contract double %c, %1
1312   ret double %2
1315 define double @fsgnjx_f64(double %x, double %y) nounwind {
1316 ; RV32IFD-LABEL: fsgnjx_f64:
1317 ; RV32IFD:       # %bb.0:
1318 ; RV32IFD-NEXT:    addi sp, sp, -16
1319 ; RV32IFD-NEXT:    lui a0, 261888
1320 ; RV32IFD-NEXT:    sw zero, 8(sp)
1321 ; RV32IFD-NEXT:    sw a0, 12(sp)
1322 ; RV32IFD-NEXT:    fld fa5, 8(sp)
1323 ; RV32IFD-NEXT:    fsgnj.d fa5, fa5, fa0
1324 ; RV32IFD-NEXT:    fmul.d fa0, fa5, fa1
1325 ; RV32IFD-NEXT:    addi sp, sp, 16
1326 ; RV32IFD-NEXT:    ret
1328 ; RV64IFD-LABEL: fsgnjx_f64:
1329 ; RV64IFD:       # %bb.0:
1330 ; RV64IFD-NEXT:    li a0, 1023
1331 ; RV64IFD-NEXT:    slli a0, a0, 52
1332 ; RV64IFD-NEXT:    fmv.d.x fa5, a0
1333 ; RV64IFD-NEXT:    fsgnj.d fa5, fa5, fa0
1334 ; RV64IFD-NEXT:    fmul.d fa0, fa5, fa1
1335 ; RV64IFD-NEXT:    ret
1337 ; RV32I-LABEL: fsgnjx_f64:
1338 ; RV32I:       # %bb.0:
1339 ; RV32I-NEXT:    addi sp, sp, -16
1340 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1341 ; RV32I-NEXT:    lui a0, 524288
1342 ; RV32I-NEXT:    lui a4, 261888
1343 ; RV32I-NEXT:    and a0, a1, a0
1344 ; RV32I-NEXT:    or a1, a0, a4
1345 ; RV32I-NEXT:    li a0, 0
1346 ; RV32I-NEXT:    call __muldf3
1347 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1348 ; RV32I-NEXT:    addi sp, sp, 16
1349 ; RV32I-NEXT:    ret
1351 ; RV64I-LABEL: fsgnjx_f64:
1352 ; RV64I:       # %bb.0:
1353 ; RV64I-NEXT:    addi sp, sp, -16
1354 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1355 ; RV64I-NEXT:    li a2, 1023
1356 ; RV64I-NEXT:    srli a0, a0, 63
1357 ; RV64I-NEXT:    slli a2, a2, 52
1358 ; RV64I-NEXT:    slli a0, a0, 63
1359 ; RV64I-NEXT:    or a0, a0, a2
1360 ; RV64I-NEXT:    call __muldf3
1361 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1362 ; RV64I-NEXT:    addi sp, sp, 16
1363 ; RV64I-NEXT:    ret
1364   %z = call double @llvm.copysign.f64(double 1.0, double %x)
1365   %mul = fmul double %z, %y
1366   ret double %mul