1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
3; RUN:   -target-abi=ilp32f | FileCheck -check-prefix=CHECKIF %s
4; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5; RUN:   -target-abi=lp64f | FileCheck -check-prefix=CHECKIF %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 float-fcmp.ll and float-convert.ll
13; respectively. Some other float-*.ll files in this folder exercise LLVM IR
14; instructions that don't directly match a RISC-V instruction.
15
16define float @fadd_s(float %a, float %b) nounwind {
17; CHECKIF-LABEL: fadd_s:
18; CHECKIF:       # %bb.0:
19; CHECKIF-NEXT:    fadd.s fa0, fa0, fa1
20; CHECKIF-NEXT:    ret
21;
22; RV32I-LABEL: fadd_s:
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 __addsf3@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_s:
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 __addsf3@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 float %a, %b
40  ret float %1
41}
42
43define float @fsub_s(float %a, float %b) nounwind {
44; CHECKIF-LABEL: fsub_s:
45; CHECKIF:       # %bb.0:
46; CHECKIF-NEXT:    fsub.s fa0, fa0, fa1
47; CHECKIF-NEXT:    ret
48;
49; RV32I-LABEL: fsub_s:
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 __subsf3@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_s:
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 __subsf3@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 float %a, %b
67  ret float %1
68}
69
70define float @fmul_s(float %a, float %b) nounwind {
71; CHECKIF-LABEL: fmul_s:
72; CHECKIF:       # %bb.0:
73; CHECKIF-NEXT:    fmul.s fa0, fa0, fa1
74; CHECKIF-NEXT:    ret
75;
76; RV32I-LABEL: fmul_s:
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 __mulsf3@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_s:
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 __mulsf3@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 float %a, %b
94  ret float %1
95}
96
97define float @fdiv_s(float %a, float %b) nounwind {
98; CHECKIF-LABEL: fdiv_s:
99; CHECKIF:       # %bb.0:
100; CHECKIF-NEXT:    fdiv.s fa0, fa0, fa1
101; CHECKIF-NEXT:    ret
102;
103; RV32I-LABEL: fdiv_s:
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 __divsf3@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_s:
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 __divsf3@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 float %a, %b
121  ret float %1
122}
123
124declare float @llvm.sqrt.f32(float)
125
126define float @fsqrt_s(float %a) nounwind {
127; CHECKIF-LABEL: fsqrt_s:
128; CHECKIF:       # %bb.0:
129; CHECKIF-NEXT:    fsqrt.s fa0, fa0
130; CHECKIF-NEXT:    ret
131;
132; RV32I-LABEL: fsqrt_s:
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 sqrtf@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_s:
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 sqrtf@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 float @llvm.sqrt.f32(float %a)
150  ret float %1
151}
152
153declare float @llvm.copysign.f32(float, float)
154
155define float @fsgnj_s(float %a, float %b) nounwind {
156; CHECKIF-LABEL: fsgnj_s:
157; CHECKIF:       # %bb.0:
158; CHECKIF-NEXT:    fsgnj.s fa0, fa0, fa1
159; CHECKIF-NEXT:    ret
160;
161; RV32I-LABEL: fsgnj_s:
162; RV32I:       # %bb.0:
163; RV32I-NEXT:    lui a2, 524288
164; RV32I-NEXT:    and a1, a1, a2
165; RV32I-NEXT:    slli a0, a0, 1
166; RV32I-NEXT:    srli a0, a0, 1
167; RV32I-NEXT:    or a0, a0, a1
168; RV32I-NEXT:    ret
169;
170; RV64I-LABEL: fsgnj_s:
171; RV64I:       # %bb.0:
172; RV64I-NEXT:    lui a2, 524288
173; RV64I-NEXT:    and a1, a1, a2
174; RV64I-NEXT:    slli a0, a0, 33
175; RV64I-NEXT:    srli a0, a0, 33
176; RV64I-NEXT:    or a0, a0, a1
177; RV64I-NEXT:    ret
178  %1 = call float @llvm.copysign.f32(float %a, float %b)
179  ret float %1
180}
181
182define i32 @fneg_s(float %a, float %b) nounwind {
183; CHECKIF-LABEL: fneg_s:
184; CHECKIF:       # %bb.0:
185; CHECKIF-NEXT:    fadd.s ft0, fa0, fa0
186; CHECKIF-NEXT:    fneg.s ft1, ft0
187; CHECKIF-NEXT:    feq.s a0, ft0, ft1
188; CHECKIF-NEXT:    ret
189;
190; RV32I-LABEL: fneg_s:
191; RV32I:       # %bb.0:
192; RV32I-NEXT:    addi sp, sp, -16
193; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
194; RV32I-NEXT:    mv a1, a0
195; RV32I-NEXT:    call __addsf3@plt
196; RV32I-NEXT:    lui a1, 524288
197; RV32I-NEXT:    xor a1, a0, a1
198; RV32I-NEXT:    call __eqsf2@plt
199; RV32I-NEXT:    seqz a0, a0
200; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
201; RV32I-NEXT:    addi sp, sp, 16
202; RV32I-NEXT:    ret
203;
204; RV64I-LABEL: fneg_s:
205; RV64I:       # %bb.0:
206; RV64I-NEXT:    addi sp, sp, -16
207; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
208; RV64I-NEXT:    mv a1, a0
209; RV64I-NEXT:    call __addsf3@plt
210; RV64I-NEXT:    lui a1, 524288
211; RV64I-NEXT:    xor a1, a0, a1
212; RV64I-NEXT:    call __eqsf2@plt
213; RV64I-NEXT:    seqz a0, a0
214; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
215; RV64I-NEXT:    addi sp, sp, 16
216; RV64I-NEXT:    ret
217  %1 = fadd float %a, %a
218  %2 = fneg float %1
219  %3 = fcmp oeq float %1, %2
220  %4 = zext i1 %3 to i32
221  ret i32 %4
222}
223
224define float @fsgnjn_s(float %a, float %b) nounwind {
225; CHECKIF-LABEL: fsgnjn_s:
226; CHECKIF:       # %bb.0:
227; CHECKIF-NEXT:    fadd.s ft0, fa0, fa1
228; CHECKIF-NEXT:    fsgnjn.s fa0, fa0, ft0
229; CHECKIF-NEXT:    ret
230;
231; RV32I-LABEL: fsgnjn_s:
232; RV32I:       # %bb.0:
233; RV32I-NEXT:    addi sp, sp, -16
234; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
235; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
236; RV32I-NEXT:    mv s0, a0
237; RV32I-NEXT:    call __addsf3@plt
238; RV32I-NEXT:    not a0, a0
239; RV32I-NEXT:    lui a1, 524288
240; RV32I-NEXT:    and a0, a0, a1
241; RV32I-NEXT:    slli a1, s0, 1
242; RV32I-NEXT:    srli a1, a1, 1
243; RV32I-NEXT:    or a0, a1, a0
244; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
245; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
246; RV32I-NEXT:    addi sp, sp, 16
247; RV32I-NEXT:    ret
248;
249; RV64I-LABEL: fsgnjn_s:
250; RV64I:       # %bb.0:
251; RV64I-NEXT:    addi sp, sp, -16
252; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
253; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
254; RV64I-NEXT:    mv s0, a0
255; RV64I-NEXT:    call __addsf3@plt
256; RV64I-NEXT:    not a0, a0
257; RV64I-NEXT:    lui a1, 524288
258; RV64I-NEXT:    and a0, a0, a1
259; RV64I-NEXT:    slli a1, s0, 33
260; RV64I-NEXT:    srli a1, a1, 33
261; RV64I-NEXT:    or a0, a1, a0
262; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
263; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
264; RV64I-NEXT:    addi sp, sp, 16
265; RV64I-NEXT:    ret
266  %1 = fadd float %a, %b
267  %2 = fneg float %1
268  %3 = call float @llvm.copysign.f32(float %a, float %2)
269  ret float %3
270}
271
272declare float @llvm.fabs.f32(float)
273
274define float @fabs_s(float %a, float %b) nounwind {
275; CHECKIF-LABEL: fabs_s:
276; CHECKIF:       # %bb.0:
277; CHECKIF-NEXT:    fadd.s ft0, fa0, fa1
278; CHECKIF-NEXT:    fabs.s ft1, ft0
279; CHECKIF-NEXT:    fadd.s fa0, ft1, ft0
280; CHECKIF-NEXT:    ret
281;
282; RV32I-LABEL: fabs_s:
283; RV32I:       # %bb.0:
284; RV32I-NEXT:    addi sp, sp, -16
285; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
286; RV32I-NEXT:    call __addsf3@plt
287; RV32I-NEXT:    mv a1, a0
288; RV32I-NEXT:    slli a0, a0, 1
289; RV32I-NEXT:    srli a0, a0, 1
290; RV32I-NEXT:    call __addsf3@plt
291; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
292; RV32I-NEXT:    addi sp, sp, 16
293; RV32I-NEXT:    ret
294;
295; RV64I-LABEL: fabs_s:
296; RV64I:       # %bb.0:
297; RV64I-NEXT:    addi sp, sp, -16
298; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
299; RV64I-NEXT:    call __addsf3@plt
300; RV64I-NEXT:    mv a1, a0
301; RV64I-NEXT:    slli a0, a0, 33
302; RV64I-NEXT:    srli a0, a0, 33
303; RV64I-NEXT:    call __addsf3@plt
304; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
305; RV64I-NEXT:    addi sp, sp, 16
306; RV64I-NEXT:    ret
307  %1 = fadd float %a, %b
308  %2 = call float @llvm.fabs.f32(float %1)
309  %3 = fadd float %2, %1
310  ret float %3
311}
312
313declare float @llvm.minnum.f32(float, float)
314
315define float @fmin_s(float %a, float %b) nounwind {
316; CHECKIF-LABEL: fmin_s:
317; CHECKIF:       # %bb.0:
318; CHECKIF-NEXT:    fmin.s fa0, fa0, fa1
319; CHECKIF-NEXT:    ret
320;
321; RV32I-LABEL: fmin_s:
322; RV32I:       # %bb.0:
323; RV32I-NEXT:    addi sp, sp, -16
324; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
325; RV32I-NEXT:    call fminf@plt
326; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
327; RV32I-NEXT:    addi sp, sp, 16
328; RV32I-NEXT:    ret
329;
330; RV64I-LABEL: fmin_s:
331; RV64I:       # %bb.0:
332; RV64I-NEXT:    addi sp, sp, -16
333; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
334; RV64I-NEXT:    call fminf@plt
335; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
336; RV64I-NEXT:    addi sp, sp, 16
337; RV64I-NEXT:    ret
338  %1 = call float @llvm.minnum.f32(float %a, float %b)
339  ret float %1
340}
341
342declare float @llvm.maxnum.f32(float, float)
343
344define float @fmax_s(float %a, float %b) nounwind {
345; CHECKIF-LABEL: fmax_s:
346; CHECKIF:       # %bb.0:
347; CHECKIF-NEXT:    fmax.s fa0, fa0, fa1
348; CHECKIF-NEXT:    ret
349;
350; RV32I-LABEL: fmax_s:
351; RV32I:       # %bb.0:
352; RV32I-NEXT:    addi sp, sp, -16
353; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
354; RV32I-NEXT:    call fmaxf@plt
355; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
356; RV32I-NEXT:    addi sp, sp, 16
357; RV32I-NEXT:    ret
358;
359; RV64I-LABEL: fmax_s:
360; RV64I:       # %bb.0:
361; RV64I-NEXT:    addi sp, sp, -16
362; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
363; RV64I-NEXT:    call fmaxf@plt
364; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
365; RV64I-NEXT:    addi sp, sp, 16
366; RV64I-NEXT:    ret
367  %1 = call float @llvm.maxnum.f32(float %a, float %b)
368  ret float %1
369}
370
371declare float @llvm.fma.f32(float, float, float)
372
373define float @fmadd_s(float %a, float %b, float %c) nounwind {
374; CHECKIF-LABEL: fmadd_s:
375; CHECKIF:       # %bb.0:
376; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
377; CHECKIF-NEXT:    ret
378;
379; RV32I-LABEL: fmadd_s:
380; RV32I:       # %bb.0:
381; RV32I-NEXT:    addi sp, sp, -16
382; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
383; RV32I-NEXT:    call fmaf@plt
384; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
385; RV32I-NEXT:    addi sp, sp, 16
386; RV32I-NEXT:    ret
387;
388; RV64I-LABEL: fmadd_s:
389; RV64I:       # %bb.0:
390; RV64I-NEXT:    addi sp, sp, -16
391; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
392; RV64I-NEXT:    call fmaf@plt
393; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
394; RV64I-NEXT:    addi sp, sp, 16
395; RV64I-NEXT:    ret
396  %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
397  ret float %1
398}
399
400define float @fmsub_s(float %a, float %b, float %c) nounwind {
401; CHECKIF-LABEL: fmsub_s:
402; CHECKIF:       # %bb.0:
403; CHECKIF-NEXT:    fmv.w.x ft0, zero
404; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
405; CHECKIF-NEXT:    fmsub.s fa0, fa0, fa1, ft0
406; CHECKIF-NEXT:    ret
407;
408; RV32I-LABEL: fmsub_s:
409; RV32I:       # %bb.0:
410; RV32I-NEXT:    addi sp, sp, -16
411; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
412; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
413; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
414; RV32I-NEXT:    mv s0, a1
415; RV32I-NEXT:    mv s1, a0
416; RV32I-NEXT:    mv a0, a2
417; RV32I-NEXT:    li a1, 0
418; RV32I-NEXT:    call __addsf3@plt
419; RV32I-NEXT:    lui a1, 524288
420; RV32I-NEXT:    xor a2, a0, a1
421; RV32I-NEXT:    mv a0, s1
422; RV32I-NEXT:    mv a1, s0
423; RV32I-NEXT:    call fmaf@plt
424; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
425; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
426; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
427; RV32I-NEXT:    addi sp, sp, 16
428; RV32I-NEXT:    ret
429;
430; RV64I-LABEL: fmsub_s:
431; RV64I:       # %bb.0:
432; RV64I-NEXT:    addi sp, sp, -32
433; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
434; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
435; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
436; RV64I-NEXT:    mv s0, a1
437; RV64I-NEXT:    mv s1, a0
438; RV64I-NEXT:    mv a0, a2
439; RV64I-NEXT:    li a1, 0
440; RV64I-NEXT:    call __addsf3@plt
441; RV64I-NEXT:    lui a1, 524288
442; RV64I-NEXT:    xor a2, a0, a1
443; RV64I-NEXT:    mv a0, s1
444; RV64I-NEXT:    mv a1, s0
445; RV64I-NEXT:    call fmaf@plt
446; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
447; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
448; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
449; RV64I-NEXT:    addi sp, sp, 32
450; RV64I-NEXT:    ret
451  %c_ = fadd float 0.0, %c ; avoid negation using xor
452  %negc = fsub float -0.0, %c_
453  %1 = call float @llvm.fma.f32(float %a, float %b, float %negc)
454  ret float %1
455}
456
457define float @fnmadd_s(float %a, float %b, float %c) nounwind {
458; CHECKIF-LABEL: fnmadd_s:
459; CHECKIF:       # %bb.0:
460; CHECKIF-NEXT:    fmv.w.x ft0, zero
461; CHECKIF-NEXT:    fadd.s ft1, fa0, ft0
462; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
463; CHECKIF-NEXT:    fnmadd.s fa0, ft1, fa1, ft0
464; CHECKIF-NEXT:    ret
465;
466; RV32I-LABEL: fnmadd_s:
467; RV32I:       # %bb.0:
468; RV32I-NEXT:    addi sp, sp, -16
469; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
470; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
471; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
472; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
473; RV32I-NEXT:    mv s0, a2
474; RV32I-NEXT:    mv s1, a1
475; RV32I-NEXT:    li a1, 0
476; RV32I-NEXT:    call __addsf3@plt
477; RV32I-NEXT:    mv s2, a0
478; RV32I-NEXT:    mv a0, s0
479; RV32I-NEXT:    li a1, 0
480; RV32I-NEXT:    call __addsf3@plt
481; RV32I-NEXT:    lui a2, 524288
482; RV32I-NEXT:    xor a1, s2, a2
483; RV32I-NEXT:    xor a2, a0, a2
484; RV32I-NEXT:    mv a0, a1
485; RV32I-NEXT:    mv a1, s1
486; RV32I-NEXT:    call fmaf@plt
487; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
488; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
489; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
490; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
491; RV32I-NEXT:    addi sp, sp, 16
492; RV32I-NEXT:    ret
493;
494; RV64I-LABEL: fnmadd_s:
495; RV64I:       # %bb.0:
496; RV64I-NEXT:    addi sp, sp, -32
497; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
498; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
499; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
500; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
501; RV64I-NEXT:    mv s0, a2
502; RV64I-NEXT:    mv s1, a1
503; RV64I-NEXT:    li a1, 0
504; RV64I-NEXT:    call __addsf3@plt
505; RV64I-NEXT:    mv s2, a0
506; RV64I-NEXT:    mv a0, s0
507; RV64I-NEXT:    li a1, 0
508; RV64I-NEXT:    call __addsf3@plt
509; RV64I-NEXT:    lui a2, 524288
510; RV64I-NEXT:    xor a1, s2, a2
511; RV64I-NEXT:    xor a2, a0, a2
512; RV64I-NEXT:    mv a0, a1
513; RV64I-NEXT:    mv a1, s1
514; RV64I-NEXT:    call fmaf@plt
515; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
516; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
517; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
518; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
519; RV64I-NEXT:    addi sp, sp, 32
520; RV64I-NEXT:    ret
521  %a_ = fadd float 0.0, %a
522  %c_ = fadd float 0.0, %c
523  %nega = fsub float -0.0, %a_
524  %negc = fsub float -0.0, %c_
525  %1 = call float @llvm.fma.f32(float %nega, float %b, float %negc)
526  ret float %1
527}
528
529define float @fnmadd_s_2(float %a, float %b, float %c) nounwind {
530; CHECKIF-LABEL: fnmadd_s_2:
531; CHECKIF:       # %bb.0:
532; CHECKIF-NEXT:    fmv.w.x ft0, zero
533; CHECKIF-NEXT:    fadd.s ft1, fa1, ft0
534; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
535; CHECKIF-NEXT:    fnmadd.s fa0, ft1, fa0, ft0
536; CHECKIF-NEXT:    ret
537;
538; RV32I-LABEL: fnmadd_s_2:
539; RV32I:       # %bb.0:
540; RV32I-NEXT:    addi sp, sp, -16
541; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
542; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
543; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
544; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
545; RV32I-NEXT:    mv s0, a2
546; RV32I-NEXT:    mv s1, a0
547; RV32I-NEXT:    mv a0, a1
548; RV32I-NEXT:    li a1, 0
549; RV32I-NEXT:    call __addsf3@plt
550; RV32I-NEXT:    mv s2, a0
551; RV32I-NEXT:    mv a0, s0
552; RV32I-NEXT:    li a1, 0
553; RV32I-NEXT:    call __addsf3@plt
554; RV32I-NEXT:    lui a2, 524288
555; RV32I-NEXT:    xor a1, s2, a2
556; RV32I-NEXT:    xor a2, a0, a2
557; RV32I-NEXT:    mv a0, s1
558; RV32I-NEXT:    call fmaf@plt
559; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
560; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
561; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
562; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
563; RV32I-NEXT:    addi sp, sp, 16
564; RV32I-NEXT:    ret
565;
566; RV64I-LABEL: fnmadd_s_2:
567; RV64I:       # %bb.0:
568; RV64I-NEXT:    addi sp, sp, -32
569; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
570; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
571; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
572; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
573; RV64I-NEXT:    mv s0, a2
574; RV64I-NEXT:    mv s1, a0
575; RV64I-NEXT:    mv a0, a1
576; RV64I-NEXT:    li a1, 0
577; RV64I-NEXT:    call __addsf3@plt
578; RV64I-NEXT:    mv s2, a0
579; RV64I-NEXT:    mv a0, s0
580; RV64I-NEXT:    li a1, 0
581; RV64I-NEXT:    call __addsf3@plt
582; RV64I-NEXT:    lui a2, 524288
583; RV64I-NEXT:    xor a1, s2, a2
584; RV64I-NEXT:    xor a2, a0, a2
585; RV64I-NEXT:    mv a0, s1
586; RV64I-NEXT:    call fmaf@plt
587; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
588; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
589; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
590; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
591; RV64I-NEXT:    addi sp, sp, 32
592; RV64I-NEXT:    ret
593  %b_ = fadd float 0.0, %b
594  %c_ = fadd float 0.0, %c
595  %negb = fsub float -0.0, %b_
596  %negc = fsub float -0.0, %c_
597  %1 = call float @llvm.fma.f32(float %a, float %negb, float %negc)
598  ret float %1
599}
600
601define float @fnmadd_s_3(float %a, float %b, float %c) nounwind {
602; RV32IF-LABEL: fnmadd_s_3:
603; RV32IF:       # %bb.0:
604; RV32IF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
605; RV32IF-NEXT:    fneg.s fa0, ft0
606; RV32IF-NEXT:    ret
607;
608; RV64IF-LABEL: fnmadd_s_3:
609; RV64IF:       # %bb.0:
610; RV64IF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
611; RV64IF-NEXT:    fneg.s fa0, ft0
612; RV64IF-NEXT:    ret
613;
614; CHECKIF-LABEL: fnmadd_s_3:
615; CHECKIF:       # %bb.0:
616; CHECKIF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
617; CHECKIF-NEXT:    fneg.s fa0, ft0
618; CHECKIF-NEXT:    ret
619;
620; RV32I-LABEL: fnmadd_s_3:
621; RV32I:       # %bb.0:
622; RV32I-NEXT:    addi sp, sp, -16
623; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
624; RV32I-NEXT:    call fmaf@plt
625; RV32I-NEXT:    lui a1, 524288
626; RV32I-NEXT:    xor a0, a0, a1
627; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
628; RV32I-NEXT:    addi sp, sp, 16
629; RV32I-NEXT:    ret
630;
631; RV64I-LABEL: fnmadd_s_3:
632; RV64I:       # %bb.0:
633; RV64I-NEXT:    addi sp, sp, -16
634; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
635; RV64I-NEXT:    call fmaf@plt
636; RV64I-NEXT:    lui a1, 524288
637; RV64I-NEXT:    xor a0, a0, a1
638; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
639; RV64I-NEXT:    addi sp, sp, 16
640; RV64I-NEXT:    ret
641  %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
642  %neg = fneg float %1
643  ret float %neg
644}
645
646define float @fnmadd_nsz(float %a, float %b, float %c) nounwind {
647; RV32IF-LABEL: fnmadd_nsz:
648; RV32IF:       # %bb.0:
649; RV32IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
650; RV32IF-NEXT:    ret
651;
652; RV64IF-LABEL: fnmadd_nsz:
653; RV64IF:       # %bb.0:
654; RV64IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
655; RV64IF-NEXT:    ret
656;
657; CHECKIF-LABEL: fnmadd_nsz:
658; CHECKIF:       # %bb.0:
659; CHECKIF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
660; CHECKIF-NEXT:    ret
661;
662; RV32I-LABEL: fnmadd_nsz:
663; RV32I:       # %bb.0:
664; RV32I-NEXT:    addi sp, sp, -16
665; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
666; RV32I-NEXT:    call fmaf@plt
667; RV32I-NEXT:    lui a1, 524288
668; RV32I-NEXT:    xor a0, a0, a1
669; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
670; RV32I-NEXT:    addi sp, sp, 16
671; RV32I-NEXT:    ret
672;
673; RV64I-LABEL: fnmadd_nsz:
674; RV64I:       # %bb.0:
675; RV64I-NEXT:    addi sp, sp, -16
676; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
677; RV64I-NEXT:    call fmaf@plt
678; RV64I-NEXT:    lui a1, 524288
679; RV64I-NEXT:    xor a0, a0, a1
680; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
681; RV64I-NEXT:    addi sp, sp, 16
682; RV64I-NEXT:    ret
683  %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c)
684  %neg = fneg nsz float %1
685  ret float %neg
686}
687
688define float @fnmsub_s(float %a, float %b, float %c) nounwind {
689; CHECKIF-LABEL: fnmsub_s:
690; CHECKIF:       # %bb.0:
691; CHECKIF-NEXT:    fmv.w.x ft0, zero
692; CHECKIF-NEXT:    fadd.s ft0, fa0, ft0
693; CHECKIF-NEXT:    fnmsub.s fa0, ft0, fa1, fa2
694; CHECKIF-NEXT:    ret
695;
696; RV32I-LABEL: fnmsub_s:
697; RV32I:       # %bb.0:
698; RV32I-NEXT:    addi sp, sp, -16
699; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
700; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
701; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
702; RV32I-NEXT:    mv s0, a2
703; RV32I-NEXT:    mv s1, a1
704; RV32I-NEXT:    li a1, 0
705; RV32I-NEXT:    call __addsf3@plt
706; RV32I-NEXT:    lui a1, 524288
707; RV32I-NEXT:    xor a0, a0, a1
708; RV32I-NEXT:    mv a1, s1
709; RV32I-NEXT:    mv a2, s0
710; RV32I-NEXT:    call fmaf@plt
711; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
712; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
713; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
714; RV32I-NEXT:    addi sp, sp, 16
715; RV32I-NEXT:    ret
716;
717; RV64I-LABEL: fnmsub_s:
718; RV64I:       # %bb.0:
719; RV64I-NEXT:    addi sp, sp, -32
720; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
721; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
722; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
723; RV64I-NEXT:    mv s0, a2
724; RV64I-NEXT:    mv s1, a1
725; RV64I-NEXT:    li a1, 0
726; RV64I-NEXT:    call __addsf3@plt
727; RV64I-NEXT:    lui a1, 524288
728; RV64I-NEXT:    xor a0, a0, a1
729; RV64I-NEXT:    mv a1, s1
730; RV64I-NEXT:    mv a2, s0
731; RV64I-NEXT:    call fmaf@plt
732; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
733; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
734; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
735; RV64I-NEXT:    addi sp, sp, 32
736; RV64I-NEXT:    ret
737  %a_ = fadd float 0.0, %a
738  %nega = fsub float -0.0, %a_
739  %1 = call float @llvm.fma.f32(float %nega, float %b, float %c)
740  ret float %1
741}
742
743define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
744; CHECKIF-LABEL: fnmsub_s_2:
745; CHECKIF:       # %bb.0:
746; CHECKIF-NEXT:    fmv.w.x ft0, zero
747; CHECKIF-NEXT:    fadd.s ft0, fa1, ft0
748; CHECKIF-NEXT:    fnmsub.s fa0, ft0, fa0, fa2
749; CHECKIF-NEXT:    ret
750;
751; RV32I-LABEL: fnmsub_s_2:
752; RV32I:       # %bb.0:
753; RV32I-NEXT:    addi sp, sp, -16
754; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
755; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
756; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
757; RV32I-NEXT:    mv s0, a2
758; RV32I-NEXT:    mv s1, a0
759; RV32I-NEXT:    mv a0, a1
760; RV32I-NEXT:    li a1, 0
761; RV32I-NEXT:    call __addsf3@plt
762; RV32I-NEXT:    lui a1, 524288
763; RV32I-NEXT:    xor a1, a0, a1
764; RV32I-NEXT:    mv a0, s1
765; RV32I-NEXT:    mv a2, s0
766; RV32I-NEXT:    call fmaf@plt
767; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
768; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
769; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
770; RV32I-NEXT:    addi sp, sp, 16
771; RV32I-NEXT:    ret
772;
773; RV64I-LABEL: fnmsub_s_2:
774; RV64I:       # %bb.0:
775; RV64I-NEXT:    addi sp, sp, -32
776; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
777; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
778; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
779; RV64I-NEXT:    mv s0, a2
780; RV64I-NEXT:    mv s1, a0
781; RV64I-NEXT:    mv a0, a1
782; RV64I-NEXT:    li a1, 0
783; RV64I-NEXT:    call __addsf3@plt
784; RV64I-NEXT:    lui a1, 524288
785; RV64I-NEXT:    xor a1, a0, a1
786; RV64I-NEXT:    mv a0, s1
787; RV64I-NEXT:    mv a2, s0
788; RV64I-NEXT:    call fmaf@plt
789; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
790; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
791; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
792; RV64I-NEXT:    addi sp, sp, 32
793; RV64I-NEXT:    ret
794  %b_ = fadd float 0.0, %b
795  %negb = fsub float -0.0, %b_
796  %1 = call float @llvm.fma.f32(float %a, float %negb, float %c)
797  ret float %1
798}
799
800define float @fmadd_s_contract(float %a, float %b, float %c) nounwind {
801; CHECKIF-LABEL: fmadd_s_contract:
802; CHECKIF:       # %bb.0:
803; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
804; CHECKIF-NEXT:    ret
805;
806; RV32I-LABEL: fmadd_s_contract:
807; RV32I:       # %bb.0:
808; RV32I-NEXT:    addi sp, sp, -16
809; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
810; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
811; RV32I-NEXT:    mv s0, a2
812; RV32I-NEXT:    call __mulsf3@plt
813; RV32I-NEXT:    mv a1, s0
814; RV32I-NEXT:    call __addsf3@plt
815; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
816; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
817; RV32I-NEXT:    addi sp, sp, 16
818; RV32I-NEXT:    ret
819;
820; RV64I-LABEL: fmadd_s_contract:
821; RV64I:       # %bb.0:
822; RV64I-NEXT:    addi sp, sp, -16
823; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
824; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
825; RV64I-NEXT:    mv s0, a2
826; RV64I-NEXT:    call __mulsf3@plt
827; RV64I-NEXT:    mv a1, s0
828; RV64I-NEXT:    call __addsf3@plt
829; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
830; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
831; RV64I-NEXT:    addi sp, sp, 16
832; RV64I-NEXT:    ret
833  %1 = fmul contract float %a, %b
834  %2 = fadd contract float %1, %c
835  ret float %2
836}
837
838define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
839; CHECKIF-LABEL: fmsub_s_contract:
840; CHECKIF:       # %bb.0:
841; CHECKIF-NEXT:    fmv.w.x ft0, zero
842; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
843; CHECKIF-NEXT:    fmsub.s fa0, fa0, fa1, ft0
844; CHECKIF-NEXT:    ret
845;
846; RV32I-LABEL: fmsub_s_contract:
847; RV32I:       # %bb.0:
848; RV32I-NEXT:    addi sp, sp, -16
849; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
850; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
851; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
852; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
853; RV32I-NEXT:    mv s0, a1
854; RV32I-NEXT:    mv s1, a0
855; RV32I-NEXT:    mv a0, a2
856; RV32I-NEXT:    li a1, 0
857; RV32I-NEXT:    call __addsf3@plt
858; RV32I-NEXT:    mv s2, a0
859; RV32I-NEXT:    mv a0, s1
860; RV32I-NEXT:    mv a1, s0
861; RV32I-NEXT:    call __mulsf3@plt
862; RV32I-NEXT:    mv a1, s2
863; RV32I-NEXT:    call __subsf3@plt
864; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
865; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
866; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
867; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
868; RV32I-NEXT:    addi sp, sp, 16
869; RV32I-NEXT:    ret
870;
871; RV64I-LABEL: fmsub_s_contract:
872; RV64I:       # %bb.0:
873; RV64I-NEXT:    addi sp, sp, -32
874; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
875; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
876; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
877; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
878; RV64I-NEXT:    mv s0, a1
879; RV64I-NEXT:    mv s1, a0
880; RV64I-NEXT:    mv a0, a2
881; RV64I-NEXT:    li a1, 0
882; RV64I-NEXT:    call __addsf3@plt
883; RV64I-NEXT:    mv s2, a0
884; RV64I-NEXT:    mv a0, s1
885; RV64I-NEXT:    mv a1, s0
886; RV64I-NEXT:    call __mulsf3@plt
887; RV64I-NEXT:    mv a1, s2
888; RV64I-NEXT:    call __subsf3@plt
889; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
890; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
891; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
892; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
893; RV64I-NEXT:    addi sp, sp, 32
894; RV64I-NEXT:    ret
895  %c_ = fadd float 0.0, %c ; avoid negation using xor
896  %1 = fmul contract float %a, %b
897  %2 = fsub contract float %1, %c_
898  ret float %2
899}
900
901define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind {
902; CHECKIF-LABEL: fnmadd_s_contract:
903; CHECKIF:       # %bb.0:
904; CHECKIF-NEXT:    fmv.w.x ft0, zero
905; CHECKIF-NEXT:    fadd.s ft1, fa0, ft0
906; CHECKIF-NEXT:    fadd.s ft2, fa1, ft0
907; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
908; CHECKIF-NEXT:    fnmadd.s fa0, ft1, ft2, ft0
909; CHECKIF-NEXT:    ret
910;
911; RV32I-LABEL: fnmadd_s_contract:
912; RV32I:       # %bb.0:
913; RV32I-NEXT:    addi sp, sp, -16
914; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
915; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
916; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
917; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
918; RV32I-NEXT:    mv s0, a2
919; RV32I-NEXT:    mv s1, a1
920; RV32I-NEXT:    li a1, 0
921; RV32I-NEXT:    call __addsf3@plt
922; RV32I-NEXT:    mv s2, a0
923; RV32I-NEXT:    mv a0, s1
924; RV32I-NEXT:    li a1, 0
925; RV32I-NEXT:    call __addsf3@plt
926; RV32I-NEXT:    mv s1, a0
927; RV32I-NEXT:    mv a0, s0
928; RV32I-NEXT:    li a1, 0
929; RV32I-NEXT:    call __addsf3@plt
930; RV32I-NEXT:    mv s0, a0
931; RV32I-NEXT:    mv a0, s2
932; RV32I-NEXT:    mv a1, s1
933; RV32I-NEXT:    call __mulsf3@plt
934; RV32I-NEXT:    lui a1, 524288
935; RV32I-NEXT:    xor a0, a0, a1
936; RV32I-NEXT:    mv a1, s0
937; RV32I-NEXT:    call __subsf3@plt
938; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
939; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
940; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
941; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
942; RV32I-NEXT:    addi sp, sp, 16
943; RV32I-NEXT:    ret
944;
945; RV64I-LABEL: fnmadd_s_contract:
946; RV64I:       # %bb.0:
947; RV64I-NEXT:    addi sp, sp, -32
948; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
949; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
950; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
951; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
952; RV64I-NEXT:    mv s0, a2
953; RV64I-NEXT:    mv s1, a1
954; RV64I-NEXT:    li a1, 0
955; RV64I-NEXT:    call __addsf3@plt
956; RV64I-NEXT:    mv s2, a0
957; RV64I-NEXT:    mv a0, s1
958; RV64I-NEXT:    li a1, 0
959; RV64I-NEXT:    call __addsf3@plt
960; RV64I-NEXT:    mv s1, a0
961; RV64I-NEXT:    mv a0, s0
962; RV64I-NEXT:    li a1, 0
963; RV64I-NEXT:    call __addsf3@plt
964; RV64I-NEXT:    mv s0, a0
965; RV64I-NEXT:    mv a0, s2
966; RV64I-NEXT:    mv a1, s1
967; RV64I-NEXT:    call __mulsf3@plt
968; RV64I-NEXT:    lui a1, 524288
969; RV64I-NEXT:    xor a0, a0, a1
970; RV64I-NEXT:    mv a1, s0
971; RV64I-NEXT:    call __subsf3@plt
972; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
973; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
974; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
975; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
976; RV64I-NEXT:    addi sp, sp, 32
977; RV64I-NEXT:    ret
978  %a_ = fadd float 0.0, %a ; avoid negation using xor
979  %b_ = fadd float 0.0, %b ; avoid negation using xor
980  %c_ = fadd float 0.0, %c ; avoid negation using xor
981  %1 = fmul contract float %a_, %b_
982  %2 = fneg float %1
983  %3 = fsub contract float %2, %c_
984  ret float %3
985}
986
987define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind {
988; CHECKIF-LABEL: fnmsub_s_contract:
989; CHECKIF:       # %bb.0:
990; CHECKIF-NEXT:    fmv.w.x ft0, zero
991; CHECKIF-NEXT:    fadd.s ft1, fa0, ft0
992; CHECKIF-NEXT:    fadd.s ft0, fa1, ft0
993; CHECKIF-NEXT:    fnmsub.s fa0, ft1, ft0, fa2
994; CHECKIF-NEXT:    ret
995;
996; RV32I-LABEL: fnmsub_s_contract:
997; RV32I:       # %bb.0:
998; RV32I-NEXT:    addi sp, sp, -16
999; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1000; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
1001; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
1002; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
1003; RV32I-NEXT:    mv s0, a2
1004; RV32I-NEXT:    mv s1, a1
1005; RV32I-NEXT:    li a1, 0
1006; RV32I-NEXT:    call __addsf3@plt
1007; RV32I-NEXT:    mv s2, a0
1008; RV32I-NEXT:    mv a0, s1
1009; RV32I-NEXT:    li a1, 0
1010; RV32I-NEXT:    call __addsf3@plt
1011; RV32I-NEXT:    mv a1, a0
1012; RV32I-NEXT:    mv a0, s2
1013; RV32I-NEXT:    call __mulsf3@plt
1014; RV32I-NEXT:    mv a1, a0
1015; RV32I-NEXT:    mv a0, s0
1016; RV32I-NEXT:    call __subsf3@plt
1017; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1018; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1019; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1020; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
1021; RV32I-NEXT:    addi sp, sp, 16
1022; RV32I-NEXT:    ret
1023;
1024; RV64I-LABEL: fnmsub_s_contract:
1025; RV64I:       # %bb.0:
1026; RV64I-NEXT:    addi sp, sp, -32
1027; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1028; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1029; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1030; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1031; RV64I-NEXT:    mv s0, a2
1032; RV64I-NEXT:    mv s1, a1
1033; RV64I-NEXT:    li a1, 0
1034; RV64I-NEXT:    call __addsf3@plt
1035; RV64I-NEXT:    mv s2, a0
1036; RV64I-NEXT:    mv a0, s1
1037; RV64I-NEXT:    li a1, 0
1038; RV64I-NEXT:    call __addsf3@plt
1039; RV64I-NEXT:    mv a1, a0
1040; RV64I-NEXT:    mv a0, s2
1041; RV64I-NEXT:    call __mulsf3@plt
1042; RV64I-NEXT:    mv a1, a0
1043; RV64I-NEXT:    mv a0, s0
1044; RV64I-NEXT:    call __subsf3@plt
1045; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1046; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1047; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1048; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1049; RV64I-NEXT:    addi sp, sp, 32
1050; RV64I-NEXT:    ret
1051  %a_ = fadd float 0.0, %a ; avoid negation using xor
1052  %b_ = fadd float 0.0, %b ; avoid negation using xor
1053  %1 = fmul contract float %a_, %b_
1054  %2 = fsub contract float %c, %1
1055  ret float %2
1056}
1057