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:   -disable-strictnode-mutation -target-abi=ilp32f \
4; RUN:   | FileCheck -check-prefix=RV32IF %s
5; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
6; RUN:   -disable-strictnode-mutation -target-abi=lp64f \
7; RUN:   | FileCheck -check-prefix=RV64IF %s
8; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
9; RUN:   -disable-strictnode-mutation | FileCheck -check-prefix=RV32I %s
10; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
11; RUN:   -disable-strictnode-mutation | FileCheck -check-prefix=RV64I %s
12
13define float @fadd_s(float %a, float %b) nounwind strictfp {
14; RV32IF-LABEL: fadd_s:
15; RV32IF:       # %bb.0:
16; RV32IF-NEXT:    fadd.s fa0, fa0, fa1
17; RV32IF-NEXT:    ret
18;
19; RV64IF-LABEL: fadd_s:
20; RV64IF:       # %bb.0:
21; RV64IF-NEXT:    fadd.s fa0, fa0, fa1
22; RV64IF-NEXT:    ret
23;
24; RV32I-LABEL: fadd_s:
25; RV32I:       # %bb.0:
26; RV32I-NEXT:    addi sp, sp, -16
27; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
28; RV32I-NEXT:    call __addsf3@plt
29; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
30; RV32I-NEXT:    addi sp, sp, 16
31; RV32I-NEXT:    ret
32;
33; RV64I-LABEL: fadd_s:
34; RV64I:       # %bb.0:
35; RV64I-NEXT:    addi sp, sp, -16
36; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
37; RV64I-NEXT:    call __addsf3@plt
38; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
39; RV64I-NEXT:    addi sp, sp, 16
40; RV64I-NEXT:    ret
41  %1 = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
42  ret float %1
43}
44declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
45
46define float @fsub_s(float %a, float %b) nounwind strictfp {
47; RV32IF-LABEL: fsub_s:
48; RV32IF:       # %bb.0:
49; RV32IF-NEXT:    fsub.s fa0, fa0, fa1
50; RV32IF-NEXT:    ret
51;
52; RV64IF-LABEL: fsub_s:
53; RV64IF:       # %bb.0:
54; RV64IF-NEXT:    fsub.s fa0, fa0, fa1
55; RV64IF-NEXT:    ret
56;
57; RV32I-LABEL: fsub_s:
58; RV32I:       # %bb.0:
59; RV32I-NEXT:    addi sp, sp, -16
60; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
61; RV32I-NEXT:    call __subsf3@plt
62; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
63; RV32I-NEXT:    addi sp, sp, 16
64; RV32I-NEXT:    ret
65;
66; RV64I-LABEL: fsub_s:
67; RV64I:       # %bb.0:
68; RV64I-NEXT:    addi sp, sp, -16
69; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
70; RV64I-NEXT:    call __subsf3@plt
71; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
72; RV64I-NEXT:    addi sp, sp, 16
73; RV64I-NEXT:    ret
74  %1 = call float @llvm.experimental.constrained.fsub.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
75  ret float %1
76}
77declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
78
79define float @fmul_s(float %a, float %b) nounwind strictfp {
80; RV32IF-LABEL: fmul_s:
81; RV32IF:       # %bb.0:
82; RV32IF-NEXT:    fmul.s fa0, fa0, fa1
83; RV32IF-NEXT:    ret
84;
85; RV64IF-LABEL: fmul_s:
86; RV64IF:       # %bb.0:
87; RV64IF-NEXT:    fmul.s fa0, fa0, fa1
88; RV64IF-NEXT:    ret
89;
90; RV32I-LABEL: fmul_s:
91; RV32I:       # %bb.0:
92; RV32I-NEXT:    addi sp, sp, -16
93; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
94; RV32I-NEXT:    call __mulsf3@plt
95; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
96; RV32I-NEXT:    addi sp, sp, 16
97; RV32I-NEXT:    ret
98;
99; RV64I-LABEL: fmul_s:
100; RV64I:       # %bb.0:
101; RV64I-NEXT:    addi sp, sp, -16
102; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
103; RV64I-NEXT:    call __mulsf3@plt
104; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
105; RV64I-NEXT:    addi sp, sp, 16
106; RV64I-NEXT:    ret
107  %1 = call float @llvm.experimental.constrained.fmul.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
108  ret float %1
109}
110declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata)
111
112define float @fdiv_s(float %a, float %b) nounwind strictfp {
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 = call float @llvm.experimental.constrained.fdiv.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
141  ret float %1
142}
143declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata)
144
145define float @fsqrt_s(float %a) nounwind strictfp {
146; RV32IF-LABEL: fsqrt_s:
147; RV32IF:       # %bb.0:
148; RV32IF-NEXT:    fsqrt.s fa0, fa0
149; RV32IF-NEXT:    ret
150;
151; RV64IF-LABEL: fsqrt_s:
152; RV64IF:       # %bb.0:
153; RV64IF-NEXT:    fsqrt.s fa0, fa0
154; RV64IF-NEXT:    ret
155;
156; RV32I-LABEL: fsqrt_s:
157; RV32I:       # %bb.0:
158; RV32I-NEXT:    addi sp, sp, -16
159; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
160; RV32I-NEXT:    call sqrtf@plt
161; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
162; RV32I-NEXT:    addi sp, sp, 16
163; RV32I-NEXT:    ret
164;
165; RV64I-LABEL: fsqrt_s:
166; RV64I:       # %bb.0:
167; RV64I-NEXT:    addi sp, sp, -16
168; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
169; RV64I-NEXT:    call sqrtf@plt
170; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
171; RV64I-NEXT:    addi sp, sp, 16
172; RV64I-NEXT:    ret
173  %1 = call float @llvm.experimental.constrained.sqrt.f32(float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
174  ret float %1
175}
176declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
177
178define float @fmin_s(float %a, float %b) nounwind strictfp {
179; RV32IF-LABEL: fmin_s:
180; RV32IF:       # %bb.0:
181; RV32IF-NEXT:    addi sp, sp, -16
182; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
183; RV32IF-NEXT:    call fminf@plt
184; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
185; RV32IF-NEXT:    addi sp, sp, 16
186; RV32IF-NEXT:    ret
187;
188; RV64IF-LABEL: fmin_s:
189; RV64IF:       # %bb.0:
190; RV64IF-NEXT:    addi sp, sp, -16
191; RV64IF-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
192; RV64IF-NEXT:    call fminf@plt
193; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
194; RV64IF-NEXT:    addi sp, sp, 16
195; RV64IF-NEXT:    ret
196;
197; RV32I-LABEL: fmin_s:
198; RV32I:       # %bb.0:
199; RV32I-NEXT:    addi sp, sp, -16
200; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
201; RV32I-NEXT:    call fminf@plt
202; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
203; RV32I-NEXT:    addi sp, sp, 16
204; RV32I-NEXT:    ret
205;
206; RV64I-LABEL: fmin_s:
207; RV64I:       # %bb.0:
208; RV64I-NEXT:    addi sp, sp, -16
209; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
210; RV64I-NEXT:    call fminf@plt
211; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
212; RV64I-NEXT:    addi sp, sp, 16
213; RV64I-NEXT:    ret
214  %1 = call float @llvm.experimental.constrained.minnum.f32(float %a, float %b, metadata !"fpexcept.strict") strictfp
215  ret float %1
216}
217declare float @llvm.experimental.constrained.minnum.f32(float, float, metadata) strictfp
218
219define float @fmax_s(float %a, float %b) nounwind strictfp {
220; RV32IF-LABEL: fmax_s:
221; RV32IF:       # %bb.0:
222; RV32IF-NEXT:    addi sp, sp, -16
223; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
224; RV32IF-NEXT:    call fmaxf@plt
225; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
226; RV32IF-NEXT:    addi sp, sp, 16
227; RV32IF-NEXT:    ret
228;
229; RV64IF-LABEL: fmax_s:
230; RV64IF:       # %bb.0:
231; RV64IF-NEXT:    addi sp, sp, -16
232; RV64IF-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
233; RV64IF-NEXT:    call fmaxf@plt
234; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
235; RV64IF-NEXT:    addi sp, sp, 16
236; RV64IF-NEXT:    ret
237;
238; RV32I-LABEL: fmax_s:
239; RV32I:       # %bb.0:
240; RV32I-NEXT:    addi sp, sp, -16
241; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
242; RV32I-NEXT:    call fmaxf@plt
243; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
244; RV32I-NEXT:    addi sp, sp, 16
245; RV32I-NEXT:    ret
246;
247; RV64I-LABEL: fmax_s:
248; RV64I:       # %bb.0:
249; RV64I-NEXT:    addi sp, sp, -16
250; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
251; RV64I-NEXT:    call fmaxf@plt
252; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
253; RV64I-NEXT:    addi sp, sp, 16
254; RV64I-NEXT:    ret
255  %1 = call float @llvm.experimental.constrained.maxnum.f32(float %a, float %b, metadata !"fpexcept.strict") strictfp
256  ret float %1
257}
258declare float @llvm.experimental.constrained.maxnum.f32(float, float, metadata) strictfp
259
260define float @fmadd_s(float %a, float %b, float %c) nounwind strictfp {
261; RV32IF-LABEL: fmadd_s:
262; RV32IF:       # %bb.0:
263; RV32IF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
264; RV32IF-NEXT:    ret
265;
266; RV64IF-LABEL: fmadd_s:
267; RV64IF:       # %bb.0:
268; RV64IF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
269; RV64IF-NEXT:    ret
270;
271; RV32I-LABEL: fmadd_s:
272; RV32I:       # %bb.0:
273; RV32I-NEXT:    addi sp, sp, -16
274; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
275; RV32I-NEXT:    call fmaf@plt
276; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
277; RV32I-NEXT:    addi sp, sp, 16
278; RV32I-NEXT:    ret
279;
280; RV64I-LABEL: fmadd_s:
281; RV64I:       # %bb.0:
282; RV64I-NEXT:    addi sp, sp, -16
283; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
284; RV64I-NEXT:    call fmaf@plt
285; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
286; RV64I-NEXT:    addi sp, sp, 16
287; RV64I-NEXT:    ret
288  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %b, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
289  ret float %1
290}
291declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata) strictfp
292
293define float @fmsub_s(float %a, float %b, float %c) nounwind strictfp {
294; RV32IF-LABEL: fmsub_s:
295; RV32IF:       # %bb.0:
296; RV32IF-NEXT:    fmv.w.x ft0, zero
297; RV32IF-NEXT:    fadd.s ft0, fa2, ft0
298; RV32IF-NEXT:    fmsub.s fa0, fa0, fa1, ft0
299; RV32IF-NEXT:    ret
300;
301; RV64IF-LABEL: fmsub_s:
302; RV64IF:       # %bb.0:
303; RV64IF-NEXT:    fmv.w.x ft0, zero
304; RV64IF-NEXT:    fadd.s ft0, fa2, ft0
305; RV64IF-NEXT:    fmsub.s fa0, fa0, fa1, ft0
306; RV64IF-NEXT:    ret
307;
308; RV32I-LABEL: fmsub_s:
309; RV32I:       # %bb.0:
310; RV32I-NEXT:    addi sp, sp, -16
311; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
312; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
313; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
314; RV32I-NEXT:    mv s0, a1
315; RV32I-NEXT:    mv s1, a0
316; RV32I-NEXT:    mv a0, a2
317; RV32I-NEXT:    li a1, 0
318; RV32I-NEXT:    call __addsf3@plt
319; RV32I-NEXT:    lui a1, 524288
320; RV32I-NEXT:    xor a2, a0, a1
321; RV32I-NEXT:    mv a0, s1
322; RV32I-NEXT:    mv a1, s0
323; RV32I-NEXT:    call fmaf@plt
324; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
325; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
326; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
327; RV32I-NEXT:    addi sp, sp, 16
328; RV32I-NEXT:    ret
329;
330; RV64I-LABEL: fmsub_s:
331; RV64I:       # %bb.0:
332; RV64I-NEXT:    addi sp, sp, -32
333; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
334; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
335; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
336; RV64I-NEXT:    mv s0, a1
337; RV64I-NEXT:    mv s1, a0
338; RV64I-NEXT:    mv a0, a2
339; RV64I-NEXT:    li a1, 0
340; RV64I-NEXT:    call __addsf3@plt
341; RV64I-NEXT:    lui a1, 524288
342; RV64I-NEXT:    xor a2, a0, a1
343; RV64I-NEXT:    mv a0, s1
344; RV64I-NEXT:    mv a1, s0
345; RV64I-NEXT:    call fmaf@plt
346; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
347; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
348; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
349; RV64I-NEXT:    addi sp, sp, 32
350; RV64I-NEXT:    ret
351  %c_ = fadd float 0.0, %c ; avoid negation using xor
352  %negc = fneg float %c_
353  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %b, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
354  ret float %1
355}
356
357define float @fnmadd_s(float %a, float %b, float %c) nounwind strictfp {
358; RV32IF-LABEL: fnmadd_s:
359; RV32IF:       # %bb.0:
360; RV32IF-NEXT:    fmv.w.x ft0, zero
361; RV32IF-NEXT:    fadd.s ft1, fa0, ft0
362; RV32IF-NEXT:    fadd.s ft0, fa2, ft0
363; RV32IF-NEXT:    fnmadd.s fa0, ft1, fa1, ft0
364; RV32IF-NEXT:    ret
365;
366; RV64IF-LABEL: fnmadd_s:
367; RV64IF:       # %bb.0:
368; RV64IF-NEXT:    fmv.w.x ft0, zero
369; RV64IF-NEXT:    fadd.s ft1, fa0, ft0
370; RV64IF-NEXT:    fadd.s ft0, fa2, ft0
371; RV64IF-NEXT:    fnmadd.s fa0, ft1, fa1, ft0
372; RV64IF-NEXT:    ret
373;
374; RV32I-LABEL: fnmadd_s:
375; RV32I:       # %bb.0:
376; RV32I-NEXT:    addi sp, sp, -16
377; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
378; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
379; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
380; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
381; RV32I-NEXT:    mv s0, a2
382; RV32I-NEXT:    mv s2, a1
383; RV32I-NEXT:    li a1, 0
384; RV32I-NEXT:    call __addsf3@plt
385; RV32I-NEXT:    mv s1, a0
386; RV32I-NEXT:    mv a0, s0
387; RV32I-NEXT:    li a1, 0
388; RV32I-NEXT:    call __addsf3@plt
389; RV32I-NEXT:    lui a2, 524288
390; RV32I-NEXT:    xor a1, s1, a2
391; RV32I-NEXT:    xor a2, a0, a2
392; RV32I-NEXT:    mv a0, a1
393; RV32I-NEXT:    mv a1, s2
394; RV32I-NEXT:    call fmaf@plt
395; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
396; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
397; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
398; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
399; RV32I-NEXT:    addi sp, sp, 16
400; RV32I-NEXT:    ret
401;
402; RV64I-LABEL: fnmadd_s:
403; RV64I:       # %bb.0:
404; RV64I-NEXT:    addi sp, sp, -32
405; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
406; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
407; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
408; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
409; RV64I-NEXT:    mv s0, a2
410; RV64I-NEXT:    mv s2, a1
411; RV64I-NEXT:    li a1, 0
412; RV64I-NEXT:    call __addsf3@plt
413; RV64I-NEXT:    mv s1, a0
414; RV64I-NEXT:    mv a0, s0
415; RV64I-NEXT:    li a1, 0
416; RV64I-NEXT:    call __addsf3@plt
417; RV64I-NEXT:    lui a2, 524288
418; RV64I-NEXT:    xor a1, s1, a2
419; RV64I-NEXT:    xor a2, a0, a2
420; RV64I-NEXT:    mv a0, a1
421; RV64I-NEXT:    mv a1, s2
422; RV64I-NEXT:    call fmaf@plt
423; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
424; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
425; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
426; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
427; RV64I-NEXT:    addi sp, sp, 32
428; RV64I-NEXT:    ret
429  %a_ = fadd float 0.0, %a
430  %c_ = fadd float 0.0, %c
431  %nega = fneg float %a_
432  %negc = fneg float %c_
433  %1 = call float @llvm.experimental.constrained.fma.f32(float %nega, float %b, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
434  ret float %1
435}
436
437define float @fnmadd_s_2(float %a, float %b, float %c) nounwind strictfp {
438; RV32IF-LABEL: fnmadd_s_2:
439; RV32IF:       # %bb.0:
440; RV32IF-NEXT:    fmv.w.x ft0, zero
441; RV32IF-NEXT:    fadd.s ft1, fa1, ft0
442; RV32IF-NEXT:    fadd.s ft0, fa2, ft0
443; RV32IF-NEXT:    fnmadd.s fa0, ft1, fa0, ft0
444; RV32IF-NEXT:    ret
445;
446; RV64IF-LABEL: fnmadd_s_2:
447; RV64IF:       # %bb.0:
448; RV64IF-NEXT:    fmv.w.x ft0, zero
449; RV64IF-NEXT:    fadd.s ft1, fa1, ft0
450; RV64IF-NEXT:    fadd.s ft0, fa2, ft0
451; RV64IF-NEXT:    fnmadd.s fa0, ft1, fa0, ft0
452; RV64IF-NEXT:    ret
453;
454; RV32I-LABEL: fnmadd_s_2:
455; RV32I:       # %bb.0:
456; RV32I-NEXT:    addi sp, sp, -16
457; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
458; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
459; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
460; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
461; RV32I-NEXT:    mv s0, a2
462; RV32I-NEXT:    mv s2, a0
463; RV32I-NEXT:    mv a0, a1
464; RV32I-NEXT:    li a1, 0
465; RV32I-NEXT:    call __addsf3@plt
466; RV32I-NEXT:    mv s1, a0
467; RV32I-NEXT:    mv a0, s0
468; RV32I-NEXT:    li a1, 0
469; RV32I-NEXT:    call __addsf3@plt
470; RV32I-NEXT:    lui a2, 524288
471; RV32I-NEXT:    xor a1, s1, a2
472; RV32I-NEXT:    xor a2, a0, a2
473; RV32I-NEXT:    mv a0, s2
474; RV32I-NEXT:    call fmaf@plt
475; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
476; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
477; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
478; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
479; RV32I-NEXT:    addi sp, sp, 16
480; RV32I-NEXT:    ret
481;
482; RV64I-LABEL: fnmadd_s_2:
483; RV64I:       # %bb.0:
484; RV64I-NEXT:    addi sp, sp, -32
485; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
486; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
487; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
488; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
489; RV64I-NEXT:    mv s0, a2
490; RV64I-NEXT:    mv s2, a0
491; RV64I-NEXT:    mv a0, a1
492; RV64I-NEXT:    li a1, 0
493; RV64I-NEXT:    call __addsf3@plt
494; RV64I-NEXT:    mv s1, a0
495; RV64I-NEXT:    mv a0, s0
496; RV64I-NEXT:    li a1, 0
497; RV64I-NEXT:    call __addsf3@plt
498; RV64I-NEXT:    lui a2, 524288
499; RV64I-NEXT:    xor a1, s1, a2
500; RV64I-NEXT:    xor a2, a0, a2
501; RV64I-NEXT:    mv a0, s2
502; RV64I-NEXT:    call fmaf@plt
503; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
504; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
505; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
506; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
507; RV64I-NEXT:    addi sp, sp, 32
508; RV64I-NEXT:    ret
509  %b_ = fadd float 0.0, %b
510  %c_ = fadd float 0.0, %c
511  %negb = fneg float %b_
512  %negc = fneg float %c_
513  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %negb, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
514  ret float %1
515}
516
517define float @fnmsub_s(float %a, float %b, float %c) nounwind strictfp {
518; RV32IF-LABEL: fnmsub_s:
519; RV32IF:       # %bb.0:
520; RV32IF-NEXT:    fmv.w.x ft0, zero
521; RV32IF-NEXT:    fadd.s ft0, fa0, ft0
522; RV32IF-NEXT:    fnmsub.s fa0, ft0, fa1, fa2
523; RV32IF-NEXT:    ret
524;
525; RV64IF-LABEL: fnmsub_s:
526; RV64IF:       # %bb.0:
527; RV64IF-NEXT:    fmv.w.x ft0, zero
528; RV64IF-NEXT:    fadd.s ft0, fa0, ft0
529; RV64IF-NEXT:    fnmsub.s fa0, ft0, fa1, fa2
530; RV64IF-NEXT:    ret
531;
532; RV32I-LABEL: fnmsub_s:
533; RV32I:       # %bb.0:
534; RV32I-NEXT:    addi sp, sp, -16
535; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
536; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
537; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
538; RV32I-NEXT:    mv s0, a2
539; RV32I-NEXT:    mv s1, a1
540; RV32I-NEXT:    li a1, 0
541; RV32I-NEXT:    call __addsf3@plt
542; RV32I-NEXT:    lui a1, 524288
543; RV32I-NEXT:    xor a0, a0, a1
544; RV32I-NEXT:    mv a1, s1
545; RV32I-NEXT:    mv a2, s0
546; RV32I-NEXT:    call fmaf@plt
547; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
548; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
549; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
550; RV32I-NEXT:    addi sp, sp, 16
551; RV32I-NEXT:    ret
552;
553; RV64I-LABEL: fnmsub_s:
554; RV64I:       # %bb.0:
555; RV64I-NEXT:    addi sp, sp, -32
556; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
557; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
558; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
559; RV64I-NEXT:    mv s0, a2
560; RV64I-NEXT:    mv s1, a1
561; RV64I-NEXT:    li a1, 0
562; RV64I-NEXT:    call __addsf3@plt
563; RV64I-NEXT:    lui a1, 524288
564; RV64I-NEXT:    xor a0, a0, a1
565; RV64I-NEXT:    mv a1, s1
566; RV64I-NEXT:    mv a2, s0
567; RV64I-NEXT:    call fmaf@plt
568; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
569; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
570; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
571; RV64I-NEXT:    addi sp, sp, 32
572; RV64I-NEXT:    ret
573  %a_ = fadd float 0.0, %a
574  %nega = fneg float %a_
575  %1 = call float @llvm.experimental.constrained.fma.f32(float %nega, float %b, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
576  ret float %1
577}
578
579define float @fnmsub_s_2(float %a, float %b, float %c) nounwind strictfp {
580; RV32IF-LABEL: fnmsub_s_2:
581; RV32IF:       # %bb.0:
582; RV32IF-NEXT:    fmv.w.x ft0, zero
583; RV32IF-NEXT:    fadd.s ft0, fa1, ft0
584; RV32IF-NEXT:    fnmsub.s fa0, ft0, fa0, fa2
585; RV32IF-NEXT:    ret
586;
587; RV64IF-LABEL: fnmsub_s_2:
588; RV64IF:       # %bb.0:
589; RV64IF-NEXT:    fmv.w.x ft0, zero
590; RV64IF-NEXT:    fadd.s ft0, fa1, ft0
591; RV64IF-NEXT:    fnmsub.s fa0, ft0, fa0, fa2
592; RV64IF-NEXT:    ret
593;
594; RV32I-LABEL: fnmsub_s_2:
595; RV32I:       # %bb.0:
596; RV32I-NEXT:    addi sp, sp, -16
597; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
598; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
599; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
600; RV32I-NEXT:    mv s0, a2
601; RV32I-NEXT:    mv s1, a0
602; RV32I-NEXT:    mv a0, a1
603; RV32I-NEXT:    li a1, 0
604; RV32I-NEXT:    call __addsf3@plt
605; RV32I-NEXT:    lui a1, 524288
606; RV32I-NEXT:    xor a1, a0, a1
607; RV32I-NEXT:    mv a0, s1
608; RV32I-NEXT:    mv a2, s0
609; RV32I-NEXT:    call fmaf@plt
610; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
611; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
612; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
613; RV32I-NEXT:    addi sp, sp, 16
614; RV32I-NEXT:    ret
615;
616; RV64I-LABEL: fnmsub_s_2:
617; RV64I:       # %bb.0:
618; RV64I-NEXT:    addi sp, sp, -32
619; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
620; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
621; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
622; RV64I-NEXT:    mv s0, a2
623; RV64I-NEXT:    mv s1, a0
624; RV64I-NEXT:    mv a0, a1
625; RV64I-NEXT:    li a1, 0
626; RV64I-NEXT:    call __addsf3@plt
627; RV64I-NEXT:    lui a1, 524288
628; RV64I-NEXT:    xor a1, a0, a1
629; RV64I-NEXT:    mv a0, s1
630; RV64I-NEXT:    mv a2, s0
631; RV64I-NEXT:    call fmaf@plt
632; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
633; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
634; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
635; RV64I-NEXT:    addi sp, sp, 32
636; RV64I-NEXT:    ret
637  %b_ = fadd float 0.0, %b
638  %negb = fneg float %b_
639  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %negb, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
640  ret float %1
641}
642