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