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; RV32I-LABEL: fnmadd_s_3:
615; RV32I:       # %bb.0:
616; RV32I-NEXT:    addi sp, sp, -16
617; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
618; RV32I-NEXT:    call fmaf@plt
619; RV32I-NEXT:    lui a1, 524288
620; RV32I-NEXT:    xor a0, a0, a1
621; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
622; RV32I-NEXT:    addi sp, sp, 16
623; RV32I-NEXT:    ret
624;
625; RV64I-LABEL: fnmadd_s_3:
626; RV64I:       # %bb.0:
627; RV64I-NEXT:    addi sp, sp, -16
628; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
629; RV64I-NEXT:    call fmaf@plt
630; RV64I-NEXT:    lui a1, 524288
631; RV64I-NEXT:    xor a0, a0, a1
632; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
633; RV64I-NEXT:    addi sp, sp, 16
634; RV64I-NEXT:    ret
635  %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
636  %neg = fneg float %1
637  ret float %neg
638}
639
640define float @fnmadd_nsz(float %a, float %b, float %c) nounwind {
641; RV32IF-LABEL: fnmadd_nsz:
642; RV32IF:       # %bb.0:
643; RV32IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
644; RV32IF-NEXT:    ret
645;
646; RV64IF-LABEL: fnmadd_nsz:
647; RV64IF:       # %bb.0:
648; RV64IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
649; RV64IF-NEXT:    ret
650;
651; RV32I-LABEL: fnmadd_nsz:
652; RV32I:       # %bb.0:
653; RV32I-NEXT:    addi sp, sp, -16
654; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
655; RV32I-NEXT:    call fmaf@plt
656; RV32I-NEXT:    lui a1, 524288
657; RV32I-NEXT:    xor a0, a0, a1
658; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
659; RV32I-NEXT:    addi sp, sp, 16
660; RV32I-NEXT:    ret
661;
662; RV64I-LABEL: fnmadd_nsz:
663; RV64I:       # %bb.0:
664; RV64I-NEXT:    addi sp, sp, -16
665; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
666; RV64I-NEXT:    call fmaf@plt
667; RV64I-NEXT:    lui a1, 524288
668; RV64I-NEXT:    xor a0, a0, a1
669; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
670; RV64I-NEXT:    addi sp, sp, 16
671; RV64I-NEXT:    ret
672  %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c)
673  %neg = fneg nsz float %1
674  ret float %neg
675}
676
677define float @fnmsub_s(float %a, float %b, float %c) nounwind {
678; CHECKIF-LABEL: fnmsub_s:
679; CHECKIF:       # %bb.0:
680; CHECKIF-NEXT:    fmv.w.x ft0, zero
681; CHECKIF-NEXT:    fadd.s ft0, fa0, ft0
682; CHECKIF-NEXT:    fnmsub.s fa0, ft0, fa1, fa2
683; CHECKIF-NEXT:    ret
684;
685; RV32I-LABEL: fnmsub_s:
686; RV32I:       # %bb.0:
687; RV32I-NEXT:    addi sp, sp, -16
688; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
689; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
690; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
691; RV32I-NEXT:    mv s0, a2
692; RV32I-NEXT:    mv s1, a1
693; RV32I-NEXT:    li a1, 0
694; RV32I-NEXT:    call __addsf3@plt
695; RV32I-NEXT:    lui a1, 524288
696; RV32I-NEXT:    xor a0, a0, a1
697; RV32I-NEXT:    mv a1, s1
698; RV32I-NEXT:    mv a2, s0
699; RV32I-NEXT:    call fmaf@plt
700; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
701; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
702; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
703; RV32I-NEXT:    addi sp, sp, 16
704; RV32I-NEXT:    ret
705;
706; RV64I-LABEL: fnmsub_s:
707; RV64I:       # %bb.0:
708; RV64I-NEXT:    addi sp, sp, -32
709; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
710; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
711; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
712; RV64I-NEXT:    mv s0, a2
713; RV64I-NEXT:    mv s1, a1
714; RV64I-NEXT:    li a1, 0
715; RV64I-NEXT:    call __addsf3@plt
716; RV64I-NEXT:    lui a1, 524288
717; RV64I-NEXT:    xor a0, a0, a1
718; RV64I-NEXT:    mv a1, s1
719; RV64I-NEXT:    mv a2, s0
720; RV64I-NEXT:    call fmaf@plt
721; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
722; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
723; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
724; RV64I-NEXT:    addi sp, sp, 32
725; RV64I-NEXT:    ret
726  %a_ = fadd float 0.0, %a
727  %nega = fsub float -0.0, %a_
728  %1 = call float @llvm.fma.f32(float %nega, float %b, float %c)
729  ret float %1
730}
731
732define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
733; CHECKIF-LABEL: fnmsub_s_2:
734; CHECKIF:       # %bb.0:
735; CHECKIF-NEXT:    fmv.w.x ft0, zero
736; CHECKIF-NEXT:    fadd.s ft0, fa1, ft0
737; CHECKIF-NEXT:    fnmsub.s fa0, ft0, fa0, fa2
738; CHECKIF-NEXT:    ret
739;
740; RV32I-LABEL: fnmsub_s_2:
741; RV32I:       # %bb.0:
742; RV32I-NEXT:    addi sp, sp, -16
743; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
744; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
745; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
746; RV32I-NEXT:    mv s0, a2
747; RV32I-NEXT:    mv s1, a0
748; RV32I-NEXT:    mv a0, a1
749; RV32I-NEXT:    li a1, 0
750; RV32I-NEXT:    call __addsf3@plt
751; RV32I-NEXT:    lui a1, 524288
752; RV32I-NEXT:    xor a1, a0, a1
753; RV32I-NEXT:    mv a0, s1
754; RV32I-NEXT:    mv a2, s0
755; RV32I-NEXT:    call fmaf@plt
756; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
757; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
758; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
759; RV32I-NEXT:    addi sp, sp, 16
760; RV32I-NEXT:    ret
761;
762; RV64I-LABEL: fnmsub_s_2:
763; RV64I:       # %bb.0:
764; RV64I-NEXT:    addi sp, sp, -32
765; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
766; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
767; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
768; RV64I-NEXT:    mv s0, a2
769; RV64I-NEXT:    mv s1, a0
770; RV64I-NEXT:    mv a0, a1
771; RV64I-NEXT:    li a1, 0
772; RV64I-NEXT:    call __addsf3@plt
773; RV64I-NEXT:    lui a1, 524288
774; RV64I-NEXT:    xor a1, a0, a1
775; RV64I-NEXT:    mv a0, s1
776; RV64I-NEXT:    mv a2, s0
777; RV64I-NEXT:    call fmaf@plt
778; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
779; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
780; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
781; RV64I-NEXT:    addi sp, sp, 32
782; RV64I-NEXT:    ret
783  %b_ = fadd float 0.0, %b
784  %negb = fsub float -0.0, %b_
785  %1 = call float @llvm.fma.f32(float %a, float %negb, float %c)
786  ret float %1
787}
788
789define float @fmadd_s_contract(float %a, float %b, float %c) nounwind {
790; CHECKIF-LABEL: fmadd_s_contract:
791; CHECKIF:       # %bb.0:
792; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
793; CHECKIF-NEXT:    ret
794;
795; RV32I-LABEL: fmadd_s_contract:
796; RV32I:       # %bb.0:
797; RV32I-NEXT:    addi sp, sp, -16
798; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
799; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
800; RV32I-NEXT:    mv s0, a2
801; RV32I-NEXT:    call __mulsf3@plt
802; RV32I-NEXT:    mv a1, s0
803; RV32I-NEXT:    call __addsf3@plt
804; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
805; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
806; RV32I-NEXT:    addi sp, sp, 16
807; RV32I-NEXT:    ret
808;
809; RV64I-LABEL: fmadd_s_contract:
810; RV64I:       # %bb.0:
811; RV64I-NEXT:    addi sp, sp, -16
812; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
813; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
814; RV64I-NEXT:    mv s0, a2
815; RV64I-NEXT:    call __mulsf3@plt
816; RV64I-NEXT:    mv a1, s0
817; RV64I-NEXT:    call __addsf3@plt
818; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
819; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
820; RV64I-NEXT:    addi sp, sp, 16
821; RV64I-NEXT:    ret
822  %1 = fmul contract float %a, %b
823  %2 = fadd contract float %1, %c
824  ret float %2
825}
826
827define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
828; CHECKIF-LABEL: fmsub_s_contract:
829; CHECKIF:       # %bb.0:
830; CHECKIF-NEXT:    fmv.w.x ft0, zero
831; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
832; CHECKIF-NEXT:    fmsub.s fa0, fa0, fa1, ft0
833; CHECKIF-NEXT:    ret
834;
835; RV32I-LABEL: fmsub_s_contract:
836; RV32I:       # %bb.0:
837; RV32I-NEXT:    addi sp, sp, -16
838; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
839; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
840; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
841; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
842; RV32I-NEXT:    mv s0, a1
843; RV32I-NEXT:    mv s1, a0
844; RV32I-NEXT:    mv a0, a2
845; RV32I-NEXT:    li a1, 0
846; RV32I-NEXT:    call __addsf3@plt
847; RV32I-NEXT:    mv s2, a0
848; RV32I-NEXT:    mv a0, s1
849; RV32I-NEXT:    mv a1, s0
850; RV32I-NEXT:    call __mulsf3@plt
851; RV32I-NEXT:    mv a1, s2
852; RV32I-NEXT:    call __subsf3@plt
853; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
854; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
855; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
856; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
857; RV32I-NEXT:    addi sp, sp, 16
858; RV32I-NEXT:    ret
859;
860; RV64I-LABEL: fmsub_s_contract:
861; RV64I:       # %bb.0:
862; RV64I-NEXT:    addi sp, sp, -32
863; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
864; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
865; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
866; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
867; RV64I-NEXT:    mv s0, a1
868; RV64I-NEXT:    mv s1, a0
869; RV64I-NEXT:    mv a0, a2
870; RV64I-NEXT:    li a1, 0
871; RV64I-NEXT:    call __addsf3@plt
872; RV64I-NEXT:    mv s2, a0
873; RV64I-NEXT:    mv a0, s1
874; RV64I-NEXT:    mv a1, s0
875; RV64I-NEXT:    call __mulsf3@plt
876; RV64I-NEXT:    mv a1, s2
877; RV64I-NEXT:    call __subsf3@plt
878; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
879; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
880; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
881; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
882; RV64I-NEXT:    addi sp, sp, 32
883; RV64I-NEXT:    ret
884  %c_ = fadd float 0.0, %c ; avoid negation using xor
885  %1 = fmul contract float %a, %b
886  %2 = fsub contract float %1, %c_
887  ret float %2
888}
889
890define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind {
891; CHECKIF-LABEL: fnmadd_s_contract:
892; CHECKIF:       # %bb.0:
893; CHECKIF-NEXT:    fmv.w.x ft0, zero
894; CHECKIF-NEXT:    fadd.s ft1, fa0, ft0
895; CHECKIF-NEXT:    fadd.s ft2, fa1, ft0
896; CHECKIF-NEXT:    fadd.s ft0, fa2, ft0
897; CHECKIF-NEXT:    fnmadd.s fa0, ft1, ft2, ft0
898; CHECKIF-NEXT:    ret
899;
900; RV32I-LABEL: fnmadd_s_contract:
901; RV32I:       # %bb.0:
902; RV32I-NEXT:    addi sp, sp, -16
903; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
904; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
905; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
906; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
907; RV32I-NEXT:    mv s0, a2
908; RV32I-NEXT:    mv s1, a1
909; RV32I-NEXT:    li a1, 0
910; RV32I-NEXT:    call __addsf3@plt
911; RV32I-NEXT:    mv s2, a0
912; RV32I-NEXT:    mv a0, s1
913; RV32I-NEXT:    li a1, 0
914; RV32I-NEXT:    call __addsf3@plt
915; RV32I-NEXT:    mv s1, a0
916; RV32I-NEXT:    mv a0, s0
917; RV32I-NEXT:    li a1, 0
918; RV32I-NEXT:    call __addsf3@plt
919; RV32I-NEXT:    mv s0, a0
920; RV32I-NEXT:    mv a0, s2
921; RV32I-NEXT:    mv a1, s1
922; RV32I-NEXT:    call __mulsf3@plt
923; RV32I-NEXT:    lui a1, 524288
924; RV32I-NEXT:    xor a0, a0, a1
925; RV32I-NEXT:    mv a1, s0
926; RV32I-NEXT:    call __subsf3@plt
927; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
928; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
929; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
930; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
931; RV32I-NEXT:    addi sp, sp, 16
932; RV32I-NEXT:    ret
933;
934; RV64I-LABEL: fnmadd_s_contract:
935; RV64I:       # %bb.0:
936; RV64I-NEXT:    addi sp, sp, -32
937; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
938; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
939; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
940; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
941; RV64I-NEXT:    mv s0, a2
942; RV64I-NEXT:    mv s1, a1
943; RV64I-NEXT:    li a1, 0
944; RV64I-NEXT:    call __addsf3@plt
945; RV64I-NEXT:    mv s2, a0
946; RV64I-NEXT:    mv a0, s1
947; RV64I-NEXT:    li a1, 0
948; RV64I-NEXT:    call __addsf3@plt
949; RV64I-NEXT:    mv s1, a0
950; RV64I-NEXT:    mv a0, s0
951; RV64I-NEXT:    li a1, 0
952; RV64I-NEXT:    call __addsf3@plt
953; RV64I-NEXT:    mv s0, a0
954; RV64I-NEXT:    mv a0, s2
955; RV64I-NEXT:    mv a1, s1
956; RV64I-NEXT:    call __mulsf3@plt
957; RV64I-NEXT:    lui a1, 524288
958; RV64I-NEXT:    xor a0, a0, a1
959; RV64I-NEXT:    mv a1, s0
960; RV64I-NEXT:    call __subsf3@plt
961; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
962; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
963; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
964; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
965; RV64I-NEXT:    addi sp, sp, 32
966; RV64I-NEXT:    ret
967  %a_ = fadd float 0.0, %a ; avoid negation using xor
968  %b_ = fadd float 0.0, %b ; avoid negation using xor
969  %c_ = fadd float 0.0, %c ; avoid negation using xor
970  %1 = fmul contract float %a_, %b_
971  %2 = fneg float %1
972  %3 = fsub contract float %2, %c_
973  ret float %3
974}
975
976define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind {
977; CHECKIF-LABEL: fnmsub_s_contract:
978; CHECKIF:       # %bb.0:
979; CHECKIF-NEXT:    fmv.w.x ft0, zero
980; CHECKIF-NEXT:    fadd.s ft1, fa0, ft0
981; CHECKIF-NEXT:    fadd.s ft0, fa1, ft0
982; CHECKIF-NEXT:    fnmsub.s fa0, ft1, ft0, fa2
983; CHECKIF-NEXT:    ret
984;
985; RV32I-LABEL: fnmsub_s_contract:
986; RV32I:       # %bb.0:
987; RV32I-NEXT:    addi sp, sp, -16
988; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
989; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
990; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
991; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
992; RV32I-NEXT:    mv s0, a2
993; RV32I-NEXT:    mv s1, a1
994; RV32I-NEXT:    li a1, 0
995; RV32I-NEXT:    call __addsf3@plt
996; RV32I-NEXT:    mv s2, a0
997; RV32I-NEXT:    mv a0, s1
998; RV32I-NEXT:    li a1, 0
999; RV32I-NEXT:    call __addsf3@plt
1000; RV32I-NEXT:    mv a1, a0
1001; RV32I-NEXT:    mv a0, s2
1002; RV32I-NEXT:    call __mulsf3@plt
1003; RV32I-NEXT:    mv a1, a0
1004; RV32I-NEXT:    mv a0, s0
1005; RV32I-NEXT:    call __subsf3@plt
1006; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1007; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1008; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1009; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
1010; RV32I-NEXT:    addi sp, sp, 16
1011; RV32I-NEXT:    ret
1012;
1013; RV64I-LABEL: fnmsub_s_contract:
1014; RV64I:       # %bb.0:
1015; RV64I-NEXT:    addi sp, sp, -32
1016; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1017; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1018; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1019; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1020; RV64I-NEXT:    mv s0, a2
1021; RV64I-NEXT:    mv s1, a1
1022; RV64I-NEXT:    li a1, 0
1023; RV64I-NEXT:    call __addsf3@plt
1024; RV64I-NEXT:    mv s2, a0
1025; RV64I-NEXT:    mv a0, s1
1026; RV64I-NEXT:    li a1, 0
1027; RV64I-NEXT:    call __addsf3@plt
1028; RV64I-NEXT:    mv a1, a0
1029; RV64I-NEXT:    mv a0, s2
1030; RV64I-NEXT:    call __mulsf3@plt
1031; RV64I-NEXT:    mv a1, a0
1032; RV64I-NEXT:    mv a0, s0
1033; RV64I-NEXT:    call __subsf3@plt
1034; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1035; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1036; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1037; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1038; RV64I-NEXT:    addi sp, sp, 32
1039; RV64I-NEXT:    ret
1040  %a_ = fadd float 0.0, %a ; avoid negation using xor
1041  %b_ = fadd float 0.0, %b ; avoid negation using xor
1042  %1 = fmul contract float %a_, %b_
1043  %2 = fsub contract float %c, %1
1044  ret float %2
1045}
1046