1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3 ; RUN: -target-abi=ilp32d | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
5 ; RUN: -target-abi=lp64d | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s
6 ; RUN: llc -mtriple=riscv32 -mattr=+zdinx -verify-machineinstrs < %s \
7 ; RUN: -target-abi=ilp32 | FileCheck -check-prefix=RV32IZFINXZDINX %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+zdinx -verify-machineinstrs < %s \
9 ; RUN: -target-abi=lp64 | FileCheck -check-prefix=RV64IZFINXZDINX %s
10 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
11 ; RUN: | FileCheck -check-prefix=RV32I %s
12 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
13 ; RUN: | FileCheck -check-prefix=RV64I %s
15 ; These tests are each targeted at a particular RISC-V FPU instruction.
16 ; Compares and conversions can be found in double-fcmp.ll and double-convert.ll
17 ; respectively. Some other double-*.ll files in this folder exercise LLVM IR
18 ; instructions that don't directly match a RISC-V instruction.
20 define double @fadd_d(double %a, double %b) nounwind {
21 ; CHECKIFD-LABEL: fadd_d:
23 ; CHECKIFD-NEXT: fadd.d fa0, fa0, fa1
26 ; RV32IZFINXZDINX-LABEL: fadd_d:
27 ; RV32IZFINXZDINX: # %bb.0:
28 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
29 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
30 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
31 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
32 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
33 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
34 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
35 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
36 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
37 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2
38 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
39 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
40 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
41 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
42 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
43 ; RV32IZFINXZDINX-NEXT: ret
45 ; RV64IZFINXZDINX-LABEL: fadd_d:
46 ; RV64IZFINXZDINX: # %bb.0:
47 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a1
48 ; RV64IZFINXZDINX-NEXT: ret
50 ; RV32I-LABEL: fadd_d:
52 ; RV32I-NEXT: addi sp, sp, -16
53 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
54 ; RV32I-NEXT: call __adddf3@plt
55 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
56 ; RV32I-NEXT: addi sp, sp, 16
59 ; RV64I-LABEL: fadd_d:
61 ; RV64I-NEXT: addi sp, sp, -16
62 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
63 ; RV64I-NEXT: call __adddf3@plt
64 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
65 ; RV64I-NEXT: addi sp, sp, 16
67 %1 = fadd double %a, %b
71 define double @fsub_d(double %a, double %b) nounwind {
72 ; CHECKIFD-LABEL: fsub_d:
74 ; CHECKIFD-NEXT: fsub.d fa0, fa0, fa1
77 ; RV32IZFINXZDINX-LABEL: fsub_d:
78 ; RV32IZFINXZDINX: # %bb.0:
79 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
80 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
81 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
82 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
83 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
84 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
85 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
86 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
87 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
88 ; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a2
89 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
90 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
91 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
92 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
93 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
94 ; RV32IZFINXZDINX-NEXT: ret
96 ; RV64IZFINXZDINX-LABEL: fsub_d:
97 ; RV64IZFINXZDINX: # %bb.0:
98 ; RV64IZFINXZDINX-NEXT: fsub.d a0, a0, a1
99 ; RV64IZFINXZDINX-NEXT: ret
101 ; RV32I-LABEL: fsub_d:
103 ; RV32I-NEXT: addi sp, sp, -16
104 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
105 ; RV32I-NEXT: call __subdf3@plt
106 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
107 ; RV32I-NEXT: addi sp, sp, 16
110 ; RV64I-LABEL: fsub_d:
112 ; RV64I-NEXT: addi sp, sp, -16
113 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
114 ; RV64I-NEXT: call __subdf3@plt
115 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
116 ; RV64I-NEXT: addi sp, sp, 16
118 %1 = fsub double %a, %b
122 define double @fmul_d(double %a, double %b) nounwind {
123 ; CHECKIFD-LABEL: fmul_d:
125 ; CHECKIFD-NEXT: fmul.d fa0, fa0, fa1
128 ; RV32IZFINXZDINX-LABEL: fmul_d:
129 ; RV32IZFINXZDINX: # %bb.0:
130 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
131 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
132 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
133 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
134 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
135 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
136 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
137 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
138 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
139 ; RV32IZFINXZDINX-NEXT: fmul.d a0, a0, a2
140 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
141 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
142 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
143 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
144 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
145 ; RV32IZFINXZDINX-NEXT: ret
147 ; RV64IZFINXZDINX-LABEL: fmul_d:
148 ; RV64IZFINXZDINX: # %bb.0:
149 ; RV64IZFINXZDINX-NEXT: fmul.d a0, a0, a1
150 ; RV64IZFINXZDINX-NEXT: ret
152 ; RV32I-LABEL: fmul_d:
154 ; RV32I-NEXT: addi sp, sp, -16
155 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
156 ; RV32I-NEXT: call __muldf3@plt
157 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
158 ; RV32I-NEXT: addi sp, sp, 16
161 ; RV64I-LABEL: fmul_d:
163 ; RV64I-NEXT: addi sp, sp, -16
164 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
165 ; RV64I-NEXT: call __muldf3@plt
166 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
167 ; RV64I-NEXT: addi sp, sp, 16
169 %1 = fmul double %a, %b
173 define double @fdiv_d(double %a, double %b) nounwind {
174 ; CHECKIFD-LABEL: fdiv_d:
176 ; CHECKIFD-NEXT: fdiv.d fa0, fa0, fa1
179 ; RV32IZFINXZDINX-LABEL: fdiv_d:
180 ; RV32IZFINXZDINX: # %bb.0:
181 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
182 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
183 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
184 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
185 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
186 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
187 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
188 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
189 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
190 ; RV32IZFINXZDINX-NEXT: fdiv.d a0, a0, a2
191 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
192 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
193 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
194 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
195 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
196 ; RV32IZFINXZDINX-NEXT: ret
198 ; RV64IZFINXZDINX-LABEL: fdiv_d:
199 ; RV64IZFINXZDINX: # %bb.0:
200 ; RV64IZFINXZDINX-NEXT: fdiv.d a0, a0, a1
201 ; RV64IZFINXZDINX-NEXT: ret
203 ; RV32I-LABEL: fdiv_d:
205 ; RV32I-NEXT: addi sp, sp, -16
206 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
207 ; RV32I-NEXT: call __divdf3@plt
208 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
209 ; RV32I-NEXT: addi sp, sp, 16
212 ; RV64I-LABEL: fdiv_d:
214 ; RV64I-NEXT: addi sp, sp, -16
215 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
216 ; RV64I-NEXT: call __divdf3@plt
217 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
218 ; RV64I-NEXT: addi sp, sp, 16
220 %1 = fdiv double %a, %b
224 declare double @llvm.sqrt.f64(double)
226 define double @fsqrt_d(double %a) nounwind {
227 ; CHECKIFD-LABEL: fsqrt_d:
229 ; CHECKIFD-NEXT: fsqrt.d fa0, fa0
232 ; RV32IZFINXZDINX-LABEL: fsqrt_d:
233 ; RV32IZFINXZDINX: # %bb.0:
234 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
235 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
236 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
237 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
238 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
239 ; RV32IZFINXZDINX-NEXT: fsqrt.d a0, a0
240 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
241 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
242 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
243 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
244 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
245 ; RV32IZFINXZDINX-NEXT: ret
247 ; RV64IZFINXZDINX-LABEL: fsqrt_d:
248 ; RV64IZFINXZDINX: # %bb.0:
249 ; RV64IZFINXZDINX-NEXT: fsqrt.d a0, a0
250 ; RV64IZFINXZDINX-NEXT: ret
252 ; RV32I-LABEL: fsqrt_d:
254 ; RV32I-NEXT: addi sp, sp, -16
255 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
256 ; RV32I-NEXT: call sqrt@plt
257 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
258 ; RV32I-NEXT: addi sp, sp, 16
261 ; RV64I-LABEL: fsqrt_d:
263 ; RV64I-NEXT: addi sp, sp, -16
264 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
265 ; RV64I-NEXT: call sqrt@plt
266 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
267 ; RV64I-NEXT: addi sp, sp, 16
269 %1 = call double @llvm.sqrt.f64(double %a)
273 declare double @llvm.copysign.f64(double, double)
275 define double @fsgnj_d(double %a, double %b) nounwind {
276 ; CHECKIFD-LABEL: fsgnj_d:
278 ; CHECKIFD-NEXT: fsgnj.d fa0, fa0, fa1
281 ; RV32IZFINXZDINX-LABEL: fsgnj_d:
282 ; RV32IZFINXZDINX: # %bb.0:
283 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
284 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
285 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
286 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
287 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
288 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
289 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
290 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
291 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
292 ; RV32IZFINXZDINX-NEXT: fsgnj.d a0, a0, a2
293 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
294 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
295 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
296 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
297 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
298 ; RV32IZFINXZDINX-NEXT: ret
300 ; RV64IZFINXZDINX-LABEL: fsgnj_d:
301 ; RV64IZFINXZDINX: # %bb.0:
302 ; RV64IZFINXZDINX-NEXT: fsgnj.d a0, a0, a1
303 ; RV64IZFINXZDINX-NEXT: ret
305 ; RV32I-LABEL: fsgnj_d:
307 ; RV32I-NEXT: lui a2, 524288
308 ; RV32I-NEXT: and a2, a3, a2
309 ; RV32I-NEXT: slli a1, a1, 1
310 ; RV32I-NEXT: srli a1, a1, 1
311 ; RV32I-NEXT: or a1, a1, a2
314 ; RV64I-LABEL: fsgnj_d:
316 ; RV64I-NEXT: srli a1, a1, 63
317 ; RV64I-NEXT: slli a1, a1, 63
318 ; RV64I-NEXT: slli a0, a0, 1
319 ; RV64I-NEXT: srli a0, a0, 1
320 ; RV64I-NEXT: or a0, a0, a1
322 %1 = call double @llvm.copysign.f64(double %a, double %b)
326 ; This function performs extra work to ensure that
327 ; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
328 define i32 @fneg_d(double %a, double %b) nounwind {
329 ; CHECKIFD-LABEL: fneg_d:
331 ; CHECKIFD-NEXT: fadd.d fa5, fa0, fa0
332 ; CHECKIFD-NEXT: fneg.d fa4, fa5
333 ; CHECKIFD-NEXT: feq.d a0, fa5, fa4
336 ; RV32IZFINXZDINX-LABEL: fneg_d:
337 ; RV32IZFINXZDINX: # %bb.0:
338 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
339 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
340 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
341 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
342 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
343 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a0
344 ; RV32IZFINXZDINX-NEXT: fneg.d a2, a0
345 ; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a2
346 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
347 ; RV32IZFINXZDINX-NEXT: ret
349 ; RV64IZFINXZDINX-LABEL: fneg_d:
350 ; RV64IZFINXZDINX: # %bb.0:
351 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a0
352 ; RV64IZFINXZDINX-NEXT: fneg.d a1, a0
353 ; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a1
354 ; RV64IZFINXZDINX-NEXT: ret
356 ; RV32I-LABEL: fneg_d:
358 ; RV32I-NEXT: addi sp, sp, -16
359 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
360 ; RV32I-NEXT: mv a2, a0
361 ; RV32I-NEXT: mv a3, a1
362 ; RV32I-NEXT: call __adddf3@plt
363 ; RV32I-NEXT: lui a3, 524288
364 ; RV32I-NEXT: xor a3, a1, a3
365 ; RV32I-NEXT: mv a2, a0
366 ; RV32I-NEXT: call __eqdf2@plt
367 ; RV32I-NEXT: seqz a0, a0
368 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
369 ; RV32I-NEXT: addi sp, sp, 16
372 ; RV64I-LABEL: fneg_d:
374 ; RV64I-NEXT: addi sp, sp, -16
375 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
376 ; RV64I-NEXT: mv a1, a0
377 ; RV64I-NEXT: call __adddf3@plt
378 ; RV64I-NEXT: li a1, -1
379 ; RV64I-NEXT: slli a1, a1, 63
380 ; RV64I-NEXT: xor a1, a0, a1
381 ; RV64I-NEXT: call __eqdf2@plt
382 ; RV64I-NEXT: seqz a0, a0
383 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
384 ; RV64I-NEXT: addi sp, sp, 16
386 %1 = fadd double %a, %a
388 %3 = fcmp oeq double %1, %2
389 %4 = zext i1 %3 to i32
393 define double @fsgnjn_d(double %a, double %b) nounwind {
394 ; TODO: fsgnjn.s isn't selected on RV64 because DAGCombiner::visitBITCAST will
395 ; convert (bitconvert (fneg x)) to a xor.
397 ; CHECKIFD-LABEL: fsgnjn_d:
399 ; CHECKIFD-NEXT: fsgnjn.d fa0, fa0, fa1
402 ; RV32IZFINXZDINX-LABEL: fsgnjn_d:
403 ; RV32IZFINXZDINX: # %bb.0:
404 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
405 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
406 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
407 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
408 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
409 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
410 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
411 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
412 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
413 ; RV32IZFINXZDINX-NEXT: fsgnjn.d a0, a0, a2
414 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
415 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
416 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
417 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
418 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
419 ; RV32IZFINXZDINX-NEXT: ret
421 ; RV64IZFINXZDINX-LABEL: fsgnjn_d:
422 ; RV64IZFINXZDINX: # %bb.0:
423 ; RV64IZFINXZDINX-NEXT: li a2, -1
424 ; RV64IZFINXZDINX-NEXT: slli a2, a2, 63
425 ; RV64IZFINXZDINX-NEXT: xor a1, a1, a2
426 ; RV64IZFINXZDINX-NEXT: fsgnj.d a0, a0, a1
427 ; RV64IZFINXZDINX-NEXT: ret
429 ; RV32I-LABEL: fsgnjn_d:
431 ; RV32I-NEXT: not a2, a3
432 ; RV32I-NEXT: lui a3, 524288
433 ; RV32I-NEXT: and a2, a2, a3
434 ; RV32I-NEXT: slli a1, a1, 1
435 ; RV32I-NEXT: srli a1, a1, 1
436 ; RV32I-NEXT: or a1, a1, a2
439 ; RV64I-LABEL: fsgnjn_d:
441 ; RV64I-NEXT: not a1, a1
442 ; RV64I-NEXT: slli a0, a0, 1
443 ; RV64I-NEXT: srli a0, a0, 1
444 ; RV64I-NEXT: srli a1, a1, 63
445 ; RV64I-NEXT: slli a1, a1, 63
446 ; RV64I-NEXT: or a0, a0, a1
448 %1 = fsub double -0.0, %b
449 %2 = call double @llvm.copysign.f64(double %a, double %1)
453 declare double @llvm.fabs.f64(double)
455 ; This function performs extra work to ensure that
456 ; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
457 define double @fabs_d(double %a, double %b) nounwind {
458 ; CHECKIFD-LABEL: fabs_d:
460 ; CHECKIFD-NEXT: fadd.d fa5, fa0, fa1
461 ; CHECKIFD-NEXT: fabs.d fa4, fa5
462 ; CHECKIFD-NEXT: fadd.d fa0, fa4, fa5
465 ; RV32IZFINXZDINX-LABEL: fabs_d:
466 ; RV32IZFINXZDINX: # %bb.0:
467 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
468 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
469 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
470 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
471 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
472 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
473 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
474 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
475 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
476 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a2
477 ; RV32IZFINXZDINX-NEXT: fabs.d a2, a0
478 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a2, a0
479 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
480 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
481 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
482 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
483 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
484 ; RV32IZFINXZDINX-NEXT: ret
486 ; RV64IZFINXZDINX-LABEL: fabs_d:
487 ; RV64IZFINXZDINX: # %bb.0:
488 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a1
489 ; RV64IZFINXZDINX-NEXT: fabs.d a1, a0
490 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a1, a0
491 ; RV64IZFINXZDINX-NEXT: ret
493 ; RV32I-LABEL: fabs_d:
495 ; RV32I-NEXT: addi sp, sp, -16
496 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
497 ; RV32I-NEXT: call __adddf3@plt
498 ; RV32I-NEXT: mv a3, a1
499 ; RV32I-NEXT: slli a1, a1, 1
500 ; RV32I-NEXT: srli a1, a1, 1
501 ; RV32I-NEXT: mv a2, a0
502 ; RV32I-NEXT: call __adddf3@plt
503 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
504 ; RV32I-NEXT: addi sp, sp, 16
507 ; RV64I-LABEL: fabs_d:
509 ; RV64I-NEXT: addi sp, sp, -16
510 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
511 ; RV64I-NEXT: call __adddf3@plt
512 ; RV64I-NEXT: mv a1, a0
513 ; RV64I-NEXT: slli a0, a0, 1
514 ; RV64I-NEXT: srli a0, a0, 1
515 ; RV64I-NEXT: call __adddf3@plt
516 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
517 ; RV64I-NEXT: addi sp, sp, 16
519 %1 = fadd double %a, %b
520 %2 = call double @llvm.fabs.f64(double %1)
521 %3 = fadd double %2, %1
525 declare double @llvm.minnum.f64(double, double)
527 define double @fmin_d(double %a, double %b) nounwind {
528 ; CHECKIFD-LABEL: fmin_d:
530 ; CHECKIFD-NEXT: fmin.d fa0, fa0, fa1
533 ; RV32IZFINXZDINX-LABEL: fmin_d:
534 ; RV32IZFINXZDINX: # %bb.0:
535 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
536 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
537 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
538 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
539 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
540 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
541 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
542 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
543 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
544 ; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2
545 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
546 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
547 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
548 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
549 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
550 ; RV32IZFINXZDINX-NEXT: ret
552 ; RV64IZFINXZDINX-LABEL: fmin_d:
553 ; RV64IZFINXZDINX: # %bb.0:
554 ; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a1
555 ; RV64IZFINXZDINX-NEXT: ret
557 ; RV32I-LABEL: fmin_d:
559 ; RV32I-NEXT: addi sp, sp, -16
560 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
561 ; RV32I-NEXT: call fmin@plt
562 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
563 ; RV32I-NEXT: addi sp, sp, 16
566 ; RV64I-LABEL: fmin_d:
568 ; RV64I-NEXT: addi sp, sp, -16
569 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
570 ; RV64I-NEXT: call fmin@plt
571 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
572 ; RV64I-NEXT: addi sp, sp, 16
574 %1 = call double @llvm.minnum.f64(double %a, double %b)
578 declare double @llvm.maxnum.f64(double, double)
580 define double @fmax_d(double %a, double %b) nounwind {
581 ; CHECKIFD-LABEL: fmax_d:
583 ; CHECKIFD-NEXT: fmax.d fa0, fa0, fa1
586 ; RV32IZFINXZDINX-LABEL: fmax_d:
587 ; RV32IZFINXZDINX: # %bb.0:
588 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
589 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
590 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
591 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
592 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
593 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
594 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
595 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
596 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
597 ; RV32IZFINXZDINX-NEXT: fmax.d a0, a0, a2
598 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
599 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
600 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
601 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
602 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
603 ; RV32IZFINXZDINX-NEXT: ret
605 ; RV64IZFINXZDINX-LABEL: fmax_d:
606 ; RV64IZFINXZDINX: # %bb.0:
607 ; RV64IZFINXZDINX-NEXT: fmax.d a0, a0, a1
608 ; RV64IZFINXZDINX-NEXT: ret
610 ; RV32I-LABEL: fmax_d:
612 ; RV32I-NEXT: addi sp, sp, -16
613 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
614 ; RV32I-NEXT: call fmax@plt
615 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
616 ; RV32I-NEXT: addi sp, sp, 16
619 ; RV64I-LABEL: fmax_d:
621 ; RV64I-NEXT: addi sp, sp, -16
622 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
623 ; RV64I-NEXT: call fmax@plt
624 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
625 ; RV64I-NEXT: addi sp, sp, 16
627 %1 = call double @llvm.maxnum.f64(double %a, double %b)
631 declare double @llvm.fma.f64(double, double, double)
633 define double @fmadd_d(double %a, double %b, double %c) nounwind {
634 ; CHECKIFD-LABEL: fmadd_d:
636 ; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa2
639 ; RV32IZFINXZDINX-LABEL: fmadd_d:
640 ; RV32IZFINXZDINX: # %bb.0:
641 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
642 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
643 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
644 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
645 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
646 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
647 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
648 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
649 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
650 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
651 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
652 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
653 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
654 ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4
655 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
656 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
657 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
658 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
659 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
660 ; RV32IZFINXZDINX-NEXT: ret
662 ; RV64IZFINXZDINX-LABEL: fmadd_d:
663 ; RV64IZFINXZDINX: # %bb.0:
664 ; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2
665 ; RV64IZFINXZDINX-NEXT: ret
667 ; RV32I-LABEL: fmadd_d:
669 ; RV32I-NEXT: addi sp, sp, -16
670 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
671 ; RV32I-NEXT: call fma@plt
672 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
673 ; RV32I-NEXT: addi sp, sp, 16
676 ; RV64I-LABEL: fmadd_d:
678 ; RV64I-NEXT: addi sp, sp, -16
679 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
680 ; RV64I-NEXT: call fma@plt
681 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
682 ; RV64I-NEXT: addi sp, sp, 16
684 %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
688 define double @fmsub_d(double %a, double %b, double %c) nounwind {
689 ; RV32IFD-LABEL: fmsub_d:
691 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
692 ; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
693 ; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5
696 ; RV64IFD-LABEL: fmsub_d:
698 ; RV64IFD-NEXT: fmv.d.x fa5, zero
699 ; RV64IFD-NEXT: fadd.d fa5, fa2, fa5
700 ; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5
703 ; RV32IZFINXZDINX-LABEL: fmsub_d:
704 ; RV32IZFINXZDINX: # %bb.0:
705 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
706 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
707 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
708 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
709 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
710 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
711 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
712 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
713 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
714 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
715 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
716 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
717 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
718 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
719 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6
720 ; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4
721 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
722 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
723 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
724 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
725 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
726 ; RV32IZFINXZDINX-NEXT: ret
728 ; RV64IZFINXZDINX-LABEL: fmsub_d:
729 ; RV64IZFINXZDINX: # %bb.0:
730 ; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero
731 ; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a2
732 ; RV64IZFINXZDINX-NEXT: ret
734 ; RV32I-LABEL: fmsub_d:
736 ; RV32I-NEXT: addi sp, sp, -32
737 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
738 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
739 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
740 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
741 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
742 ; RV32I-NEXT: mv s0, a3
743 ; RV32I-NEXT: mv s1, a2
744 ; RV32I-NEXT: mv s2, a1
745 ; RV32I-NEXT: mv s3, a0
746 ; RV32I-NEXT: mv a0, a4
747 ; RV32I-NEXT: mv a1, a5
748 ; RV32I-NEXT: li a2, 0
749 ; RV32I-NEXT: li a3, 0
750 ; RV32I-NEXT: call __adddf3@plt
751 ; RV32I-NEXT: mv a4, a0
752 ; RV32I-NEXT: lui a5, 524288
753 ; RV32I-NEXT: xor a5, a1, a5
754 ; RV32I-NEXT: mv a0, s3
755 ; RV32I-NEXT: mv a1, s2
756 ; RV32I-NEXT: mv a2, s1
757 ; RV32I-NEXT: mv a3, s0
758 ; RV32I-NEXT: call fma@plt
759 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
760 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
761 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
762 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
763 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
764 ; RV32I-NEXT: addi sp, sp, 32
767 ; RV64I-LABEL: fmsub_d:
769 ; RV64I-NEXT: addi sp, sp, -32
770 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
771 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
772 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
773 ; RV64I-NEXT: mv s0, a1
774 ; RV64I-NEXT: mv s1, a0
775 ; RV64I-NEXT: mv a0, a2
776 ; RV64I-NEXT: li a1, 0
777 ; RV64I-NEXT: call __adddf3@plt
778 ; RV64I-NEXT: li a1, -1
779 ; RV64I-NEXT: slli a1, a1, 63
780 ; RV64I-NEXT: xor a2, a0, a1
781 ; RV64I-NEXT: mv a0, s1
782 ; RV64I-NEXT: mv a1, s0
783 ; RV64I-NEXT: call fma@plt
784 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
785 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
786 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
787 ; RV64I-NEXT: addi sp, sp, 32
789 %c_ = fadd double 0.0, %c ; avoid negation using xor
790 %negc = fsub double -0.0, %c_
791 %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
795 define double @fnmadd_d(double %a, double %b, double %c) nounwind {
796 ; RV32IFD-LABEL: fnmadd_d:
798 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
799 ; RV32IFD-NEXT: fadd.d fa4, fa0, fa5
800 ; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
801 ; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5
804 ; RV64IFD-LABEL: fnmadd_d:
806 ; RV64IFD-NEXT: fmv.d.x fa5, zero
807 ; RV64IFD-NEXT: fadd.d fa4, fa0, fa5
808 ; RV64IFD-NEXT: fadd.d fa5, fa2, fa5
809 ; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5
812 ; RV32IZFINXZDINX-LABEL: fnmadd_d:
813 ; RV32IZFINXZDINX: # %bb.0:
814 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
815 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
816 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
817 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
818 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
819 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
820 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
821 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
822 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
823 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
824 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
825 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
826 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
827 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
828 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6
829 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6
830 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4
831 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
832 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
833 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
834 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
835 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
836 ; RV32IZFINXZDINX-NEXT: ret
838 ; RV64IZFINXZDINX-LABEL: fnmadd_d:
839 ; RV64IZFINXZDINX: # %bb.0:
840 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero
841 ; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero
842 ; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a2
843 ; RV64IZFINXZDINX-NEXT: ret
845 ; RV32I-LABEL: fnmadd_d:
847 ; RV32I-NEXT: addi sp, sp, -32
848 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
849 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
850 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
851 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
852 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
853 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
854 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
855 ; RV32I-NEXT: mv s0, a5
856 ; RV32I-NEXT: mv s1, a4
857 ; RV32I-NEXT: mv s2, a3
858 ; RV32I-NEXT: mv s3, a2
859 ; RV32I-NEXT: li a2, 0
860 ; RV32I-NEXT: li a3, 0
861 ; RV32I-NEXT: call __adddf3@plt
862 ; RV32I-NEXT: mv s4, a0
863 ; RV32I-NEXT: mv s5, a1
864 ; RV32I-NEXT: mv a0, s1
865 ; RV32I-NEXT: mv a1, s0
866 ; RV32I-NEXT: li a2, 0
867 ; RV32I-NEXT: li a3, 0
868 ; RV32I-NEXT: call __adddf3@plt
869 ; RV32I-NEXT: mv a4, a0
870 ; RV32I-NEXT: lui a5, 524288
871 ; RV32I-NEXT: xor a2, s5, a5
872 ; RV32I-NEXT: xor a5, a1, a5
873 ; RV32I-NEXT: mv a0, s4
874 ; RV32I-NEXT: mv a1, a2
875 ; RV32I-NEXT: mv a2, s3
876 ; RV32I-NEXT: mv a3, s2
877 ; RV32I-NEXT: call fma@plt
878 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
879 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
880 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
881 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
882 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
883 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
884 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
885 ; RV32I-NEXT: addi sp, sp, 32
888 ; RV64I-LABEL: fnmadd_d:
890 ; RV64I-NEXT: addi sp, sp, -32
891 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
892 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
893 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
894 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
895 ; RV64I-NEXT: mv s0, a2
896 ; RV64I-NEXT: mv s1, a1
897 ; RV64I-NEXT: li a1, 0
898 ; RV64I-NEXT: call __adddf3@plt
899 ; RV64I-NEXT: mv s2, a0
900 ; RV64I-NEXT: mv a0, s0
901 ; RV64I-NEXT: li a1, 0
902 ; RV64I-NEXT: call __adddf3@plt
903 ; RV64I-NEXT: li a1, -1
904 ; RV64I-NEXT: slli a2, a1, 63
905 ; RV64I-NEXT: xor a1, s2, a2
906 ; RV64I-NEXT: xor a2, a0, a2
907 ; RV64I-NEXT: mv a0, a1
908 ; RV64I-NEXT: mv a1, s1
909 ; RV64I-NEXT: call fma@plt
910 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
911 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
912 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
913 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
914 ; RV64I-NEXT: addi sp, sp, 32
916 %a_ = fadd double 0.0, %a
917 %c_ = fadd double 0.0, %c
918 %nega = fsub double -0.0, %a_
919 %negc = fsub double -0.0, %c_
920 %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
924 define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
925 ; RV32IFD-LABEL: fnmadd_d_2:
927 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
928 ; RV32IFD-NEXT: fadd.d fa4, fa1, fa5
929 ; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
930 ; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5
933 ; RV64IFD-LABEL: fnmadd_d_2:
935 ; RV64IFD-NEXT: fmv.d.x fa5, zero
936 ; RV64IFD-NEXT: fadd.d fa4, fa1, fa5
937 ; RV64IFD-NEXT: fadd.d fa5, fa2, fa5
938 ; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5
941 ; RV32IZFINXZDINX-LABEL: fnmadd_d_2:
942 ; RV32IZFINXZDINX: # %bb.0:
943 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
944 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
945 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
946 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
947 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
948 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
949 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
950 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
951 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
952 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
953 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
954 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
955 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
956 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
957 ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6
958 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6
959 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a2, a0, a4
960 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
961 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
962 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
963 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
964 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
965 ; RV32IZFINXZDINX-NEXT: ret
967 ; RV64IZFINXZDINX-LABEL: fnmadd_d_2:
968 ; RV64IZFINXZDINX: # %bb.0:
969 ; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero
970 ; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero
971 ; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a1, a0, a2
972 ; RV64IZFINXZDINX-NEXT: ret
974 ; RV32I-LABEL: fnmadd_d_2:
976 ; RV32I-NEXT: addi sp, sp, -32
977 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
978 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
979 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
980 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
981 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
982 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
983 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
984 ; RV32I-NEXT: mv s0, a5
985 ; RV32I-NEXT: mv s1, a4
986 ; RV32I-NEXT: mv s2, a1
987 ; RV32I-NEXT: mv s3, a0
988 ; RV32I-NEXT: mv a0, a2
989 ; RV32I-NEXT: mv a1, a3
990 ; RV32I-NEXT: li a2, 0
991 ; RV32I-NEXT: li a3, 0
992 ; RV32I-NEXT: call __adddf3@plt
993 ; RV32I-NEXT: mv s4, a0
994 ; RV32I-NEXT: mv s5, a1
995 ; RV32I-NEXT: mv a0, s1
996 ; RV32I-NEXT: mv a1, s0
997 ; RV32I-NEXT: li a2, 0
998 ; RV32I-NEXT: li a3, 0
999 ; RV32I-NEXT: call __adddf3@plt
1000 ; RV32I-NEXT: mv a4, a0
1001 ; RV32I-NEXT: lui a5, 524288
1002 ; RV32I-NEXT: xor a3, s5, a5
1003 ; RV32I-NEXT: xor a5, a1, a5
1004 ; RV32I-NEXT: mv a0, s3
1005 ; RV32I-NEXT: mv a1, s2
1006 ; RV32I-NEXT: mv a2, s4
1007 ; RV32I-NEXT: call fma@plt
1008 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1009 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1010 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1011 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1012 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1013 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
1014 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
1015 ; RV32I-NEXT: addi sp, sp, 32
1018 ; RV64I-LABEL: fnmadd_d_2:
1020 ; RV64I-NEXT: addi sp, sp, -32
1021 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1022 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1023 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1024 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1025 ; RV64I-NEXT: mv s0, a2
1026 ; RV64I-NEXT: mv s1, a0
1027 ; RV64I-NEXT: mv a0, a1
1028 ; RV64I-NEXT: li a1, 0
1029 ; RV64I-NEXT: call __adddf3@plt
1030 ; RV64I-NEXT: mv s2, a0
1031 ; RV64I-NEXT: mv a0, s0
1032 ; RV64I-NEXT: li a1, 0
1033 ; RV64I-NEXT: call __adddf3@plt
1034 ; RV64I-NEXT: li a1, -1
1035 ; RV64I-NEXT: slli a2, a1, 63
1036 ; RV64I-NEXT: xor a1, s2, a2
1037 ; RV64I-NEXT: xor a2, a0, a2
1038 ; RV64I-NEXT: mv a0, s1
1039 ; RV64I-NEXT: call fma@plt
1040 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1041 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1042 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1043 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1044 ; RV64I-NEXT: addi sp, sp, 32
1046 %b_ = fadd double 0.0, %b
1047 %c_ = fadd double 0.0, %c
1048 %negb = fsub double -0.0, %b_
1049 %negc = fsub double -0.0, %c_
1050 %1 = call double @llvm.fma.f64(double %a, double %negb, double %negc)
1054 define double @fnmadd_d_3(double %a, double %b, double %c) nounwind {
1055 ; CHECKIFD-LABEL: fnmadd_d_3:
1056 ; CHECKIFD: # %bb.0:
1057 ; CHECKIFD-NEXT: fmadd.d fa5, fa0, fa1, fa2
1058 ; CHECKIFD-NEXT: fneg.d fa0, fa5
1059 ; CHECKIFD-NEXT: ret
1061 ; RV32IZFINXZDINX-LABEL: fnmadd_d_3:
1062 ; RV32IZFINXZDINX: # %bb.0:
1063 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1064 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1065 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1066 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1067 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1068 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1069 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1070 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1071 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1072 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1073 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1074 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1075 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1076 ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4
1077 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1078 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1079 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1080 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1081 ; RV32IZFINXZDINX-NEXT: lui a2, 524288
1082 ; RV32IZFINXZDINX-NEXT: xor a1, a1, a2
1083 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1084 ; RV32IZFINXZDINX-NEXT: ret
1086 ; RV64IZFINXZDINX-LABEL: fnmadd_d_3:
1087 ; RV64IZFINXZDINX: # %bb.0:
1088 ; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2
1089 ; RV64IZFINXZDINX-NEXT: li a1, -1
1090 ; RV64IZFINXZDINX-NEXT: slli a1, a1, 63
1091 ; RV64IZFINXZDINX-NEXT: xor a0, a0, a1
1092 ; RV64IZFINXZDINX-NEXT: ret
1094 ; RV32I-LABEL: fnmadd_d_3:
1096 ; RV32I-NEXT: addi sp, sp, -16
1097 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1098 ; RV32I-NEXT: call fma@plt
1099 ; RV32I-NEXT: lui a2, 524288
1100 ; RV32I-NEXT: xor a1, a1, a2
1101 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1102 ; RV32I-NEXT: addi sp, sp, 16
1105 ; RV64I-LABEL: fnmadd_d_3:
1107 ; RV64I-NEXT: addi sp, sp, -16
1108 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1109 ; RV64I-NEXT: call fma@plt
1110 ; RV64I-NEXT: li a1, -1
1111 ; RV64I-NEXT: slli a1, a1, 63
1112 ; RV64I-NEXT: xor a0, a0, a1
1113 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1114 ; RV64I-NEXT: addi sp, sp, 16
1116 %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
1117 %neg = fneg double %1
1122 define double @fnmadd_nsz(double %a, double %b, double %c) nounwind {
1123 ; CHECKIFD-LABEL: fnmadd_nsz:
1124 ; CHECKIFD: # %bb.0:
1125 ; CHECKIFD-NEXT: fnmadd.d fa0, fa0, fa1, fa2
1126 ; CHECKIFD-NEXT: ret
1128 ; RV32IZFINXZDINX-LABEL: fnmadd_nsz:
1129 ; RV32IZFINXZDINX: # %bb.0:
1130 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1131 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1132 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1133 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1134 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1135 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1136 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1137 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1138 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1139 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1140 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1141 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1142 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1143 ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4
1144 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1145 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1146 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1147 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1148 ; RV32IZFINXZDINX-NEXT: lui a2, 524288
1149 ; RV32IZFINXZDINX-NEXT: xor a1, a1, a2
1150 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1151 ; RV32IZFINXZDINX-NEXT: ret
1153 ; RV64IZFINXZDINX-LABEL: fnmadd_nsz:
1154 ; RV64IZFINXZDINX: # %bb.0:
1155 ; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2
1156 ; RV64IZFINXZDINX-NEXT: li a1, -1
1157 ; RV64IZFINXZDINX-NEXT: slli a1, a1, 63
1158 ; RV64IZFINXZDINX-NEXT: xor a0, a0, a1
1159 ; RV64IZFINXZDINX-NEXT: ret
1161 ; RV32I-LABEL: fnmadd_nsz:
1163 ; RV32I-NEXT: addi sp, sp, -16
1164 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1165 ; RV32I-NEXT: call fma@plt
1166 ; RV32I-NEXT: lui a2, 524288
1167 ; RV32I-NEXT: xor a1, a1, a2
1168 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1169 ; RV32I-NEXT: addi sp, sp, 16
1172 ; RV64I-LABEL: fnmadd_nsz:
1174 ; RV64I-NEXT: addi sp, sp, -16
1175 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1176 ; RV64I-NEXT: call fma@plt
1177 ; RV64I-NEXT: li a1, -1
1178 ; RV64I-NEXT: slli a1, a1, 63
1179 ; RV64I-NEXT: xor a0, a0, a1
1180 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1181 ; RV64I-NEXT: addi sp, sp, 16
1183 %1 = call nsz double @llvm.fma.f64(double %a, double %b, double %c)
1184 %neg = fneg nsz double %1
1188 define double @fnmsub_d(double %a, double %b, double %c) nounwind {
1189 ; RV32IFD-LABEL: fnmsub_d:
1191 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
1192 ; RV32IFD-NEXT: fadd.d fa5, fa0, fa5
1193 ; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa2
1196 ; RV64IFD-LABEL: fnmsub_d:
1198 ; RV64IFD-NEXT: fmv.d.x fa5, zero
1199 ; RV64IFD-NEXT: fadd.d fa5, fa0, fa5
1200 ; RV64IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa2
1203 ; RV32IZFINXZDINX-LABEL: fnmsub_d:
1204 ; RV32IZFINXZDINX: # %bb.0:
1205 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1206 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1207 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1208 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1209 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1210 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1211 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1212 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1213 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1214 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1215 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1216 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1217 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1218 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
1219 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6
1220 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4
1221 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1222 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1223 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1224 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1225 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1226 ; RV32IZFINXZDINX-NEXT: ret
1228 ; RV64IZFINXZDINX-LABEL: fnmsub_d:
1229 ; RV64IZFINXZDINX: # %bb.0:
1230 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero
1231 ; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a0, a1, a2
1232 ; RV64IZFINXZDINX-NEXT: ret
1234 ; RV32I-LABEL: fnmsub_d:
1236 ; RV32I-NEXT: addi sp, sp, -32
1237 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1238 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1239 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1240 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1241 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
1242 ; RV32I-NEXT: mv s0, a5
1243 ; RV32I-NEXT: mv s1, a4
1244 ; RV32I-NEXT: mv s2, a3
1245 ; RV32I-NEXT: mv s3, a2
1246 ; RV32I-NEXT: li a2, 0
1247 ; RV32I-NEXT: li a3, 0
1248 ; RV32I-NEXT: call __adddf3@plt
1249 ; RV32I-NEXT: lui a2, 524288
1250 ; RV32I-NEXT: xor a1, a1, a2
1251 ; RV32I-NEXT: mv a2, s3
1252 ; RV32I-NEXT: mv a3, s2
1253 ; RV32I-NEXT: mv a4, s1
1254 ; RV32I-NEXT: mv a5, s0
1255 ; RV32I-NEXT: call fma@plt
1256 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1257 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1258 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1259 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1260 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1261 ; RV32I-NEXT: addi sp, sp, 32
1264 ; RV64I-LABEL: fnmsub_d:
1266 ; RV64I-NEXT: addi sp, sp, -32
1267 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1268 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1269 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1270 ; RV64I-NEXT: mv s0, a2
1271 ; RV64I-NEXT: mv s1, a1
1272 ; RV64I-NEXT: li a1, 0
1273 ; RV64I-NEXT: call __adddf3@plt
1274 ; RV64I-NEXT: li a1, -1
1275 ; RV64I-NEXT: slli a1, a1, 63
1276 ; RV64I-NEXT: xor a0, a0, a1
1277 ; RV64I-NEXT: mv a1, s1
1278 ; RV64I-NEXT: mv a2, s0
1279 ; RV64I-NEXT: call fma@plt
1280 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1281 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1282 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1283 ; RV64I-NEXT: addi sp, sp, 32
1285 %a_ = fadd double 0.0, %a
1286 %nega = fsub double -0.0, %a_
1287 %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
1291 define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
1292 ; RV32IFD-LABEL: fnmsub_d_2:
1294 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
1295 ; RV32IFD-NEXT: fadd.d fa5, fa1, fa5
1296 ; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa2
1299 ; RV64IFD-LABEL: fnmsub_d_2:
1301 ; RV64IFD-NEXT: fmv.d.x fa5, zero
1302 ; RV64IFD-NEXT: fadd.d fa5, fa1, fa5
1303 ; RV64IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa2
1306 ; RV32IZFINXZDINX-LABEL: fnmsub_d_2:
1307 ; RV32IZFINXZDINX: # %bb.0:
1308 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1309 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1310 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1311 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1312 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1313 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1314 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1315 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1316 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1317 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1318 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1319 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1320 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1321 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
1322 ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6
1323 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a2, a0, a4
1324 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1325 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1326 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1327 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1328 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1329 ; RV32IZFINXZDINX-NEXT: ret
1331 ; RV64IZFINXZDINX-LABEL: fnmsub_d_2:
1332 ; RV64IZFINXZDINX: # %bb.0:
1333 ; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero
1334 ; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a1, a0, a2
1335 ; RV64IZFINXZDINX-NEXT: ret
1337 ; RV32I-LABEL: fnmsub_d_2:
1339 ; RV32I-NEXT: addi sp, sp, -32
1340 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1341 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1342 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1343 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1344 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
1345 ; RV32I-NEXT: mv s0, a5
1346 ; RV32I-NEXT: mv s1, a4
1347 ; RV32I-NEXT: mv s2, a1
1348 ; RV32I-NEXT: mv s3, a0
1349 ; RV32I-NEXT: mv a0, a2
1350 ; RV32I-NEXT: mv a1, a3
1351 ; RV32I-NEXT: li a2, 0
1352 ; RV32I-NEXT: li a3, 0
1353 ; RV32I-NEXT: call __adddf3@plt
1354 ; RV32I-NEXT: mv a2, a0
1355 ; RV32I-NEXT: lui a3, 524288
1356 ; RV32I-NEXT: xor a3, a1, a3
1357 ; RV32I-NEXT: mv a0, s3
1358 ; RV32I-NEXT: mv a1, s2
1359 ; RV32I-NEXT: mv a4, s1
1360 ; RV32I-NEXT: mv a5, s0
1361 ; RV32I-NEXT: call fma@plt
1362 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1363 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1364 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1365 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1366 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1367 ; RV32I-NEXT: addi sp, sp, 32
1370 ; RV64I-LABEL: fnmsub_d_2:
1372 ; RV64I-NEXT: addi sp, sp, -32
1373 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1374 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1375 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1376 ; RV64I-NEXT: mv s0, a2
1377 ; RV64I-NEXT: mv s1, a0
1378 ; RV64I-NEXT: mv a0, a1
1379 ; RV64I-NEXT: li a1, 0
1380 ; RV64I-NEXT: call __adddf3@plt
1381 ; RV64I-NEXT: li a1, -1
1382 ; RV64I-NEXT: slli a1, a1, 63
1383 ; RV64I-NEXT: xor a1, a0, a1
1384 ; RV64I-NEXT: mv a0, s1
1385 ; RV64I-NEXT: mv a2, s0
1386 ; RV64I-NEXT: call fma@plt
1387 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1388 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1389 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1390 ; RV64I-NEXT: addi sp, sp, 32
1392 %b_ = fadd double 0.0, %b
1393 %negb = fsub double -0.0, %b_
1394 %1 = call double @llvm.fma.f64(double %a, double %negb, double %c)
1398 define double @fmadd_d_contract(double %a, double %b, double %c) nounwind {
1399 ; CHECKIFD-LABEL: fmadd_d_contract:
1400 ; CHECKIFD: # %bb.0:
1401 ; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa2
1402 ; CHECKIFD-NEXT: ret
1404 ; RV32IZFINXZDINX-LABEL: fmadd_d_contract:
1405 ; RV32IZFINXZDINX: # %bb.0:
1406 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1407 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1408 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1409 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1410 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1411 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1412 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1413 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1414 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1415 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1416 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1417 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1418 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1419 ; RV32IZFINXZDINX-NEXT: fmadd.d a0, a0, a2, a4
1420 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1421 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1422 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1423 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1424 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1425 ; RV32IZFINXZDINX-NEXT: ret
1427 ; RV64IZFINXZDINX-LABEL: fmadd_d_contract:
1428 ; RV64IZFINXZDINX: # %bb.0:
1429 ; RV64IZFINXZDINX-NEXT: fmadd.d a0, a0, a1, a2
1430 ; RV64IZFINXZDINX-NEXT: ret
1432 ; RV32I-LABEL: fmadd_d_contract:
1434 ; RV32I-NEXT: addi sp, sp, -16
1435 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1436 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
1437 ; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
1438 ; RV32I-NEXT: mv s0, a5
1439 ; RV32I-NEXT: mv s1, a4
1440 ; RV32I-NEXT: call __muldf3@plt
1441 ; RV32I-NEXT: mv a2, s1
1442 ; RV32I-NEXT: mv a3, s0
1443 ; RV32I-NEXT: call __adddf3@plt
1444 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1445 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
1446 ; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
1447 ; RV32I-NEXT: addi sp, sp, 16
1450 ; RV64I-LABEL: fmadd_d_contract:
1452 ; RV64I-NEXT: addi sp, sp, -16
1453 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
1454 ; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
1455 ; RV64I-NEXT: mv s0, a2
1456 ; RV64I-NEXT: call __muldf3@plt
1457 ; RV64I-NEXT: mv a1, s0
1458 ; RV64I-NEXT: call __adddf3@plt
1459 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
1460 ; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
1461 ; RV64I-NEXT: addi sp, sp, 16
1463 %1 = fmul contract double %a, %b
1464 %2 = fadd contract double %1, %c
1468 define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
1469 ; RV32IFD-LABEL: fmsub_d_contract:
1471 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
1472 ; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
1473 ; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5
1476 ; RV64IFD-LABEL: fmsub_d_contract:
1478 ; RV64IFD-NEXT: fmv.d.x fa5, zero
1479 ; RV64IFD-NEXT: fadd.d fa5, fa2, fa5
1480 ; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5
1483 ; RV32IZFINXZDINX-LABEL: fmsub_d_contract:
1484 ; RV32IZFINXZDINX: # %bb.0:
1485 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1486 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1487 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1488 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1489 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1490 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1491 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1492 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1493 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1494 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1495 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1496 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1497 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1498 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
1499 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6
1500 ; RV32IZFINXZDINX-NEXT: fmsub.d a0, a0, a2, a4
1501 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1502 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1503 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1504 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1505 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1506 ; RV32IZFINXZDINX-NEXT: ret
1508 ; RV64IZFINXZDINX-LABEL: fmsub_d_contract:
1509 ; RV64IZFINXZDINX: # %bb.0:
1510 ; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero
1511 ; RV64IZFINXZDINX-NEXT: fmsub.d a0, a0, a1, a2
1512 ; RV64IZFINXZDINX-NEXT: ret
1514 ; RV32I-LABEL: fmsub_d_contract:
1516 ; RV32I-NEXT: addi sp, sp, -32
1517 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1518 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1519 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1520 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1521 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
1522 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
1523 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
1524 ; RV32I-NEXT: mv s0, a3
1525 ; RV32I-NEXT: mv s1, a2
1526 ; RV32I-NEXT: mv s2, a1
1527 ; RV32I-NEXT: mv s3, a0
1528 ; RV32I-NEXT: mv a0, a4
1529 ; RV32I-NEXT: mv a1, a5
1530 ; RV32I-NEXT: li a2, 0
1531 ; RV32I-NEXT: li a3, 0
1532 ; RV32I-NEXT: call __adddf3@plt
1533 ; RV32I-NEXT: mv s4, a0
1534 ; RV32I-NEXT: mv s5, a1
1535 ; RV32I-NEXT: mv a0, s3
1536 ; RV32I-NEXT: mv a1, s2
1537 ; RV32I-NEXT: mv a2, s1
1538 ; RV32I-NEXT: mv a3, s0
1539 ; RV32I-NEXT: call __muldf3@plt
1540 ; RV32I-NEXT: mv a2, s4
1541 ; RV32I-NEXT: mv a3, s5
1542 ; RV32I-NEXT: call __subdf3@plt
1543 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1544 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1545 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1546 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1547 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1548 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
1549 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
1550 ; RV32I-NEXT: addi sp, sp, 32
1553 ; RV64I-LABEL: fmsub_d_contract:
1555 ; RV64I-NEXT: addi sp, sp, -32
1556 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1557 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1558 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1559 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1560 ; RV64I-NEXT: mv s0, a1
1561 ; RV64I-NEXT: mv s1, a0
1562 ; RV64I-NEXT: mv a0, a2
1563 ; RV64I-NEXT: li a1, 0
1564 ; RV64I-NEXT: call __adddf3@plt
1565 ; RV64I-NEXT: mv s2, a0
1566 ; RV64I-NEXT: mv a0, s1
1567 ; RV64I-NEXT: mv a1, s0
1568 ; RV64I-NEXT: call __muldf3@plt
1569 ; RV64I-NEXT: mv a1, s2
1570 ; RV64I-NEXT: call __subdf3@plt
1571 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1572 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1573 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1574 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1575 ; RV64I-NEXT: addi sp, sp, 32
1577 %c_ = fadd double 0.0, %c ; avoid negation using xor
1578 %1 = fmul contract double %a, %b
1579 %2 = fsub contract double %1, %c_
1583 define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
1584 ; RV32IFD-LABEL: fnmadd_d_contract:
1586 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
1587 ; RV32IFD-NEXT: fadd.d fa4, fa0, fa5
1588 ; RV32IFD-NEXT: fadd.d fa3, fa1, fa5
1589 ; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
1590 ; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa3, fa5
1593 ; RV64IFD-LABEL: fnmadd_d_contract:
1595 ; RV64IFD-NEXT: fmv.d.x fa5, zero
1596 ; RV64IFD-NEXT: fadd.d fa4, fa0, fa5
1597 ; RV64IFD-NEXT: fadd.d fa3, fa1, fa5
1598 ; RV64IFD-NEXT: fadd.d fa5, fa2, fa5
1599 ; RV64IFD-NEXT: fnmadd.d fa0, fa4, fa3, fa5
1602 ; RV32IZFINXZDINX-LABEL: fnmadd_d_contract:
1603 ; RV32IZFINXZDINX: # %bb.0:
1604 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1605 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1606 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1607 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1608 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1609 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1610 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1611 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1612 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1613 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1614 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1615 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1616 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1617 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
1618 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6
1619 ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6
1620 ; RV32IZFINXZDINX-NEXT: fadd.d a4, a4, a6
1621 ; RV32IZFINXZDINX-NEXT: fnmadd.d a0, a0, a2, a4
1622 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1623 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1624 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1625 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1626 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1627 ; RV32IZFINXZDINX-NEXT: ret
1629 ; RV64IZFINXZDINX-LABEL: fnmadd_d_contract:
1630 ; RV64IZFINXZDINX: # %bb.0:
1631 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero
1632 ; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero
1633 ; RV64IZFINXZDINX-NEXT: fadd.d a2, a2, zero
1634 ; RV64IZFINXZDINX-NEXT: fnmadd.d a0, a0, a1, a2
1635 ; RV64IZFINXZDINX-NEXT: ret
1637 ; RV32I-LABEL: fnmadd_d_contract:
1639 ; RV32I-NEXT: addi sp, sp, -32
1640 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1641 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1642 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1643 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1644 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
1645 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
1646 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
1647 ; RV32I-NEXT: mv s0, a5
1648 ; RV32I-NEXT: mv s1, a4
1649 ; RV32I-NEXT: mv s2, a3
1650 ; RV32I-NEXT: mv s3, a2
1651 ; RV32I-NEXT: li a2, 0
1652 ; RV32I-NEXT: li a3, 0
1653 ; RV32I-NEXT: call __adddf3@plt
1654 ; RV32I-NEXT: mv s4, a0
1655 ; RV32I-NEXT: mv s5, a1
1656 ; RV32I-NEXT: mv a0, s3
1657 ; RV32I-NEXT: mv a1, s2
1658 ; RV32I-NEXT: li a2, 0
1659 ; RV32I-NEXT: li a3, 0
1660 ; RV32I-NEXT: call __adddf3@plt
1661 ; RV32I-NEXT: mv s2, a0
1662 ; RV32I-NEXT: mv s3, a1
1663 ; RV32I-NEXT: mv a0, s1
1664 ; RV32I-NEXT: mv a1, s0
1665 ; RV32I-NEXT: li a2, 0
1666 ; RV32I-NEXT: li a3, 0
1667 ; RV32I-NEXT: call __adddf3@plt
1668 ; RV32I-NEXT: mv s0, a0
1669 ; RV32I-NEXT: mv s1, a1
1670 ; RV32I-NEXT: mv a0, s4
1671 ; RV32I-NEXT: mv a1, s5
1672 ; RV32I-NEXT: mv a2, s2
1673 ; RV32I-NEXT: mv a3, s3
1674 ; RV32I-NEXT: call __muldf3@plt
1675 ; RV32I-NEXT: lui a2, 524288
1676 ; RV32I-NEXT: xor a1, a1, a2
1677 ; RV32I-NEXT: mv a2, s0
1678 ; RV32I-NEXT: mv a3, s1
1679 ; RV32I-NEXT: call __subdf3@plt
1680 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1681 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1682 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1683 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1684 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1685 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
1686 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
1687 ; RV32I-NEXT: addi sp, sp, 32
1690 ; RV64I-LABEL: fnmadd_d_contract:
1692 ; RV64I-NEXT: addi sp, sp, -32
1693 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1694 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1695 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1696 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1697 ; RV64I-NEXT: mv s0, a2
1698 ; RV64I-NEXT: mv s1, a1
1699 ; RV64I-NEXT: li a1, 0
1700 ; RV64I-NEXT: call __adddf3@plt
1701 ; RV64I-NEXT: mv s2, a0
1702 ; RV64I-NEXT: mv a0, s1
1703 ; RV64I-NEXT: li a1, 0
1704 ; RV64I-NEXT: call __adddf3@plt
1705 ; RV64I-NEXT: mv s1, a0
1706 ; RV64I-NEXT: mv a0, s0
1707 ; RV64I-NEXT: li a1, 0
1708 ; RV64I-NEXT: call __adddf3@plt
1709 ; RV64I-NEXT: mv s0, a0
1710 ; RV64I-NEXT: mv a0, s2
1711 ; RV64I-NEXT: mv a1, s1
1712 ; RV64I-NEXT: call __muldf3@plt
1713 ; RV64I-NEXT: li a1, -1
1714 ; RV64I-NEXT: slli a1, a1, 63
1715 ; RV64I-NEXT: xor a0, a0, a1
1716 ; RV64I-NEXT: mv a1, s0
1717 ; RV64I-NEXT: call __subdf3@plt
1718 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1719 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1720 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1721 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1722 ; RV64I-NEXT: addi sp, sp, 32
1724 %a_ = fadd double 0.0, %a ; avoid negation using xor
1725 %b_ = fadd double 0.0, %b ; avoid negation using xor
1726 %c_ = fadd double 0.0, %c ; avoid negation using xor
1727 %1 = fmul contract double %a_, %b_
1729 %3 = fsub contract double %2, %c_
1733 define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
1734 ; RV32IFD-LABEL: fnmsub_d_contract:
1736 ; RV32IFD-NEXT: fcvt.d.w fa5, zero
1737 ; RV32IFD-NEXT: fadd.d fa4, fa0, fa5
1738 ; RV32IFD-NEXT: fadd.d fa5, fa1, fa5
1739 ; RV32IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa2
1742 ; RV64IFD-LABEL: fnmsub_d_contract:
1744 ; RV64IFD-NEXT: fmv.d.x fa5, zero
1745 ; RV64IFD-NEXT: fadd.d fa4, fa0, fa5
1746 ; RV64IFD-NEXT: fadd.d fa5, fa1, fa5
1747 ; RV64IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa2
1750 ; RV32IZFINXZDINX-LABEL: fnmsub_d_contract:
1751 ; RV32IZFINXZDINX: # %bb.0:
1752 ; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1753 ; RV32IZFINXZDINX-NEXT: sw a4, 8(sp)
1754 ; RV32IZFINXZDINX-NEXT: sw a5, 12(sp)
1755 ; RV32IZFINXZDINX-NEXT: lw a4, 8(sp)
1756 ; RV32IZFINXZDINX-NEXT: lw a5, 12(sp)
1757 ; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
1758 ; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
1759 ; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
1760 ; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
1761 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1762 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1763 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1764 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1765 ; RV32IZFINXZDINX-NEXT: fcvt.d.w a6, zero
1766 ; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a6
1767 ; RV32IZFINXZDINX-NEXT: fadd.d a2, a2, a6
1768 ; RV32IZFINXZDINX-NEXT: fnmsub.d a0, a0, a2, a4
1769 ; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1770 ; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1771 ; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1772 ; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1773 ; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1774 ; RV32IZFINXZDINX-NEXT: ret
1776 ; RV64IZFINXZDINX-LABEL: fnmsub_d_contract:
1777 ; RV64IZFINXZDINX: # %bb.0:
1778 ; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, zero
1779 ; RV64IZFINXZDINX-NEXT: fadd.d a1, a1, zero
1780 ; RV64IZFINXZDINX-NEXT: fnmsub.d a0, a0, a1, a2
1781 ; RV64IZFINXZDINX-NEXT: ret
1783 ; RV32I-LABEL: fnmsub_d_contract:
1785 ; RV32I-NEXT: addi sp, sp, -32
1786 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1787 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1788 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1789 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1790 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
1791 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
1792 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
1793 ; RV32I-NEXT: mv s0, a5
1794 ; RV32I-NEXT: mv s1, a4
1795 ; RV32I-NEXT: mv s2, a3
1796 ; RV32I-NEXT: mv s3, a2
1797 ; RV32I-NEXT: li a2, 0
1798 ; RV32I-NEXT: li a3, 0
1799 ; RV32I-NEXT: call __adddf3@plt
1800 ; RV32I-NEXT: mv s4, a0
1801 ; RV32I-NEXT: mv s5, a1
1802 ; RV32I-NEXT: mv a0, s3
1803 ; RV32I-NEXT: mv a1, s2
1804 ; RV32I-NEXT: li a2, 0
1805 ; RV32I-NEXT: li a3, 0
1806 ; RV32I-NEXT: call __adddf3@plt
1807 ; RV32I-NEXT: mv a2, a0
1808 ; RV32I-NEXT: mv a3, a1
1809 ; RV32I-NEXT: mv a0, s4
1810 ; RV32I-NEXT: mv a1, s5
1811 ; RV32I-NEXT: call __muldf3@plt
1812 ; RV32I-NEXT: mv a2, a0
1813 ; RV32I-NEXT: mv a3, a1
1814 ; RV32I-NEXT: mv a0, s1
1815 ; RV32I-NEXT: mv a1, s0
1816 ; RV32I-NEXT: call __subdf3@plt
1817 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1818 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1819 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1820 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1821 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
1822 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
1823 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
1824 ; RV32I-NEXT: addi sp, sp, 32
1827 ; RV64I-LABEL: fnmsub_d_contract:
1829 ; RV64I-NEXT: addi sp, sp, -32
1830 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
1831 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
1832 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
1833 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
1834 ; RV64I-NEXT: mv s0, a2
1835 ; RV64I-NEXT: mv s1, a1
1836 ; RV64I-NEXT: li a1, 0
1837 ; RV64I-NEXT: call __adddf3@plt
1838 ; RV64I-NEXT: mv s2, a0
1839 ; RV64I-NEXT: mv a0, s1
1840 ; RV64I-NEXT: li a1, 0
1841 ; RV64I-NEXT: call __adddf3@plt
1842 ; RV64I-NEXT: mv a1, a0
1843 ; RV64I-NEXT: mv a0, s2
1844 ; RV64I-NEXT: call __muldf3@plt
1845 ; RV64I-NEXT: mv a1, a0
1846 ; RV64I-NEXT: mv a0, s0
1847 ; RV64I-NEXT: call __subdf3@plt
1848 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
1849 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
1850 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
1851 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
1852 ; RV64I-NEXT: addi sp, sp, 32
1854 %a_ = fadd double 0.0, %a ; avoid negation using xor
1855 %b_ = fadd double 0.0, %b ; avoid negation using xor
1856 %1 = fmul contract double %a_, %b_
1857 %2 = fsub contract double %c, %1