[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / CodeGen / RISCV / double-arith-strict.ll
blobeb9721a104b41bb3a12d9f62063c288015400343
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:
15 ; CHECKIFD:       # %bb.0:
16 ; CHECKIFD-NEXT:    fadd.d fa0, fa0, fa1
17 ; CHECKIFD-NEXT:    ret
19 ; RV32I-LABEL: fadd_d:
20 ; RV32I:       # %bb.0:
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
26 ; RV32I-NEXT:    ret
28 ; RV64I-LABEL: fadd_d:
29 ; RV64I:       # %bb.0:
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
35 ; RV64I-NEXT:    ret
36   %1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
37   ret double %1
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:
43 ; CHECKIFD:       # %bb.0:
44 ; CHECKIFD-NEXT:    fsub.d fa0, fa0, fa1
45 ; CHECKIFD-NEXT:    ret
47 ; RV32I-LABEL: fsub_d:
48 ; RV32I:       # %bb.0:
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
54 ; RV32I-NEXT:    ret
56 ; RV64I-LABEL: fsub_d:
57 ; RV64I:       # %bb.0:
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
63 ; RV64I-NEXT:    ret
64   %1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
65   ret double %1
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:
71 ; CHECKIFD:       # %bb.0:
72 ; CHECKIFD-NEXT:    fmul.d fa0, fa0, fa1
73 ; CHECKIFD-NEXT:    ret
75 ; RV32I-LABEL: fmul_d:
76 ; RV32I:       # %bb.0:
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
82 ; RV32I-NEXT:    ret
84 ; RV64I-LABEL: fmul_d:
85 ; RV64I:       # %bb.0:
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
91 ; RV64I-NEXT:    ret
92   %1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
93   ret double %1
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:
99 ; CHECKIFD:       # %bb.0:
100 ; CHECKIFD-NEXT:    fdiv.d fa0, fa0, fa1
101 ; CHECKIFD-NEXT:    ret
103 ; RV32I-LABEL: fdiv_d:
104 ; RV32I:       # %bb.0:
105 ; RV32I-NEXT:    addi sp, sp, -16
106 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
107 ; RV32I-NEXT:    call __divdf3@plt
108 ; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
109 ; RV32I-NEXT:    addi sp, sp, 16
110 ; RV32I-NEXT:    ret
112 ; RV64I-LABEL: fdiv_d:
113 ; RV64I:       # %bb.0:
114 ; RV64I-NEXT:    addi sp, sp, -16
115 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
116 ; RV64I-NEXT:    call __divdf3@plt
117 ; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
118 ; RV64I-NEXT:    addi sp, sp, 16
119 ; RV64I-NEXT:    ret
120   %1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
121   ret double %1
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:
127 ; CHECKIFD:       # %bb.0:
128 ; CHECKIFD-NEXT:    fsqrt.d fa0, fa0
129 ; CHECKIFD-NEXT:    ret
131 ; RV32I-LABEL: fsqrt_d:
132 ; RV32I:       # %bb.0:
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
138 ; RV32I-NEXT:    ret
140 ; RV64I-LABEL: fsqrt_d:
141 ; RV64I:       # %bb.0:
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
147 ; RV64I-NEXT:    ret
148   %1 = call double @llvm.experimental.constrained.sqrt.f64(double %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
149   ret double %1
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:
155 ; RV32IFD:       # %bb.0:
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
161 ; RV32IFD-NEXT:    ret
163 ; RV64IFD-LABEL: fmin_d:
164 ; RV64IFD:       # %bb.0:
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
170 ; RV64IFD-NEXT:    ret
172 ; RV32I-LABEL: fmin_d:
173 ; RV32I:       # %bb.0:
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
179 ; RV32I-NEXT:    ret
181 ; RV64I-LABEL: fmin_d:
182 ; RV64I:       # %bb.0:
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
188 ; RV64I-NEXT:    ret
189   %1 = call double @llvm.experimental.constrained.minnum.f64(double %a, double %b, metadata !"fpexcept.strict") strictfp
190   ret double %1
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:
196 ; RV32IFD:       # %bb.0:
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
202 ; RV32IFD-NEXT:    ret
204 ; RV64IFD-LABEL: fmax_d:
205 ; RV64IFD:       # %bb.0:
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
211 ; RV64IFD-NEXT:    ret
213 ; RV32I-LABEL: fmax_d:
214 ; RV32I:       # %bb.0:
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
220 ; RV32I-NEXT:    ret
222 ; RV64I-LABEL: fmax_d:
223 ; RV64I:       # %bb.0:
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
229 ; RV64I-NEXT:    ret
230   %1 = call double @llvm.experimental.constrained.maxnum.f64(double %a, double %b, metadata !"fpexcept.strict") strictfp
231   ret double %1
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:
237 ; CHECKIFD:       # %bb.0:
238 ; CHECKIFD-NEXT:    fmadd.d fa0, fa0, fa1, fa2
239 ; CHECKIFD-NEXT:    ret
241 ; RV32I-LABEL: fmadd_d:
242 ; RV32I:       # %bb.0:
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
248 ; RV32I-NEXT:    ret
250 ; RV64I-LABEL: fmadd_d:
251 ; RV64I:       # %bb.0:
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
257 ; RV64I-NEXT:    ret
258   %1 = call double @llvm.experimental.constrained.fma.f64(double %a, double %b, double %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
259   ret double %1
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:
265 ; RV32IFD:       # %bb.0:
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
269 ; RV32IFD-NEXT:    ret
271 ; RV64IFD-LABEL: fmsub_d:
272 ; RV64IFD:       # %bb.0:
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
276 ; RV64IFD-NEXT:    ret
278 ; RV32I-LABEL: fmsub_d:
279 ; RV32I:       # %bb.0:
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
309 ; RV32I-NEXT:    ret
311 ; RV64I-LABEL: fmsub_d:
312 ; RV64I:       # %bb.0:
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
332 ; RV64I-NEXT:    ret
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
336   ret double %1
339 define double @fnmadd_d(double %a, double %b, double %c) nounwind strictfp {
340 ; RV32IFD-LABEL: fnmadd_d:
341 ; RV32IFD:       # %bb.0:
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
346 ; RV32IFD-NEXT:    ret
348 ; RV64IFD-LABEL: fnmadd_d:
349 ; RV64IFD:       # %bb.0:
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
354 ; RV64IFD-NEXT:    ret
356 ; RV32I-LABEL: fnmadd_d:
357 ; RV32I:       # %bb.0:
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
397 ; RV32I-NEXT:    ret
399 ; RV64I-LABEL: fnmadd_d:
400 ; RV64I:       # %bb.0:
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
426 ; RV64I-NEXT:    ret
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
432   ret double %1
435 define double @fnmadd_d_2(double %a, double %b, double %c) nounwind strictfp {
436 ; RV32IFD-LABEL: fnmadd_d_2:
437 ; RV32IFD:       # %bb.0:
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
442 ; RV32IFD-NEXT:    ret
444 ; RV64IFD-LABEL: fnmadd_d_2:
445 ; RV64IFD:       # %bb.0:
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
450 ; RV64IFD-NEXT:    ret
452 ; RV32I-LABEL: fnmadd_d_2:
453 ; RV32I:       # %bb.0:
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
494 ; RV32I-NEXT:    ret
496 ; RV64I-LABEL: fnmadd_d_2:
497 ; RV64I:       # %bb.0:
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
523 ; RV64I-NEXT:    ret
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
529   ret double %1
532 define double @fnmsub_d(double %a, double %b, double %c) nounwind strictfp {
533 ; RV32IFD-LABEL: fnmsub_d:
534 ; RV32IFD:       # %bb.0:
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
538 ; RV32IFD-NEXT:    ret
540 ; RV64IFD-LABEL: fnmsub_d:
541 ; RV64IFD:       # %bb.0:
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
545 ; RV64IFD-NEXT:    ret
547 ; RV32I-LABEL: fnmsub_d:
548 ; RV32I:       # %bb.0:
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
575 ; RV32I-NEXT:    ret
577 ; RV64I-LABEL: fnmsub_d:
578 ; RV64I:       # %bb.0:
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
597 ; RV64I-NEXT:    ret
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
601   ret double %1
604 define double @fnmsub_d_2(double %a, double %b, double %c) nounwind strictfp {
605 ; RV32IFD-LABEL: fnmsub_d_2:
606 ; RV32IFD:       # %bb.0:
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
610 ; RV32IFD-NEXT:    ret
612 ; RV64IFD-LABEL: fnmsub_d_2:
613 ; RV64IFD:       # %bb.0:
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
617 ; RV64IFD-NEXT:    ret
619 ; RV32I-LABEL: fnmsub_d_2:
620 ; RV32I:       # %bb.0:
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
650 ; RV32I-NEXT:    ret
652 ; RV64I-LABEL: fnmsub_d_2:
653 ; RV64I:       # %bb.0:
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
673 ; RV64I-NEXT:    ret
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
677   ret double %1