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