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