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: -disable-strictnode-mutation -target-abi=ilp32d \
4 ; RUN: | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s
5 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
6 ; RUN: -disable-strictnode-mutation -target-abi=lp64d \
7 ; RUN: | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s
8 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
9 ; RUN: -disable-strictnode-mutation | FileCheck -check-prefix=RV32I %s
10 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
11 ; RUN: -disable-strictnode-mutation | FileCheck -check-prefix=RV64I %s
13 define double @fadd_d(double %a, double %b) nounwind strictfp {
14 ; CHECKIFD-LABEL: fadd_d:
16 ; CHECKIFD-NEXT: fadd.d fa0, fa0, fa1
19 ; RV32I-LABEL: fadd_d:
21 ; RV32I-NEXT: addi sp, sp, -16
22 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
23 ; RV32I-NEXT: call __adddf3@plt
24 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
25 ; RV32I-NEXT: addi sp, sp, 16
28 ; RV64I-LABEL: fadd_d:
30 ; RV64I-NEXT: addi sp, sp, -16
31 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
32 ; RV64I-NEXT: call __adddf3@plt
33 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
34 ; RV64I-NEXT: addi sp, sp, 16
36 %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
39 declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
41 define double @fsub_d(double %a, double %b) nounwind strictfp {
42 ; CHECKIFD-LABEL: fsub_d:
44 ; CHECKIFD-NEXT: fsub.d fa0, fa0, fa1
47 ; RV32I-LABEL: fsub_d:
49 ; RV32I-NEXT: addi sp, sp, -16
50 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
51 ; RV32I-NEXT: call __subdf3@plt
52 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
53 ; RV32I-NEXT: addi sp, sp, 16
56 ; RV64I-LABEL: fsub_d:
58 ; RV64I-NEXT: addi sp, sp, -16
59 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
60 ; RV64I-NEXT: call __subdf3@plt
61 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
62 ; RV64I-NEXT: addi sp, sp, 16
64 %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
67 declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
69 define double @fmul_d(double %a, double %b) nounwind strictfp {
70 ; CHECKIFD-LABEL: fmul_d:
72 ; CHECKIFD-NEXT: fmul.d fa0, fa0, fa1
75 ; RV32I-LABEL: fmul_d:
77 ; RV32I-NEXT: addi sp, sp, -16
78 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
79 ; RV32I-NEXT: call __muldf3@plt
80 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
81 ; RV32I-NEXT: addi sp, sp, 16
84 ; RV64I-LABEL: fmul_d:
86 ; RV64I-NEXT: addi sp, sp, -16
87 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
88 ; RV64I-NEXT: call __muldf3@plt
89 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
90 ; RV64I-NEXT: addi sp, sp, 16
92 %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
95 declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
97 define double @fdiv_d(double %a, double %b) nounwind strictfp {
98 ; CHECKIFD-LABEL: fdiv_d:
100 ; CHECKIFD-NEXT: fdiv.d fa0, fa0, fa1
103 ; RV32I-LABEL: fdiv_d:
105 ; RV32I-NEXT: addi sp, sp, -16
106 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
107 ; RV32I-NEXT: call __divdf3@plt
108 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
109 ; RV32I-NEXT: addi sp, sp, 16
112 ; RV64I-LABEL: fdiv_d:
114 ; RV64I-NEXT: addi sp, sp, -16
115 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
116 ; RV64I-NEXT: call __divdf3@plt
117 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
118 ; RV64I-NEXT: addi sp, sp, 16
120 %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
123 declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
125 define double @fsqrt_d(double %a) nounwind strictfp {
126 ; CHECKIFD-LABEL: fsqrt_d:
128 ; CHECKIFD-NEXT: fsqrt.d fa0, fa0
131 ; RV32I-LABEL: fsqrt_d:
133 ; RV32I-NEXT: addi sp, sp, -16
134 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
135 ; RV32I-NEXT: call sqrt@plt
136 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
137 ; RV32I-NEXT: addi sp, sp, 16
140 ; RV64I-LABEL: fsqrt_d:
142 ; RV64I-NEXT: addi sp, sp, -16
143 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
144 ; RV64I-NEXT: call sqrt@plt
145 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
146 ; RV64I-NEXT: addi sp, sp, 16
148 %1 = call double @llvm.experimental.constrained.sqrt.f64(double %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
151 declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata)
153 define double @fmin_d(double %a, double %b) nounwind strictfp {
154 ; RV32IFD-LABEL: fmin_d:
156 ; RV32IFD-NEXT: addi sp, sp, -16
157 ; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
158 ; RV32IFD-NEXT: call fmin@plt
159 ; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
160 ; RV32IFD-NEXT: addi sp, sp, 16
163 ; RV64IFD-LABEL: fmin_d:
165 ; RV64IFD-NEXT: addi sp, sp, -16
166 ; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
167 ; RV64IFD-NEXT: call fmin@plt
168 ; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
169 ; RV64IFD-NEXT: addi sp, sp, 16
172 ; RV32I-LABEL: fmin_d:
174 ; RV32I-NEXT: addi sp, sp, -16
175 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
176 ; RV32I-NEXT: call fmin@plt
177 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
178 ; RV32I-NEXT: addi sp, sp, 16
181 ; RV64I-LABEL: fmin_d:
183 ; RV64I-NEXT: addi sp, sp, -16
184 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
185 ; RV64I-NEXT: call fmin@plt
186 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
187 ; RV64I-NEXT: addi sp, sp, 16
189 %1 = call double @llvm.experimental.constrained.minnum.f64(double %a, double %b, metadata !"fpexcept.strict") strictfp
192 declare double @llvm.experimental.constrained.minnum.f64(double, double, metadata) strictfp
194 define double @fmax_d(double %a, double %b) nounwind strictfp {
195 ; RV32IFD-LABEL: fmax_d:
197 ; RV32IFD-NEXT: addi sp, sp, -16
198 ; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
199 ; RV32IFD-NEXT: call fmax@plt
200 ; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
201 ; RV32IFD-NEXT: addi sp, sp, 16
204 ; RV64IFD-LABEL: fmax_d:
206 ; RV64IFD-NEXT: addi sp, sp, -16
207 ; RV64IFD-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
208 ; RV64IFD-NEXT: call fmax@plt
209 ; RV64IFD-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
210 ; RV64IFD-NEXT: addi sp, sp, 16
213 ; RV32I-LABEL: fmax_d:
215 ; RV32I-NEXT: addi sp, sp, -16
216 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
217 ; RV32I-NEXT: call fmax@plt
218 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
219 ; RV32I-NEXT: addi sp, sp, 16
222 ; RV64I-LABEL: fmax_d:
224 ; RV64I-NEXT: addi sp, sp, -16
225 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
226 ; RV64I-NEXT: call fmax@plt
227 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
228 ; RV64I-NEXT: addi sp, sp, 16
230 %1 = call double @llvm.experimental.constrained.maxnum.f64(double %a, double %b, metadata !"fpexcept.strict") strictfp
233 declare double @llvm.experimental.constrained.maxnum.f64(double, double, metadata) strictfp
235 define double @fmadd_d(double %a, double %b, double %c) nounwind strictfp {
236 ; CHECKIFD-LABEL: fmadd_d:
238 ; CHECKIFD-NEXT: fmadd.d fa0, fa0, fa1, fa2
241 ; RV32I-LABEL: fmadd_d:
243 ; RV32I-NEXT: addi sp, sp, -16
244 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
245 ; RV32I-NEXT: call fma@plt
246 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
247 ; RV32I-NEXT: addi sp, sp, 16
250 ; RV64I-LABEL: fmadd_d:
252 ; RV64I-NEXT: addi sp, sp, -16
253 ; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
254 ; RV64I-NEXT: call fma@plt
255 ; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
256 ; RV64I-NEXT: addi sp, sp, 16
258 %1 = call double @llvm.experimental.constrained.fma.f64(double %a, double %b, double %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
261 declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata) strictfp
263 define double @fmsub_d(double %a, double %b, double %c) nounwind strictfp {
264 ; RV32IFD-LABEL: fmsub_d:
266 ; RV32IFD-NEXT: fcvt.d.w ft0, zero
267 ; RV32IFD-NEXT: fadd.d ft0, fa2, ft0
268 ; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, ft0
271 ; RV64IFD-LABEL: fmsub_d:
273 ; RV64IFD-NEXT: fmv.d.x ft0, zero
274 ; RV64IFD-NEXT: fadd.d ft0, fa2, ft0
275 ; RV64IFD-NEXT: fmsub.d fa0, fa0, fa1, ft0
278 ; RV32I-LABEL: fmsub_d:
280 ; RV32I-NEXT: addi sp, sp, -32
281 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
282 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
283 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
284 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
285 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
286 ; RV32I-NEXT: mv s0, a3
287 ; RV32I-NEXT: mv s1, a2
288 ; RV32I-NEXT: mv s2, a1
289 ; RV32I-NEXT: mv s3, a0
290 ; RV32I-NEXT: mv a0, a4
291 ; RV32I-NEXT: mv a1, a5
292 ; RV32I-NEXT: li a2, 0
293 ; RV32I-NEXT: li a3, 0
294 ; RV32I-NEXT: call __adddf3@plt
295 ; RV32I-NEXT: mv a4, a0
296 ; RV32I-NEXT: lui a0, 524288
297 ; RV32I-NEXT: xor a5, a1, a0
298 ; RV32I-NEXT: mv a0, s3
299 ; RV32I-NEXT: mv a1, s2
300 ; RV32I-NEXT: mv a2, s1
301 ; RV32I-NEXT: mv a3, s0
302 ; RV32I-NEXT: call fma@plt
303 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
304 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
305 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
306 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
307 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
308 ; RV32I-NEXT: addi sp, sp, 32
311 ; RV64I-LABEL: fmsub_d:
313 ; RV64I-NEXT: addi sp, sp, -32
314 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
315 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
316 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
317 ; RV64I-NEXT: mv s0, a1
318 ; RV64I-NEXT: mv s1, a0
319 ; RV64I-NEXT: mv a0, a2
320 ; RV64I-NEXT: li a1, 0
321 ; RV64I-NEXT: call __adddf3@plt
322 ; RV64I-NEXT: li a1, -1
323 ; RV64I-NEXT: slli a1, a1, 63
324 ; RV64I-NEXT: xor a2, a0, a1
325 ; RV64I-NEXT: mv a0, s1
326 ; RV64I-NEXT: mv a1, s0
327 ; RV64I-NEXT: call fma@plt
328 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
329 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
330 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
331 ; RV64I-NEXT: addi sp, sp, 32
333 %c_ = fadd double 0.0, %c ; avoid negation using xor
334 %negc = fneg double %c_
335 %1 = call double @llvm.experimental.constrained.fma.f64(double %a, double %b, double %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
339 define double @fnmadd_d(double %a, double %b, double %c) nounwind strictfp {
340 ; RV32IFD-LABEL: fnmadd_d:
342 ; RV32IFD-NEXT: fcvt.d.w ft0, zero
343 ; RV32IFD-NEXT: fadd.d ft1, fa0, ft0
344 ; RV32IFD-NEXT: fadd.d ft0, fa2, ft0
345 ; RV32IFD-NEXT: fnmadd.d fa0, ft1, fa1, ft0
348 ; RV64IFD-LABEL: fnmadd_d:
350 ; RV64IFD-NEXT: fmv.d.x ft0, zero
351 ; RV64IFD-NEXT: fadd.d ft1, fa0, ft0
352 ; RV64IFD-NEXT: fadd.d ft0, fa2, ft0
353 ; RV64IFD-NEXT: fnmadd.d fa0, ft1, fa1, ft0
356 ; RV32I-LABEL: fnmadd_d:
358 ; RV32I-NEXT: addi sp, sp, -32
359 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
360 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
361 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
362 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
363 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
364 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
365 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
366 ; RV32I-NEXT: mv s0, a5
367 ; RV32I-NEXT: mv s1, a4
368 ; RV32I-NEXT: mv s2, a3
369 ; RV32I-NEXT: mv s3, a2
370 ; RV32I-NEXT: li a2, 0
371 ; RV32I-NEXT: li a3, 0
372 ; RV32I-NEXT: call __adddf3@plt
373 ; RV32I-NEXT: mv s4, a0
374 ; RV32I-NEXT: mv s5, a1
375 ; RV32I-NEXT: mv a0, s1
376 ; RV32I-NEXT: mv a1, s0
377 ; RV32I-NEXT: li a2, 0
378 ; RV32I-NEXT: li a3, 0
379 ; RV32I-NEXT: call __adddf3@plt
380 ; RV32I-NEXT: mv a4, a0
381 ; RV32I-NEXT: lui a0, 524288
382 ; RV32I-NEXT: xor a2, s5, a0
383 ; RV32I-NEXT: xor a5, a1, a0
384 ; RV32I-NEXT: mv a0, s4
385 ; RV32I-NEXT: mv a1, a2
386 ; RV32I-NEXT: mv a2, s3
387 ; RV32I-NEXT: mv a3, s2
388 ; RV32I-NEXT: call fma@plt
389 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
390 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
391 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
392 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
393 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
394 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
395 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
396 ; RV32I-NEXT: addi sp, sp, 32
399 ; RV64I-LABEL: fnmadd_d:
401 ; RV64I-NEXT: addi sp, sp, -32
402 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
403 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
404 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
405 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
406 ; RV64I-NEXT: mv s0, a2
407 ; RV64I-NEXT: mv s1, a1
408 ; RV64I-NEXT: li a1, 0
409 ; RV64I-NEXT: call __adddf3@plt
410 ; RV64I-NEXT: mv s2, a0
411 ; RV64I-NEXT: mv a0, s0
412 ; RV64I-NEXT: li a1, 0
413 ; RV64I-NEXT: call __adddf3@plt
414 ; RV64I-NEXT: li a1, -1
415 ; RV64I-NEXT: slli a2, a1, 63
416 ; RV64I-NEXT: xor a1, s2, a2
417 ; RV64I-NEXT: xor a2, a0, a2
418 ; RV64I-NEXT: mv a0, a1
419 ; RV64I-NEXT: mv a1, s1
420 ; RV64I-NEXT: call fma@plt
421 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
422 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
423 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
424 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
425 ; RV64I-NEXT: addi sp, sp, 32
427 %a_ = fadd double 0.0, %a
428 %c_ = fadd double 0.0, %c
429 %nega = fneg double %a_
430 %negc = fneg double %c_
431 %1 = call double @llvm.experimental.constrained.fma.f64(double %nega, double %b, double %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
435 define double @fnmadd_d_2(double %a, double %b, double %c) nounwind strictfp {
436 ; RV32IFD-LABEL: fnmadd_d_2:
438 ; RV32IFD-NEXT: fcvt.d.w ft0, zero
439 ; RV32IFD-NEXT: fadd.d ft1, fa1, ft0
440 ; RV32IFD-NEXT: fadd.d ft0, fa2, ft0
441 ; RV32IFD-NEXT: fnmadd.d fa0, ft1, fa0, ft0
444 ; RV64IFD-LABEL: fnmadd_d_2:
446 ; RV64IFD-NEXT: fmv.d.x ft0, zero
447 ; RV64IFD-NEXT: fadd.d ft1, fa1, ft0
448 ; RV64IFD-NEXT: fadd.d ft0, fa2, ft0
449 ; RV64IFD-NEXT: fnmadd.d fa0, ft1, fa0, ft0
452 ; RV32I-LABEL: fnmadd_d_2:
454 ; RV32I-NEXT: addi sp, sp, -32
455 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
456 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
457 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
458 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
459 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
460 ; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
461 ; RV32I-NEXT: sw s5, 4(sp) # 4-byte Folded Spill
462 ; RV32I-NEXT: mv s0, a5
463 ; RV32I-NEXT: mv s1, a4
464 ; RV32I-NEXT: mv s2, a1
465 ; RV32I-NEXT: mv s3, a0
466 ; RV32I-NEXT: mv a0, a2
467 ; RV32I-NEXT: mv a1, a3
468 ; RV32I-NEXT: li a2, 0
469 ; RV32I-NEXT: li a3, 0
470 ; RV32I-NEXT: call __adddf3@plt
471 ; RV32I-NEXT: mv s4, a0
472 ; RV32I-NEXT: mv s5, a1
473 ; RV32I-NEXT: mv a0, s1
474 ; RV32I-NEXT: mv a1, s0
475 ; RV32I-NEXT: li a2, 0
476 ; RV32I-NEXT: li a3, 0
477 ; RV32I-NEXT: call __adddf3@plt
478 ; RV32I-NEXT: mv a4, a0
479 ; RV32I-NEXT: lui a0, 524288
480 ; RV32I-NEXT: xor a3, s5, a0
481 ; RV32I-NEXT: xor a5, a1, a0
482 ; RV32I-NEXT: mv a0, s3
483 ; RV32I-NEXT: mv a1, s2
484 ; RV32I-NEXT: mv a2, s4
485 ; RV32I-NEXT: call fma@plt
486 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
487 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
488 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
489 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
490 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
491 ; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
492 ; RV32I-NEXT: lw s5, 4(sp) # 4-byte Folded Reload
493 ; RV32I-NEXT: addi sp, sp, 32
496 ; RV64I-LABEL: fnmadd_d_2:
498 ; RV64I-NEXT: addi sp, sp, -32
499 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
500 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
501 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
502 ; RV64I-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
503 ; RV64I-NEXT: mv s0, a2
504 ; RV64I-NEXT: mv s1, a0
505 ; RV64I-NEXT: mv a0, a1
506 ; RV64I-NEXT: li a1, 0
507 ; RV64I-NEXT: call __adddf3@plt
508 ; RV64I-NEXT: mv s2, a0
509 ; RV64I-NEXT: mv a0, s0
510 ; RV64I-NEXT: li a1, 0
511 ; RV64I-NEXT: call __adddf3@plt
512 ; RV64I-NEXT: li a1, -1
513 ; RV64I-NEXT: slli a2, a1, 63
514 ; RV64I-NEXT: xor a1, s2, a2
515 ; RV64I-NEXT: xor a2, a0, a2
516 ; RV64I-NEXT: mv a0, s1
517 ; RV64I-NEXT: call fma@plt
518 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
519 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
520 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
521 ; RV64I-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
522 ; RV64I-NEXT: addi sp, sp, 32
524 %b_ = fadd double 0.0, %b
525 %c_ = fadd double 0.0, %c
526 %negb = fneg double %b_
527 %negc = fneg double %c_
528 %1 = call double @llvm.experimental.constrained.fma.f64(double %a, double %negb, double %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
532 define double @fnmsub_d(double %a, double %b, double %c) nounwind strictfp {
533 ; RV32IFD-LABEL: fnmsub_d:
535 ; RV32IFD-NEXT: fcvt.d.w ft0, zero
536 ; RV32IFD-NEXT: fadd.d ft0, fa0, ft0
537 ; RV32IFD-NEXT: fnmsub.d fa0, ft0, fa1, fa2
540 ; RV64IFD-LABEL: fnmsub_d:
542 ; RV64IFD-NEXT: fmv.d.x ft0, zero
543 ; RV64IFD-NEXT: fadd.d ft0, fa0, ft0
544 ; RV64IFD-NEXT: fnmsub.d fa0, ft0, fa1, fa2
547 ; RV32I-LABEL: fnmsub_d:
549 ; RV32I-NEXT: addi sp, sp, -32
550 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
551 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
552 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
553 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
554 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
555 ; RV32I-NEXT: mv s0, a5
556 ; RV32I-NEXT: mv s1, a4
557 ; RV32I-NEXT: mv s2, a3
558 ; RV32I-NEXT: mv s3, a2
559 ; RV32I-NEXT: li a2, 0
560 ; RV32I-NEXT: li a3, 0
561 ; RV32I-NEXT: call __adddf3@plt
562 ; RV32I-NEXT: lui a2, 524288
563 ; RV32I-NEXT: xor a1, a1, a2
564 ; RV32I-NEXT: mv a2, s3
565 ; RV32I-NEXT: mv a3, s2
566 ; RV32I-NEXT: mv a4, s1
567 ; RV32I-NEXT: mv a5, s0
568 ; RV32I-NEXT: call fma@plt
569 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
570 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
571 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
572 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
573 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
574 ; RV32I-NEXT: addi sp, sp, 32
577 ; RV64I-LABEL: fnmsub_d:
579 ; RV64I-NEXT: addi sp, sp, -32
580 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
581 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
582 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
583 ; RV64I-NEXT: mv s0, a2
584 ; RV64I-NEXT: mv s1, a1
585 ; RV64I-NEXT: li a1, 0
586 ; RV64I-NEXT: call __adddf3@plt
587 ; RV64I-NEXT: li a1, -1
588 ; RV64I-NEXT: slli a1, a1, 63
589 ; RV64I-NEXT: xor a0, a0, a1
590 ; RV64I-NEXT: mv a1, s1
591 ; RV64I-NEXT: mv a2, s0
592 ; RV64I-NEXT: call fma@plt
593 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
594 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
595 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
596 ; RV64I-NEXT: addi sp, sp, 32
598 %a_ = fadd double 0.0, %a
599 %nega = fneg double %a_
600 %1 = call double @llvm.experimental.constrained.fma.f64(double %nega, double %b, double %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
604 define double @fnmsub_d_2(double %a, double %b, double %c) nounwind strictfp {
605 ; RV32IFD-LABEL: fnmsub_d_2:
607 ; RV32IFD-NEXT: fcvt.d.w ft0, zero
608 ; RV32IFD-NEXT: fadd.d ft0, fa1, ft0
609 ; RV32IFD-NEXT: fnmsub.d fa0, ft0, fa0, fa2
612 ; RV64IFD-LABEL: fnmsub_d_2:
614 ; RV64IFD-NEXT: fmv.d.x ft0, zero
615 ; RV64IFD-NEXT: fadd.d ft0, fa1, ft0
616 ; RV64IFD-NEXT: fnmsub.d fa0, ft0, fa0, fa2
619 ; RV32I-LABEL: fnmsub_d_2:
621 ; RV32I-NEXT: addi sp, sp, -32
622 ; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
623 ; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
624 ; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
625 ; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
626 ; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
627 ; RV32I-NEXT: mv s0, a5
628 ; RV32I-NEXT: mv s1, a4
629 ; RV32I-NEXT: mv s2, a1
630 ; RV32I-NEXT: mv s3, a0
631 ; RV32I-NEXT: mv a0, a2
632 ; RV32I-NEXT: mv a1, a3
633 ; RV32I-NEXT: li a2, 0
634 ; RV32I-NEXT: li a3, 0
635 ; RV32I-NEXT: call __adddf3@plt
636 ; RV32I-NEXT: mv a2, a0
637 ; RV32I-NEXT: lui a0, 524288
638 ; RV32I-NEXT: xor a3, a1, a0
639 ; RV32I-NEXT: mv a0, s3
640 ; RV32I-NEXT: mv a1, s2
641 ; RV32I-NEXT: mv a4, s1
642 ; RV32I-NEXT: mv a5, s0
643 ; RV32I-NEXT: call fma@plt
644 ; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
645 ; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
646 ; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
647 ; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
648 ; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
649 ; RV32I-NEXT: addi sp, sp, 32
652 ; RV64I-LABEL: fnmsub_d_2:
654 ; RV64I-NEXT: addi sp, sp, -32
655 ; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
656 ; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
657 ; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
658 ; RV64I-NEXT: mv s0, a2
659 ; RV64I-NEXT: mv s1, a0
660 ; RV64I-NEXT: mv a0, a1
661 ; RV64I-NEXT: li a1, 0
662 ; RV64I-NEXT: call __adddf3@plt
663 ; RV64I-NEXT: li a1, -1
664 ; RV64I-NEXT: slli a1, a1, 63
665 ; RV64I-NEXT: xor a1, a0, a1
666 ; RV64I-NEXT: mv a0, s1
667 ; RV64I-NEXT: mv a2, s0
668 ; RV64I-NEXT: call fma@plt
669 ; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
670 ; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
671 ; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
672 ; RV64I-NEXT: addi sp, sp, 32
674 %b_ = fadd double 0.0, %b
675 %negb = fneg double %b_
676 %1 = call double @llvm.experimental.constrained.fma.f64(double %a, double %negb, double %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp