1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+zfh -verify-machineinstrs \
3; RUN:   -target-abi ilp32f < %s | FileCheck -check-prefix=RV32IZFH %s
4; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
5; RUN:   -target-abi lp64f < %s | FileCheck -check-prefix=RV64IZFH %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 half-fcmp.ll and half-convert.ll
13; respectively. Some other half-*.ll files in this folder exercise LLVM IR
14; instructions that don't directly match a RISC-V instruction.
15
16define half @fadd_s(half %a, half %b) nounwind {
17; RV32IZFH-LABEL: fadd_s:
18; RV32IZFH:       # %bb.0:
19; RV32IZFH-NEXT:    fadd.h fa0, fa0, fa1
20; RV32IZFH-NEXT:    ret
21;
22; RV64IZFH-LABEL: fadd_s:
23; RV64IZFH:       # %bb.0:
24; RV64IZFH-NEXT:    fadd.h fa0, fa0, fa1
25; RV64IZFH-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:    sw s0, 8(sp) # 4-byte Folded Spill
32; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
33; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
34; RV32I-NEXT:    mv s2, a1
35; RV32I-NEXT:    lui a1, 16
36; RV32I-NEXT:    addi s0, a1, -1
37; RV32I-NEXT:    and a0, a0, s0
38; RV32I-NEXT:    call __gnu_h2f_ieee@plt
39; RV32I-NEXT:    mv s1, a0
40; RV32I-NEXT:    and a0, s2, s0
41; RV32I-NEXT:    call __gnu_h2f_ieee@plt
42; RV32I-NEXT:    mv a1, a0
43; RV32I-NEXT:    mv a0, s1
44; RV32I-NEXT:    call __addsf3@plt
45; RV32I-NEXT:    call __gnu_f2h_ieee@plt
46; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
47; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
48; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
49; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
50; RV32I-NEXT:    addi sp, sp, 16
51; RV32I-NEXT:    ret
52;
53; RV64I-LABEL: fadd_s:
54; RV64I:       # %bb.0:
55; RV64I-NEXT:    addi sp, sp, -32
56; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
57; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
58; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
59; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
60; RV64I-NEXT:    mv s2, a1
61; RV64I-NEXT:    lui a1, 16
62; RV64I-NEXT:    addiw s0, a1, -1
63; RV64I-NEXT:    and a0, a0, s0
64; RV64I-NEXT:    call __gnu_h2f_ieee@plt
65; RV64I-NEXT:    mv s1, a0
66; RV64I-NEXT:    and a0, s2, s0
67; RV64I-NEXT:    call __gnu_h2f_ieee@plt
68; RV64I-NEXT:    mv a1, a0
69; RV64I-NEXT:    mv a0, s1
70; RV64I-NEXT:    call __addsf3@plt
71; RV64I-NEXT:    call __gnu_f2h_ieee@plt
72; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
73; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
74; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
75; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
76; RV64I-NEXT:    addi sp, sp, 32
77; RV64I-NEXT:    ret
78  %1 = fadd half %a, %b
79  ret half %1
80}
81
82define half @fsub_s(half %a, half %b) nounwind {
83; RV32IZFH-LABEL: fsub_s:
84; RV32IZFH:       # %bb.0:
85; RV32IZFH-NEXT:    fsub.h fa0, fa0, fa1
86; RV32IZFH-NEXT:    ret
87;
88; RV64IZFH-LABEL: fsub_s:
89; RV64IZFH:       # %bb.0:
90; RV64IZFH-NEXT:    fsub.h fa0, fa0, fa1
91; RV64IZFH-NEXT:    ret
92;
93; RV32I-LABEL: fsub_s:
94; RV32I:       # %bb.0:
95; RV32I-NEXT:    addi sp, sp, -16
96; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
97; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
98; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
99; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
100; RV32I-NEXT:    mv s2, a1
101; RV32I-NEXT:    lui a1, 16
102; RV32I-NEXT:    addi s0, a1, -1
103; RV32I-NEXT:    and a0, a0, s0
104; RV32I-NEXT:    call __gnu_h2f_ieee@plt
105; RV32I-NEXT:    mv s1, a0
106; RV32I-NEXT:    and a0, s2, s0
107; RV32I-NEXT:    call __gnu_h2f_ieee@plt
108; RV32I-NEXT:    mv a1, a0
109; RV32I-NEXT:    mv a0, s1
110; RV32I-NEXT:    call __subsf3@plt
111; RV32I-NEXT:    call __gnu_f2h_ieee@plt
112; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
113; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
114; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
115; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
116; RV32I-NEXT:    addi sp, sp, 16
117; RV32I-NEXT:    ret
118;
119; RV64I-LABEL: fsub_s:
120; RV64I:       # %bb.0:
121; RV64I-NEXT:    addi sp, sp, -32
122; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
123; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
124; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
125; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
126; RV64I-NEXT:    mv s2, a1
127; RV64I-NEXT:    lui a1, 16
128; RV64I-NEXT:    addiw s0, a1, -1
129; RV64I-NEXT:    and a0, a0, s0
130; RV64I-NEXT:    call __gnu_h2f_ieee@plt
131; RV64I-NEXT:    mv s1, a0
132; RV64I-NEXT:    and a0, s2, s0
133; RV64I-NEXT:    call __gnu_h2f_ieee@plt
134; RV64I-NEXT:    mv a1, a0
135; RV64I-NEXT:    mv a0, s1
136; RV64I-NEXT:    call __subsf3@plt
137; RV64I-NEXT:    call __gnu_f2h_ieee@plt
138; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
139; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
140; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
141; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
142; RV64I-NEXT:    addi sp, sp, 32
143; RV64I-NEXT:    ret
144  %1 = fsub half %a, %b
145  ret half %1
146}
147
148define half @fmul_s(half %a, half %b) nounwind {
149; RV32IZFH-LABEL: fmul_s:
150; RV32IZFH:       # %bb.0:
151; RV32IZFH-NEXT:    fmul.h fa0, fa0, fa1
152; RV32IZFH-NEXT:    ret
153;
154; RV64IZFH-LABEL: fmul_s:
155; RV64IZFH:       # %bb.0:
156; RV64IZFH-NEXT:    fmul.h fa0, fa0, fa1
157; RV64IZFH-NEXT:    ret
158;
159; RV32I-LABEL: fmul_s:
160; RV32I:       # %bb.0:
161; RV32I-NEXT:    addi sp, sp, -16
162; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
163; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
164; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
165; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
166; RV32I-NEXT:    mv s2, a1
167; RV32I-NEXT:    lui a1, 16
168; RV32I-NEXT:    addi s0, a1, -1
169; RV32I-NEXT:    and a0, a0, s0
170; RV32I-NEXT:    call __gnu_h2f_ieee@plt
171; RV32I-NEXT:    mv s1, a0
172; RV32I-NEXT:    and a0, s2, s0
173; RV32I-NEXT:    call __gnu_h2f_ieee@plt
174; RV32I-NEXT:    mv a1, a0
175; RV32I-NEXT:    mv a0, s1
176; RV32I-NEXT:    call __mulsf3@plt
177; RV32I-NEXT:    call __gnu_f2h_ieee@plt
178; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
179; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
180; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
181; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
182; RV32I-NEXT:    addi sp, sp, 16
183; RV32I-NEXT:    ret
184;
185; RV64I-LABEL: fmul_s:
186; RV64I:       # %bb.0:
187; RV64I-NEXT:    addi sp, sp, -32
188; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
189; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
190; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
191; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
192; RV64I-NEXT:    mv s2, a1
193; RV64I-NEXT:    lui a1, 16
194; RV64I-NEXT:    addiw s0, a1, -1
195; RV64I-NEXT:    and a0, a0, s0
196; RV64I-NEXT:    call __gnu_h2f_ieee@plt
197; RV64I-NEXT:    mv s1, a0
198; RV64I-NEXT:    and a0, s2, s0
199; RV64I-NEXT:    call __gnu_h2f_ieee@plt
200; RV64I-NEXT:    mv a1, a0
201; RV64I-NEXT:    mv a0, s1
202; RV64I-NEXT:    call __mulsf3@plt
203; RV64I-NEXT:    call __gnu_f2h_ieee@plt
204; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
205; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
206; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
207; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
208; RV64I-NEXT:    addi sp, sp, 32
209; RV64I-NEXT:    ret
210  %1 = fmul half %a, %b
211  ret half %1
212}
213
214define half @fdiv_s(half %a, half %b) nounwind {
215; RV32IZFH-LABEL: fdiv_s:
216; RV32IZFH:       # %bb.0:
217; RV32IZFH-NEXT:    fdiv.h fa0, fa0, fa1
218; RV32IZFH-NEXT:    ret
219;
220; RV64IZFH-LABEL: fdiv_s:
221; RV64IZFH:       # %bb.0:
222; RV64IZFH-NEXT:    fdiv.h fa0, fa0, fa1
223; RV64IZFH-NEXT:    ret
224;
225; RV32I-LABEL: fdiv_s:
226; RV32I:       # %bb.0:
227; RV32I-NEXT:    addi sp, sp, -16
228; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
229; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
230; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
231; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
232; RV32I-NEXT:    mv s2, a1
233; RV32I-NEXT:    lui a1, 16
234; RV32I-NEXT:    addi s0, a1, -1
235; RV32I-NEXT:    and a0, a0, s0
236; RV32I-NEXT:    call __gnu_h2f_ieee@plt
237; RV32I-NEXT:    mv s1, a0
238; RV32I-NEXT:    and a0, s2, s0
239; RV32I-NEXT:    call __gnu_h2f_ieee@plt
240; RV32I-NEXT:    mv a1, a0
241; RV32I-NEXT:    mv a0, s1
242; RV32I-NEXT:    call __divsf3@plt
243; RV32I-NEXT:    call __gnu_f2h_ieee@plt
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:    lw s1, 4(sp) # 4-byte Folded Reload
247; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
248; RV32I-NEXT:    addi sp, sp, 16
249; RV32I-NEXT:    ret
250;
251; RV64I-LABEL: fdiv_s:
252; RV64I:       # %bb.0:
253; RV64I-NEXT:    addi sp, sp, -32
254; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
255; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
256; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
257; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
258; RV64I-NEXT:    mv s2, a1
259; RV64I-NEXT:    lui a1, 16
260; RV64I-NEXT:    addiw s0, a1, -1
261; RV64I-NEXT:    and a0, a0, s0
262; RV64I-NEXT:    call __gnu_h2f_ieee@plt
263; RV64I-NEXT:    mv s1, a0
264; RV64I-NEXT:    and a0, s2, s0
265; RV64I-NEXT:    call __gnu_h2f_ieee@plt
266; RV64I-NEXT:    mv a1, a0
267; RV64I-NEXT:    mv a0, s1
268; RV64I-NEXT:    call __divsf3@plt
269; RV64I-NEXT:    call __gnu_f2h_ieee@plt
270; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
271; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
272; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
273; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
274; RV64I-NEXT:    addi sp, sp, 32
275; RV64I-NEXT:    ret
276  %1 = fdiv half %a, %b
277  ret half %1
278}
279
280declare half @llvm.sqrt.f16(half)
281
282define half @fsqrt_s(half %a) nounwind {
283; RV32IZFH-LABEL: fsqrt_s:
284; RV32IZFH:       # %bb.0:
285; RV32IZFH-NEXT:    fsqrt.h fa0, fa0
286; RV32IZFH-NEXT:    ret
287;
288; RV64IZFH-LABEL: fsqrt_s:
289; RV64IZFH:       # %bb.0:
290; RV64IZFH-NEXT:    fsqrt.h fa0, fa0
291; RV64IZFH-NEXT:    ret
292;
293; RV32I-LABEL: fsqrt_s:
294; RV32I:       # %bb.0:
295; RV32I-NEXT:    addi sp, sp, -16
296; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
297; RV32I-NEXT:    slli a0, a0, 16
298; RV32I-NEXT:    srli a0, a0, 16
299; RV32I-NEXT:    call __gnu_h2f_ieee@plt
300; RV32I-NEXT:    call sqrtf@plt
301; RV32I-NEXT:    call __gnu_f2h_ieee@plt
302; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
303; RV32I-NEXT:    addi sp, sp, 16
304; RV32I-NEXT:    ret
305;
306; RV64I-LABEL: fsqrt_s:
307; RV64I:       # %bb.0:
308; RV64I-NEXT:    addi sp, sp, -16
309; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
310; RV64I-NEXT:    slli a0, a0, 48
311; RV64I-NEXT:    srli a0, a0, 48
312; RV64I-NEXT:    call __gnu_h2f_ieee@plt
313; RV64I-NEXT:    call sqrtf@plt
314; RV64I-NEXT:    call __gnu_f2h_ieee@plt
315; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
316; RV64I-NEXT:    addi sp, sp, 16
317; RV64I-NEXT:    ret
318  %1 = call half @llvm.sqrt.f16(half %a)
319  ret half %1
320}
321
322declare half @llvm.copysign.f16(half, half)
323
324define half @fsgnj_s(half %a, half %b) nounwind {
325; RV32IZFH-LABEL: fsgnj_s:
326; RV32IZFH:       # %bb.0:
327; RV32IZFH-NEXT:    fsgnj.h fa0, fa0, fa1
328; RV32IZFH-NEXT:    ret
329;
330; RV64IZFH-LABEL: fsgnj_s:
331; RV64IZFH:       # %bb.0:
332; RV64IZFH-NEXT:    fsgnj.h fa0, fa0, fa1
333; RV64IZFH-NEXT:    ret
334;
335; RV32I-LABEL: fsgnj_s:
336; RV32I:       # %bb.0:
337; RV32I-NEXT:    lui a2, 1048568
338; RV32I-NEXT:    and a1, a1, a2
339; RV32I-NEXT:    slli a0, a0, 17
340; RV32I-NEXT:    srli a0, a0, 17
341; RV32I-NEXT:    or a0, a0, a1
342; RV32I-NEXT:    ret
343;
344; RV64I-LABEL: fsgnj_s:
345; RV64I:       # %bb.0:
346; RV64I-NEXT:    lui a2, 1048568
347; RV64I-NEXT:    and a1, a1, a2
348; RV64I-NEXT:    slli a0, a0, 49
349; RV64I-NEXT:    srli a0, a0, 49
350; RV64I-NEXT:    or a0, a0, a1
351; RV64I-NEXT:    ret
352  %1 = call half @llvm.copysign.f16(half %a, half %b)
353  ret half %1
354}
355
356; This function performs extra work to ensure that
357; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
358define i32 @fneg_s(half %a, half %b) nounwind {
359; RV32IZFH-LABEL: fneg_s:
360; RV32IZFH:       # %bb.0:
361; RV32IZFH-NEXT:    fadd.h ft0, fa0, fa0
362; RV32IZFH-NEXT:    fneg.h ft1, ft0
363; RV32IZFH-NEXT:    feq.h a0, ft0, ft1
364; RV32IZFH-NEXT:    ret
365;
366; RV64IZFH-LABEL: fneg_s:
367; RV64IZFH:       # %bb.0:
368; RV64IZFH-NEXT:    fadd.h ft0, fa0, fa0
369; RV64IZFH-NEXT:    fneg.h ft1, ft0
370; RV64IZFH-NEXT:    feq.h a0, ft0, ft1
371; RV64IZFH-NEXT:    ret
372;
373; RV32I-LABEL: fneg_s:
374; RV32I:       # %bb.0:
375; RV32I-NEXT:    addi sp, sp, -16
376; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
377; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
378; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
379; RV32I-NEXT:    lui a1, 16
380; RV32I-NEXT:    addi s1, a1, -1
381; RV32I-NEXT:    and a0, a0, s1
382; RV32I-NEXT:    call __gnu_h2f_ieee@plt
383; RV32I-NEXT:    mv a1, a0
384; RV32I-NEXT:    call __addsf3@plt
385; RV32I-NEXT:    call __gnu_f2h_ieee@plt
386; RV32I-NEXT:    and a0, a0, s1
387; RV32I-NEXT:    call __gnu_h2f_ieee@plt
388; RV32I-NEXT:    mv s0, a0
389; RV32I-NEXT:    lui a0, 524288
390; RV32I-NEXT:    xor a0, s0, a0
391; RV32I-NEXT:    call __gnu_f2h_ieee@plt
392; RV32I-NEXT:    and a0, a0, s1
393; RV32I-NEXT:    call __gnu_h2f_ieee@plt
394; RV32I-NEXT:    mv a1, a0
395; RV32I-NEXT:    mv a0, s0
396; RV32I-NEXT:    call __eqsf2@plt
397; RV32I-NEXT:    seqz a0, a0
398; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
399; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
400; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
401; RV32I-NEXT:    addi sp, sp, 16
402; RV32I-NEXT:    ret
403;
404; RV64I-LABEL: fneg_s:
405; RV64I:       # %bb.0:
406; RV64I-NEXT:    addi sp, sp, -32
407; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
408; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
409; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
410; RV64I-NEXT:    lui a1, 16
411; RV64I-NEXT:    addiw s1, a1, -1
412; RV64I-NEXT:    and a0, a0, s1
413; RV64I-NEXT:    call __gnu_h2f_ieee@plt
414; RV64I-NEXT:    mv a1, a0
415; RV64I-NEXT:    call __addsf3@plt
416; RV64I-NEXT:    call __gnu_f2h_ieee@plt
417; RV64I-NEXT:    and a0, a0, s1
418; RV64I-NEXT:    call __gnu_h2f_ieee@plt
419; RV64I-NEXT:    mv s0, a0
420; RV64I-NEXT:    lui a0, 524288
421; RV64I-NEXT:    xor a0, s0, a0
422; RV64I-NEXT:    call __gnu_f2h_ieee@plt
423; RV64I-NEXT:    and a0, a0, s1
424; RV64I-NEXT:    call __gnu_h2f_ieee@plt
425; RV64I-NEXT:    mv a1, a0
426; RV64I-NEXT:    mv a0, s0
427; RV64I-NEXT:    call __eqsf2@plt
428; RV64I-NEXT:    seqz a0, a0
429; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
430; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
431; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
432; RV64I-NEXT:    addi sp, sp, 32
433; RV64I-NEXT:    ret
434  %1 = fadd half %a, %a
435  %2 = fneg half %1
436  %3 = fcmp oeq half %1, %2
437  %4 = zext i1 %3 to i32
438  ret i32 %4
439}
440
441; This function performs extra work to ensure that
442; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
443define half @fsgnjn_s(half %a, half %b) nounwind {
444; RV32IZFH-LABEL: fsgnjn_s:
445; RV32IZFH:       # %bb.0:
446; RV32IZFH-NEXT:    fadd.h ft0, fa0, fa1
447; RV32IZFH-NEXT:    fsgnjn.h fa0, fa0, ft0
448; RV32IZFH-NEXT:    ret
449;
450; RV64IZFH-LABEL: fsgnjn_s:
451; RV64IZFH:       # %bb.0:
452; RV64IZFH-NEXT:    fadd.h ft0, fa0, fa1
453; RV64IZFH-NEXT:    fsgnjn.h fa0, fa0, ft0
454; RV64IZFH-NEXT:    ret
455;
456; RV32I-LABEL: fsgnjn_s:
457; RV32I:       # %bb.0:
458; RV32I-NEXT:    addi sp, sp, -32
459; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
460; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
461; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
462; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
463; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
464; RV32I-NEXT:    mv s3, a1
465; RV32I-NEXT:    mv s2, a0
466; RV32I-NEXT:    lui a0, 16
467; RV32I-NEXT:    addi s0, a0, -1
468; RV32I-NEXT:    and a0, s2, s0
469; RV32I-NEXT:    call __gnu_h2f_ieee@plt
470; RV32I-NEXT:    mv s1, a0
471; RV32I-NEXT:    and a0, s3, s0
472; RV32I-NEXT:    call __gnu_h2f_ieee@plt
473; RV32I-NEXT:    mv a1, a0
474; RV32I-NEXT:    mv a0, s1
475; RV32I-NEXT:    call __addsf3@plt
476; RV32I-NEXT:    call __gnu_f2h_ieee@plt
477; RV32I-NEXT:    and a0, a0, s0
478; RV32I-NEXT:    call __gnu_h2f_ieee@plt
479; RV32I-NEXT:    lui a1, 524288
480; RV32I-NEXT:    xor a0, a0, a1
481; RV32I-NEXT:    call __gnu_f2h_ieee@plt
482; RV32I-NEXT:    lui a1, 1048568
483; RV32I-NEXT:    and a0, a0, a1
484; RV32I-NEXT:    slli a1, s2, 17
485; RV32I-NEXT:    srli a1, a1, 17
486; RV32I-NEXT:    or a0, a1, a0
487; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
488; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
489; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
490; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
491; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
492; RV32I-NEXT:    addi sp, sp, 32
493; RV32I-NEXT:    ret
494;
495; RV64I-LABEL: fsgnjn_s:
496; RV64I:       # %bb.0:
497; RV64I-NEXT:    addi sp, sp, -48
498; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
499; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
500; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
501; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
502; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
503; RV64I-NEXT:    mv s3, a1
504; RV64I-NEXT:    mv s2, a0
505; RV64I-NEXT:    lui a0, 16
506; RV64I-NEXT:    addiw s0, a0, -1
507; RV64I-NEXT:    and a0, s2, s0
508; RV64I-NEXT:    call __gnu_h2f_ieee@plt
509; RV64I-NEXT:    mv s1, a0
510; RV64I-NEXT:    and a0, s3, s0
511; RV64I-NEXT:    call __gnu_h2f_ieee@plt
512; RV64I-NEXT:    mv a1, a0
513; RV64I-NEXT:    mv a0, s1
514; RV64I-NEXT:    call __addsf3@plt
515; RV64I-NEXT:    call __gnu_f2h_ieee@plt
516; RV64I-NEXT:    and a0, a0, s0
517; RV64I-NEXT:    call __gnu_h2f_ieee@plt
518; RV64I-NEXT:    lui a1, 524288
519; RV64I-NEXT:    xor a0, a0, a1
520; RV64I-NEXT:    call __gnu_f2h_ieee@plt
521; RV64I-NEXT:    lui a1, 1048568
522; RV64I-NEXT:    and a0, a0, a1
523; RV64I-NEXT:    slli a1, s2, 49
524; RV64I-NEXT:    srli a1, a1, 49
525; RV64I-NEXT:    or a0, a1, a0
526; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
527; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
528; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
529; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
530; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
531; RV64I-NEXT:    addi sp, sp, 48
532; RV64I-NEXT:    ret
533  %1 = fadd half %a, %b
534  %2 = fneg half %1
535  %3 = call half @llvm.copysign.f16(half %a, half %2)
536  ret half %3
537}
538
539declare half @llvm.fabs.f16(half)
540
541; This function performs extra work to ensure that
542; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
543define half @fabs_s(half %a, half %b) nounwind {
544; RV32IZFH-LABEL: fabs_s:
545; RV32IZFH:       # %bb.0:
546; RV32IZFH-NEXT:    fadd.h ft0, fa0, fa1
547; RV32IZFH-NEXT:    fabs.h ft1, ft0
548; RV32IZFH-NEXT:    fadd.h fa0, ft1, ft0
549; RV32IZFH-NEXT:    ret
550;
551; RV64IZFH-LABEL: fabs_s:
552; RV64IZFH:       # %bb.0:
553; RV64IZFH-NEXT:    fadd.h ft0, fa0, fa1
554; RV64IZFH-NEXT:    fabs.h ft1, ft0
555; RV64IZFH-NEXT:    fadd.h fa0, ft1, ft0
556; RV64IZFH-NEXT:    ret
557;
558; RV32I-LABEL: fabs_s:
559; RV32I:       # %bb.0:
560; RV32I-NEXT:    addi sp, sp, -16
561; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
562; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
563; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
564; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
565; RV32I-NEXT:    mv s2, a1
566; RV32I-NEXT:    lui a1, 16
567; RV32I-NEXT:    addi s1, a1, -1
568; RV32I-NEXT:    and a0, a0, s1
569; RV32I-NEXT:    call __gnu_h2f_ieee@plt
570; RV32I-NEXT:    mv s0, a0
571; RV32I-NEXT:    and a0, s2, s1
572; RV32I-NEXT:    call __gnu_h2f_ieee@plt
573; RV32I-NEXT:    mv a1, a0
574; RV32I-NEXT:    mv a0, s0
575; RV32I-NEXT:    call __addsf3@plt
576; RV32I-NEXT:    call __gnu_f2h_ieee@plt
577; RV32I-NEXT:    and a0, a0, s1
578; RV32I-NEXT:    call __gnu_h2f_ieee@plt
579; RV32I-NEXT:    mv s0, a0
580; RV32I-NEXT:    slli a0, a0, 1
581; RV32I-NEXT:    srli a0, a0, 1
582; RV32I-NEXT:    call __gnu_f2h_ieee@plt
583; RV32I-NEXT:    and a0, a0, s1
584; RV32I-NEXT:    call __gnu_h2f_ieee@plt
585; RV32I-NEXT:    mv a1, s0
586; RV32I-NEXT:    call __addsf3@plt
587; RV32I-NEXT:    call __gnu_f2h_ieee@plt
588; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
589; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
590; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
591; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
592; RV32I-NEXT:    addi sp, sp, 16
593; RV32I-NEXT:    ret
594;
595; RV64I-LABEL: fabs_s:
596; RV64I:       # %bb.0:
597; RV64I-NEXT:    addi sp, sp, -32
598; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
599; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
600; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
601; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
602; RV64I-NEXT:    mv s2, a1
603; RV64I-NEXT:    lui a1, 16
604; RV64I-NEXT:    addiw s1, a1, -1
605; RV64I-NEXT:    and a0, a0, s1
606; RV64I-NEXT:    call __gnu_h2f_ieee@plt
607; RV64I-NEXT:    mv s0, a0
608; RV64I-NEXT:    and a0, s2, s1
609; RV64I-NEXT:    call __gnu_h2f_ieee@plt
610; RV64I-NEXT:    mv a1, a0
611; RV64I-NEXT:    mv a0, s0
612; RV64I-NEXT:    call __addsf3@plt
613; RV64I-NEXT:    call __gnu_f2h_ieee@plt
614; RV64I-NEXT:    and a0, a0, s1
615; RV64I-NEXT:    call __gnu_h2f_ieee@plt
616; RV64I-NEXT:    mv s0, a0
617; RV64I-NEXT:    slli a0, a0, 33
618; RV64I-NEXT:    srli a0, a0, 33
619; RV64I-NEXT:    call __gnu_f2h_ieee@plt
620; RV64I-NEXT:    and a0, a0, s1
621; RV64I-NEXT:    call __gnu_h2f_ieee@plt
622; RV64I-NEXT:    mv a1, s0
623; RV64I-NEXT:    call __addsf3@plt
624; RV64I-NEXT:    call __gnu_f2h_ieee@plt
625; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
626; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
627; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
628; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
629; RV64I-NEXT:    addi sp, sp, 32
630; RV64I-NEXT:    ret
631  %1 = fadd half %a, %b
632  %2 = call half @llvm.fabs.f16(half %1)
633  %3 = fadd half %2, %1
634  ret half %3
635}
636
637declare half @llvm.minnum.f16(half, half)
638
639define half @fmin_s(half %a, half %b) nounwind {
640; RV32IZFH-LABEL: fmin_s:
641; RV32IZFH:       # %bb.0:
642; RV32IZFH-NEXT:    fmin.h fa0, fa0, fa1
643; RV32IZFH-NEXT:    ret
644;
645; RV64IZFH-LABEL: fmin_s:
646; RV64IZFH:       # %bb.0:
647; RV64IZFH-NEXT:    fmin.h fa0, fa0, fa1
648; RV64IZFH-NEXT:    ret
649;
650; RV32I-LABEL: fmin_s:
651; RV32I:       # %bb.0:
652; RV32I-NEXT:    addi sp, sp, -16
653; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
654; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
655; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
656; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
657; RV32I-NEXT:    mv s2, a1
658; RV32I-NEXT:    lui a1, 16
659; RV32I-NEXT:    addi s0, a1, -1
660; RV32I-NEXT:    and a0, a0, s0
661; RV32I-NEXT:    call __gnu_h2f_ieee@plt
662; RV32I-NEXT:    mv s1, a0
663; RV32I-NEXT:    and a0, s2, s0
664; RV32I-NEXT:    call __gnu_h2f_ieee@plt
665; RV32I-NEXT:    mv a1, a0
666; RV32I-NEXT:    mv a0, s1
667; RV32I-NEXT:    call fminf@plt
668; RV32I-NEXT:    call __gnu_f2h_ieee@plt
669; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
670; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
671; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
672; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
673; RV32I-NEXT:    addi sp, sp, 16
674; RV32I-NEXT:    ret
675;
676; RV64I-LABEL: fmin_s:
677; RV64I:       # %bb.0:
678; RV64I-NEXT:    addi sp, sp, -32
679; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
680; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
681; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
682; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
683; RV64I-NEXT:    mv s2, a1
684; RV64I-NEXT:    lui a1, 16
685; RV64I-NEXT:    addiw s0, a1, -1
686; RV64I-NEXT:    and a0, a0, s0
687; RV64I-NEXT:    call __gnu_h2f_ieee@plt
688; RV64I-NEXT:    mv s1, a0
689; RV64I-NEXT:    and a0, s2, s0
690; RV64I-NEXT:    call __gnu_h2f_ieee@plt
691; RV64I-NEXT:    mv a1, a0
692; RV64I-NEXT:    mv a0, s1
693; RV64I-NEXT:    call fminf@plt
694; RV64I-NEXT:    call __gnu_f2h_ieee@plt
695; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
696; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
697; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
698; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
699; RV64I-NEXT:    addi sp, sp, 32
700; RV64I-NEXT:    ret
701  %1 = call half @llvm.minnum.f16(half %a, half %b)
702  ret half %1
703}
704
705declare half @llvm.maxnum.f16(half, half)
706
707define half @fmax_s(half %a, half %b) nounwind {
708; RV32IZFH-LABEL: fmax_s:
709; RV32IZFH:       # %bb.0:
710; RV32IZFH-NEXT:    fmax.h fa0, fa0, fa1
711; RV32IZFH-NEXT:    ret
712;
713; RV64IZFH-LABEL: fmax_s:
714; RV64IZFH:       # %bb.0:
715; RV64IZFH-NEXT:    fmax.h fa0, fa0, fa1
716; RV64IZFH-NEXT:    ret
717;
718; RV32I-LABEL: fmax_s:
719; RV32I:       # %bb.0:
720; RV32I-NEXT:    addi sp, sp, -16
721; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
722; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
723; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
724; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
725; RV32I-NEXT:    mv s2, a1
726; RV32I-NEXT:    lui a1, 16
727; RV32I-NEXT:    addi s0, a1, -1
728; RV32I-NEXT:    and a0, a0, s0
729; RV32I-NEXT:    call __gnu_h2f_ieee@plt
730; RV32I-NEXT:    mv s1, a0
731; RV32I-NEXT:    and a0, s2, s0
732; RV32I-NEXT:    call __gnu_h2f_ieee@plt
733; RV32I-NEXT:    mv a1, a0
734; RV32I-NEXT:    mv a0, s1
735; RV32I-NEXT:    call fmaxf@plt
736; RV32I-NEXT:    call __gnu_f2h_ieee@plt
737; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
738; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
739; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
740; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
741; RV32I-NEXT:    addi sp, sp, 16
742; RV32I-NEXT:    ret
743;
744; RV64I-LABEL: fmax_s:
745; RV64I:       # %bb.0:
746; RV64I-NEXT:    addi sp, sp, -32
747; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
748; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
749; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
750; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
751; RV64I-NEXT:    mv s2, a1
752; RV64I-NEXT:    lui a1, 16
753; RV64I-NEXT:    addiw s0, a1, -1
754; RV64I-NEXT:    and a0, a0, s0
755; RV64I-NEXT:    call __gnu_h2f_ieee@plt
756; RV64I-NEXT:    mv s1, a0
757; RV64I-NEXT:    and a0, s2, s0
758; RV64I-NEXT:    call __gnu_h2f_ieee@plt
759; RV64I-NEXT:    mv a1, a0
760; RV64I-NEXT:    mv a0, s1
761; RV64I-NEXT:    call fmaxf@plt
762; RV64I-NEXT:    call __gnu_f2h_ieee@plt
763; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
764; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
765; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
766; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
767; RV64I-NEXT:    addi sp, sp, 32
768; RV64I-NEXT:    ret
769  %1 = call half @llvm.maxnum.f16(half %a, half %b)
770  ret half %1
771}
772
773declare half @llvm.fma.f16(half, half, half)
774
775define half @fmadd_s(half %a, half %b, half %c) nounwind {
776; RV32IZFH-LABEL: fmadd_s:
777; RV32IZFH:       # %bb.0:
778; RV32IZFH-NEXT:    fmadd.h fa0, fa0, fa1, fa2
779; RV32IZFH-NEXT:    ret
780;
781; RV64IZFH-LABEL: fmadd_s:
782; RV64IZFH:       # %bb.0:
783; RV64IZFH-NEXT:    fmadd.h fa0, fa0, fa1, fa2
784; RV64IZFH-NEXT:    ret
785;
786; RV32I-LABEL: fmadd_s:
787; RV32I:       # %bb.0:
788; RV32I-NEXT:    addi sp, sp, -32
789; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
790; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
791; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
792; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
793; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
794; RV32I-NEXT:    mv s2, a2
795; RV32I-NEXT:    mv s1, a1
796; RV32I-NEXT:    lui a1, 16
797; RV32I-NEXT:    addi s0, a1, -1
798; RV32I-NEXT:    and a0, a0, s0
799; RV32I-NEXT:    call __gnu_h2f_ieee@plt
800; RV32I-NEXT:    mv s3, a0
801; RV32I-NEXT:    and a0, s1, s0
802; RV32I-NEXT:    call __gnu_h2f_ieee@plt
803; RV32I-NEXT:    mv s1, a0
804; RV32I-NEXT:    and a0, s2, s0
805; RV32I-NEXT:    call __gnu_h2f_ieee@plt
806; RV32I-NEXT:    mv a2, a0
807; RV32I-NEXT:    mv a0, s3
808; RV32I-NEXT:    mv a1, s1
809; RV32I-NEXT:    call fmaf@plt
810; RV32I-NEXT:    call __gnu_f2h_ieee@plt
811; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
812; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
813; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
814; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
815; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
816; RV32I-NEXT:    addi sp, sp, 32
817; RV32I-NEXT:    ret
818;
819; RV64I-LABEL: fmadd_s:
820; RV64I:       # %bb.0:
821; RV64I-NEXT:    addi sp, sp, -48
822; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
823; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
824; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
825; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
826; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
827; RV64I-NEXT:    mv s2, a2
828; RV64I-NEXT:    mv s1, a1
829; RV64I-NEXT:    lui a1, 16
830; RV64I-NEXT:    addiw s0, a1, -1
831; RV64I-NEXT:    and a0, a0, s0
832; RV64I-NEXT:    call __gnu_h2f_ieee@plt
833; RV64I-NEXT:    mv s3, a0
834; RV64I-NEXT:    and a0, s1, s0
835; RV64I-NEXT:    call __gnu_h2f_ieee@plt
836; RV64I-NEXT:    mv s1, a0
837; RV64I-NEXT:    and a0, s2, s0
838; RV64I-NEXT:    call __gnu_h2f_ieee@plt
839; RV64I-NEXT:    mv a2, a0
840; RV64I-NEXT:    mv a0, s3
841; RV64I-NEXT:    mv a1, s1
842; RV64I-NEXT:    call fmaf@plt
843; RV64I-NEXT:    call __gnu_f2h_ieee@plt
844; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
845; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
846; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
847; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
848; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
849; RV64I-NEXT:    addi sp, sp, 48
850; RV64I-NEXT:    ret
851  %1 = call half @llvm.fma.f16(half %a, half %b, half %c)
852  ret half %1
853}
854
855define half @fmsub_s(half %a, half %b, half %c) nounwind {
856; RV32IZFH-LABEL: fmsub_s:
857; RV32IZFH:       # %bb.0:
858; RV32IZFH-NEXT:    fmv.h.x ft0, zero
859; RV32IZFH-NEXT:    fadd.h ft0, fa2, ft0
860; RV32IZFH-NEXT:    fmsub.h fa0, fa0, fa1, ft0
861; RV32IZFH-NEXT:    ret
862;
863; RV64IZFH-LABEL: fmsub_s:
864; RV64IZFH:       # %bb.0:
865; RV64IZFH-NEXT:    fmv.h.x ft0, zero
866; RV64IZFH-NEXT:    fadd.h ft0, fa2, ft0
867; RV64IZFH-NEXT:    fmsub.h fa0, fa0, fa1, ft0
868; RV64IZFH-NEXT:    ret
869;
870; RV32I-LABEL: fmsub_s:
871; RV32I:       # %bb.0:
872; RV32I-NEXT:    addi sp, sp, -32
873; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
874; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
875; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
876; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
877; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
878; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
879; RV32I-NEXT:    mv s2, a1
880; RV32I-NEXT:    mv s1, a0
881; RV32I-NEXT:    lui a0, 16
882; RV32I-NEXT:    addi s0, a0, -1
883; RV32I-NEXT:    and a0, a2, s0
884; RV32I-NEXT:    call __gnu_h2f_ieee@plt
885; RV32I-NEXT:    li a1, 0
886; RV32I-NEXT:    call __addsf3@plt
887; RV32I-NEXT:    call __gnu_f2h_ieee@plt
888; RV32I-NEXT:    and a0, a0, s0
889; RV32I-NEXT:    call __gnu_h2f_ieee@plt
890; RV32I-NEXT:    lui a1, 524288
891; RV32I-NEXT:    xor a0, a0, a1
892; RV32I-NEXT:    call __gnu_f2h_ieee@plt
893; RV32I-NEXT:    mv s4, a0
894; RV32I-NEXT:    and a0, s1, s0
895; RV32I-NEXT:    call __gnu_h2f_ieee@plt
896; RV32I-NEXT:    mv s3, a0
897; RV32I-NEXT:    and a0, s2, s0
898; RV32I-NEXT:    call __gnu_h2f_ieee@plt
899; RV32I-NEXT:    mv s1, a0
900; RV32I-NEXT:    and a0, s4, s0
901; RV32I-NEXT:    call __gnu_h2f_ieee@plt
902; RV32I-NEXT:    mv a2, a0
903; RV32I-NEXT:    mv a0, s3
904; RV32I-NEXT:    mv a1, s1
905; RV32I-NEXT:    call fmaf@plt
906; RV32I-NEXT:    call __gnu_f2h_ieee@plt
907; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
908; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
909; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
910; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
911; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
912; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
913; RV32I-NEXT:    addi sp, sp, 32
914; RV32I-NEXT:    ret
915;
916; RV64I-LABEL: fmsub_s:
917; RV64I:       # %bb.0:
918; RV64I-NEXT:    addi sp, sp, -48
919; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
920; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
921; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
922; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
923; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
924; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
925; RV64I-NEXT:    mv s2, a1
926; RV64I-NEXT:    mv s1, a0
927; RV64I-NEXT:    lui a0, 16
928; RV64I-NEXT:    addiw s0, a0, -1
929; RV64I-NEXT:    and a0, a2, s0
930; RV64I-NEXT:    call __gnu_h2f_ieee@plt
931; RV64I-NEXT:    li a1, 0
932; RV64I-NEXT:    call __addsf3@plt
933; RV64I-NEXT:    call __gnu_f2h_ieee@plt
934; RV64I-NEXT:    and a0, a0, s0
935; RV64I-NEXT:    call __gnu_h2f_ieee@plt
936; RV64I-NEXT:    lui a1, 524288
937; RV64I-NEXT:    xor a0, a0, a1
938; RV64I-NEXT:    call __gnu_f2h_ieee@plt
939; RV64I-NEXT:    mv s4, a0
940; RV64I-NEXT:    and a0, s1, s0
941; RV64I-NEXT:    call __gnu_h2f_ieee@plt
942; RV64I-NEXT:    mv s3, a0
943; RV64I-NEXT:    and a0, s2, s0
944; RV64I-NEXT:    call __gnu_h2f_ieee@plt
945; RV64I-NEXT:    mv s1, a0
946; RV64I-NEXT:    and a0, s4, s0
947; RV64I-NEXT:    call __gnu_h2f_ieee@plt
948; RV64I-NEXT:    mv a2, a0
949; RV64I-NEXT:    mv a0, s3
950; RV64I-NEXT:    mv a1, s1
951; RV64I-NEXT:    call fmaf@plt
952; RV64I-NEXT:    call __gnu_f2h_ieee@plt
953; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
954; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
955; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
956; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
957; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
958; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
959; RV64I-NEXT:    addi sp, sp, 48
960; RV64I-NEXT:    ret
961  %c_ = fadd half 0.0, %c ; avoid negation using xor
962  %negc = fsub half -0.0, %c_
963  %1 = call half @llvm.fma.f16(half %a, half %b, half %negc)
964  ret half %1
965}
966
967define half @fnmadd_s(half %a, half %b, half %c) nounwind {
968; RV32IZFH-LABEL: fnmadd_s:
969; RV32IZFH:       # %bb.0:
970; RV32IZFH-NEXT:    fmv.h.x ft0, zero
971; RV32IZFH-NEXT:    fadd.h ft1, fa0, ft0
972; RV32IZFH-NEXT:    fadd.h ft0, fa2, ft0
973; RV32IZFH-NEXT:    fnmadd.h fa0, ft1, fa1, ft0
974; RV32IZFH-NEXT:    ret
975;
976; RV64IZFH-LABEL: fnmadd_s:
977; RV64IZFH:       # %bb.0:
978; RV64IZFH-NEXT:    fmv.h.x ft0, zero
979; RV64IZFH-NEXT:    fadd.h ft1, fa0, ft0
980; RV64IZFH-NEXT:    fadd.h ft0, fa2, ft0
981; RV64IZFH-NEXT:    fnmadd.h fa0, ft1, fa1, ft0
982; RV64IZFH-NEXT:    ret
983;
984; RV32I-LABEL: fnmadd_s:
985; RV32I:       # %bb.0:
986; RV32I-NEXT:    addi sp, sp, -32
987; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
988; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
989; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
990; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
991; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
992; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
993; RV32I-NEXT:    mv s3, a2
994; RV32I-NEXT:    mv s2, a1
995; RV32I-NEXT:    lui a1, 16
996; RV32I-NEXT:    addi s1, a1, -1
997; RV32I-NEXT:    and a0, a0, s1
998; RV32I-NEXT:    call __gnu_h2f_ieee@plt
999; RV32I-NEXT:    li a1, 0
1000; RV32I-NEXT:    call __addsf3@plt
1001; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1002; RV32I-NEXT:    mv s4, a0
1003; RV32I-NEXT:    and a0, s3, s1
1004; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1005; RV32I-NEXT:    li a1, 0
1006; RV32I-NEXT:    call __addsf3@plt
1007; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1008; RV32I-NEXT:    mv s0, a0
1009; RV32I-NEXT:    and a0, s4, s1
1010; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1011; RV32I-NEXT:    lui s4, 524288
1012; RV32I-NEXT:    xor a0, a0, s4
1013; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1014; RV32I-NEXT:    mv s3, a0
1015; RV32I-NEXT:    and a0, s0, s1
1016; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1017; RV32I-NEXT:    xor a0, a0, s4
1018; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1019; RV32I-NEXT:    mv s4, a0
1020; RV32I-NEXT:    and a0, s2, s1
1021; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1022; RV32I-NEXT:    mv s2, a0
1023; RV32I-NEXT:    and a0, s3, s1
1024; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1025; RV32I-NEXT:    mv s0, a0
1026; RV32I-NEXT:    and a0, s4, s1
1027; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1028; RV32I-NEXT:    mv a2, a0
1029; RV32I-NEXT:    mv a0, s0
1030; RV32I-NEXT:    mv a1, s2
1031; RV32I-NEXT:    call fmaf@plt
1032; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1033; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1034; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1035; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1036; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1037; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1038; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1039; RV32I-NEXT:    addi sp, sp, 32
1040; RV32I-NEXT:    ret
1041;
1042; RV64I-LABEL: fnmadd_s:
1043; RV64I:       # %bb.0:
1044; RV64I-NEXT:    addi sp, sp, -48
1045; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1046; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1047; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1048; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1049; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1050; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1051; RV64I-NEXT:    mv s3, a2
1052; RV64I-NEXT:    mv s2, a1
1053; RV64I-NEXT:    lui a1, 16
1054; RV64I-NEXT:    addiw s1, a1, -1
1055; RV64I-NEXT:    and a0, a0, s1
1056; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1057; RV64I-NEXT:    li a1, 0
1058; RV64I-NEXT:    call __addsf3@plt
1059; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1060; RV64I-NEXT:    mv s4, a0
1061; RV64I-NEXT:    and a0, s3, s1
1062; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1063; RV64I-NEXT:    li a1, 0
1064; RV64I-NEXT:    call __addsf3@plt
1065; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1066; RV64I-NEXT:    mv s0, a0
1067; RV64I-NEXT:    and a0, s4, s1
1068; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1069; RV64I-NEXT:    lui s4, 524288
1070; RV64I-NEXT:    xor a0, a0, s4
1071; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1072; RV64I-NEXT:    mv s3, a0
1073; RV64I-NEXT:    and a0, s0, s1
1074; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1075; RV64I-NEXT:    xor a0, a0, s4
1076; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1077; RV64I-NEXT:    mv s4, a0
1078; RV64I-NEXT:    and a0, s2, s1
1079; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1080; RV64I-NEXT:    mv s2, a0
1081; RV64I-NEXT:    and a0, s3, s1
1082; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1083; RV64I-NEXT:    mv s0, a0
1084; RV64I-NEXT:    and a0, s4, s1
1085; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1086; RV64I-NEXT:    mv a2, a0
1087; RV64I-NEXT:    mv a0, s0
1088; RV64I-NEXT:    mv a1, s2
1089; RV64I-NEXT:    call fmaf@plt
1090; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1091; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1092; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1093; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1094; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1095; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1096; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1097; RV64I-NEXT:    addi sp, sp, 48
1098; RV64I-NEXT:    ret
1099  %a_ = fadd half 0.0, %a
1100  %c_ = fadd half 0.0, %c
1101  %nega = fsub half -0.0, %a_
1102  %negc = fsub half -0.0, %c_
1103  %1 = call half @llvm.fma.f16(half %nega, half %b, half %negc)
1104  ret half %1
1105}
1106
1107define half @fnmadd_s_2(half %a, half %b, half %c) nounwind {
1108; RV32IZFH-LABEL: fnmadd_s_2:
1109; RV32IZFH:       # %bb.0:
1110; RV32IZFH-NEXT:    fmv.h.x ft0, zero
1111; RV32IZFH-NEXT:    fadd.h ft1, fa1, ft0
1112; RV32IZFH-NEXT:    fadd.h ft0, fa2, ft0
1113; RV32IZFH-NEXT:    fnmadd.h fa0, ft1, fa0, ft0
1114; RV32IZFH-NEXT:    ret
1115;
1116; RV64IZFH-LABEL: fnmadd_s_2:
1117; RV64IZFH:       # %bb.0:
1118; RV64IZFH-NEXT:    fmv.h.x ft0, zero
1119; RV64IZFH-NEXT:    fadd.h ft1, fa1, ft0
1120; RV64IZFH-NEXT:    fadd.h ft0, fa2, ft0
1121; RV64IZFH-NEXT:    fnmadd.h fa0, ft1, fa0, ft0
1122; RV64IZFH-NEXT:    ret
1123;
1124; RV32I-LABEL: fnmadd_s_2:
1125; RV32I:       # %bb.0:
1126; RV32I-NEXT:    addi sp, sp, -32
1127; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1128; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1129; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1130; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1131; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1132; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1133; RV32I-NEXT:    mv s3, a2
1134; RV32I-NEXT:    mv s2, a0
1135; RV32I-NEXT:    lui a0, 16
1136; RV32I-NEXT:    addi s1, a0, -1
1137; RV32I-NEXT:    and a0, a1, s1
1138; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1139; RV32I-NEXT:    li a1, 0
1140; RV32I-NEXT:    call __addsf3@plt
1141; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1142; RV32I-NEXT:    mv s4, a0
1143; RV32I-NEXT:    and a0, s3, s1
1144; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1145; RV32I-NEXT:    li a1, 0
1146; RV32I-NEXT:    call __addsf3@plt
1147; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1148; RV32I-NEXT:    mv s0, a0
1149; RV32I-NEXT:    and a0, s4, s1
1150; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1151; RV32I-NEXT:    lui s4, 524288
1152; RV32I-NEXT:    xor a0, a0, s4
1153; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1154; RV32I-NEXT:    mv s3, a0
1155; RV32I-NEXT:    and a0, s0, s1
1156; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1157; RV32I-NEXT:    xor a0, a0, s4
1158; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1159; RV32I-NEXT:    mv s4, a0
1160; RV32I-NEXT:    and a0, s2, s1
1161; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1162; RV32I-NEXT:    mv s2, a0
1163; RV32I-NEXT:    and a0, s3, s1
1164; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1165; RV32I-NEXT:    mv s0, a0
1166; RV32I-NEXT:    and a0, s4, s1
1167; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1168; RV32I-NEXT:    mv a2, a0
1169; RV32I-NEXT:    mv a0, s2
1170; RV32I-NEXT:    mv a1, s0
1171; RV32I-NEXT:    call fmaf@plt
1172; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1173; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1174; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1175; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1176; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1177; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1178; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1179; RV32I-NEXT:    addi sp, sp, 32
1180; RV32I-NEXT:    ret
1181;
1182; RV64I-LABEL: fnmadd_s_2:
1183; RV64I:       # %bb.0:
1184; RV64I-NEXT:    addi sp, sp, -48
1185; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1186; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1187; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1188; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1189; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1190; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1191; RV64I-NEXT:    mv s3, a2
1192; RV64I-NEXT:    mv s2, a0
1193; RV64I-NEXT:    lui a0, 16
1194; RV64I-NEXT:    addiw s1, a0, -1
1195; RV64I-NEXT:    and a0, a1, s1
1196; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1197; RV64I-NEXT:    li a1, 0
1198; RV64I-NEXT:    call __addsf3@plt
1199; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1200; RV64I-NEXT:    mv s4, a0
1201; RV64I-NEXT:    and a0, s3, s1
1202; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1203; RV64I-NEXT:    li a1, 0
1204; RV64I-NEXT:    call __addsf3@plt
1205; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1206; RV64I-NEXT:    mv s0, a0
1207; RV64I-NEXT:    and a0, s4, s1
1208; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1209; RV64I-NEXT:    lui s4, 524288
1210; RV64I-NEXT:    xor a0, a0, s4
1211; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1212; RV64I-NEXT:    mv s3, a0
1213; RV64I-NEXT:    and a0, s0, s1
1214; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1215; RV64I-NEXT:    xor a0, a0, s4
1216; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1217; RV64I-NEXT:    mv s4, a0
1218; RV64I-NEXT:    and a0, s2, s1
1219; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1220; RV64I-NEXT:    mv s2, a0
1221; RV64I-NEXT:    and a0, s3, s1
1222; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1223; RV64I-NEXT:    mv s0, a0
1224; RV64I-NEXT:    and a0, s4, s1
1225; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1226; RV64I-NEXT:    mv a2, a0
1227; RV64I-NEXT:    mv a0, s2
1228; RV64I-NEXT:    mv a1, s0
1229; RV64I-NEXT:    call fmaf@plt
1230; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1231; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1232; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1233; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1234; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1235; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1236; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1237; RV64I-NEXT:    addi sp, sp, 48
1238; RV64I-NEXT:    ret
1239  %b_ = fadd half 0.0, %b
1240  %c_ = fadd half 0.0, %c
1241  %negb = fsub half -0.0, %b_
1242  %negc = fsub half -0.0, %c_
1243  %1 = call half @llvm.fma.f16(half %a, half %negb, half %negc)
1244  ret half %1
1245}
1246
1247define half @fnmsub_s(half %a, half %b, half %c) nounwind {
1248; RV32IZFH-LABEL: fnmsub_s:
1249; RV32IZFH:       # %bb.0:
1250; RV32IZFH-NEXT:    fmv.h.x ft0, zero
1251; RV32IZFH-NEXT:    fadd.h ft0, fa0, ft0
1252; RV32IZFH-NEXT:    fnmsub.h fa0, ft0, fa1, fa2
1253; RV32IZFH-NEXT:    ret
1254;
1255; RV64IZFH-LABEL: fnmsub_s:
1256; RV64IZFH:       # %bb.0:
1257; RV64IZFH-NEXT:    fmv.h.x ft0, zero
1258; RV64IZFH-NEXT:    fadd.h ft0, fa0, ft0
1259; RV64IZFH-NEXT:    fnmsub.h fa0, ft0, fa1, fa2
1260; RV64IZFH-NEXT:    ret
1261;
1262; RV32I-LABEL: fnmsub_s:
1263; RV32I:       # %bb.0:
1264; RV32I-NEXT:    addi sp, sp, -32
1265; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1266; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1267; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1268; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1269; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1270; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1271; RV32I-NEXT:    mv s2, a2
1272; RV32I-NEXT:    mv s1, a1
1273; RV32I-NEXT:    lui a1, 16
1274; RV32I-NEXT:    addi s0, a1, -1
1275; RV32I-NEXT:    and a0, a0, s0
1276; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1277; RV32I-NEXT:    li a1, 0
1278; RV32I-NEXT:    call __addsf3@plt
1279; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1280; RV32I-NEXT:    and a0, a0, s0
1281; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1282; RV32I-NEXT:    lui a1, 524288
1283; RV32I-NEXT:    xor a0, a0, a1
1284; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1285; RV32I-NEXT:    mv s4, a0
1286; RV32I-NEXT:    and a0, s1, s0
1287; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1288; RV32I-NEXT:    mv s3, a0
1289; RV32I-NEXT:    and a0, s2, s0
1290; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1291; RV32I-NEXT:    mv s1, a0
1292; RV32I-NEXT:    and a0, s4, s0
1293; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1294; RV32I-NEXT:    mv a1, s3
1295; RV32I-NEXT:    mv a2, s1
1296; RV32I-NEXT:    call fmaf@plt
1297; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1298; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1299; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1300; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1301; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1302; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1303; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1304; RV32I-NEXT:    addi sp, sp, 32
1305; RV32I-NEXT:    ret
1306;
1307; RV64I-LABEL: fnmsub_s:
1308; RV64I:       # %bb.0:
1309; RV64I-NEXT:    addi sp, sp, -48
1310; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1311; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1312; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1313; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1314; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1315; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1316; RV64I-NEXT:    mv s2, a2
1317; RV64I-NEXT:    mv s1, a1
1318; RV64I-NEXT:    lui a1, 16
1319; RV64I-NEXT:    addiw s0, a1, -1
1320; RV64I-NEXT:    and a0, a0, s0
1321; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1322; RV64I-NEXT:    li a1, 0
1323; RV64I-NEXT:    call __addsf3@plt
1324; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1325; RV64I-NEXT:    and a0, a0, s0
1326; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1327; RV64I-NEXT:    lui a1, 524288
1328; RV64I-NEXT:    xor a0, a0, a1
1329; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1330; RV64I-NEXT:    mv s4, a0
1331; RV64I-NEXT:    and a0, s1, s0
1332; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1333; RV64I-NEXT:    mv s3, a0
1334; RV64I-NEXT:    and a0, s2, s0
1335; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1336; RV64I-NEXT:    mv s1, a0
1337; RV64I-NEXT:    and a0, s4, s0
1338; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1339; RV64I-NEXT:    mv a1, s3
1340; RV64I-NEXT:    mv a2, s1
1341; RV64I-NEXT:    call fmaf@plt
1342; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1343; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1344; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1345; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1346; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1347; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1348; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1349; RV64I-NEXT:    addi sp, sp, 48
1350; RV64I-NEXT:    ret
1351  %a_ = fadd half 0.0, %a
1352  %nega = fsub half -0.0, %a_
1353  %1 = call half @llvm.fma.f16(half %nega, half %b, half %c)
1354  ret half %1
1355}
1356
1357define half @fnmsub_s_2(half %a, half %b, half %c) nounwind {
1358; RV32IZFH-LABEL: fnmsub_s_2:
1359; RV32IZFH:       # %bb.0:
1360; RV32IZFH-NEXT:    fmv.h.x ft0, zero
1361; RV32IZFH-NEXT:    fadd.h ft0, fa1, ft0
1362; RV32IZFH-NEXT:    fnmsub.h fa0, ft0, fa0, fa2
1363; RV32IZFH-NEXT:    ret
1364;
1365; RV64IZFH-LABEL: fnmsub_s_2:
1366; RV64IZFH:       # %bb.0:
1367; RV64IZFH-NEXT:    fmv.h.x ft0, zero
1368; RV64IZFH-NEXT:    fadd.h ft0, fa1, ft0
1369; RV64IZFH-NEXT:    fnmsub.h fa0, ft0, fa0, fa2
1370; RV64IZFH-NEXT:    ret
1371;
1372; RV32I-LABEL: fnmsub_s_2:
1373; RV32I:       # %bb.0:
1374; RV32I-NEXT:    addi sp, sp, -32
1375; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1376; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1377; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1378; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1379; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1380; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1381; RV32I-NEXT:    mv s2, a2
1382; RV32I-NEXT:    mv s1, a0
1383; RV32I-NEXT:    lui a0, 16
1384; RV32I-NEXT:    addi s0, a0, -1
1385; RV32I-NEXT:    and a0, a1, s0
1386; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1387; RV32I-NEXT:    li a1, 0
1388; RV32I-NEXT:    call __addsf3@plt
1389; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1390; RV32I-NEXT:    and a0, a0, s0
1391; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1392; RV32I-NEXT:    lui a1, 524288
1393; RV32I-NEXT:    xor a0, a0, a1
1394; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1395; RV32I-NEXT:    mv s4, a0
1396; RV32I-NEXT:    and a0, s1, s0
1397; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1398; RV32I-NEXT:    mv s3, a0
1399; RV32I-NEXT:    and a0, s2, s0
1400; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1401; RV32I-NEXT:    mv s1, a0
1402; RV32I-NEXT:    and a0, s4, s0
1403; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1404; RV32I-NEXT:    mv a1, a0
1405; RV32I-NEXT:    mv a0, s3
1406; RV32I-NEXT:    mv a2, s1
1407; RV32I-NEXT:    call fmaf@plt
1408; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1409; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1410; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1411; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1412; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1413; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1414; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1415; RV32I-NEXT:    addi sp, sp, 32
1416; RV32I-NEXT:    ret
1417;
1418; RV64I-LABEL: fnmsub_s_2:
1419; RV64I:       # %bb.0:
1420; RV64I-NEXT:    addi sp, sp, -48
1421; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1422; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1423; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1424; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1425; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1426; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1427; RV64I-NEXT:    mv s2, a2
1428; RV64I-NEXT:    mv s1, a0
1429; RV64I-NEXT:    lui a0, 16
1430; RV64I-NEXT:    addiw s0, a0, -1
1431; RV64I-NEXT:    and a0, a1, s0
1432; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1433; RV64I-NEXT:    li a1, 0
1434; RV64I-NEXT:    call __addsf3@plt
1435; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1436; RV64I-NEXT:    and a0, a0, s0
1437; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1438; RV64I-NEXT:    lui a1, 524288
1439; RV64I-NEXT:    xor a0, a0, a1
1440; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1441; RV64I-NEXT:    mv s4, a0
1442; RV64I-NEXT:    and a0, s1, s0
1443; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1444; RV64I-NEXT:    mv s3, a0
1445; RV64I-NEXT:    and a0, s2, s0
1446; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1447; RV64I-NEXT:    mv s1, a0
1448; RV64I-NEXT:    and a0, s4, s0
1449; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1450; RV64I-NEXT:    mv a1, a0
1451; RV64I-NEXT:    mv a0, s3
1452; RV64I-NEXT:    mv a2, s1
1453; RV64I-NEXT:    call fmaf@plt
1454; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1455; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1456; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1457; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1458; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1459; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1460; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1461; RV64I-NEXT:    addi sp, sp, 48
1462; RV64I-NEXT:    ret
1463  %b_ = fadd half 0.0, %b
1464  %negb = fsub half -0.0, %b_
1465  %1 = call half @llvm.fma.f16(half %a, half %negb, half %c)
1466  ret half %1
1467}
1468
1469define half @fmadd_s_contract(half %a, half %b, half %c) nounwind {
1470; RV32IZFH-LABEL: fmadd_s_contract:
1471; RV32IZFH:       # %bb.0:
1472; RV32IZFH-NEXT:    fmadd.h fa0, fa0, fa1, fa2
1473; RV32IZFH-NEXT:    ret
1474;
1475; RV64IZFH-LABEL: fmadd_s_contract:
1476; RV64IZFH:       # %bb.0:
1477; RV64IZFH-NEXT:    fmadd.h fa0, fa0, fa1, fa2
1478; RV64IZFH-NEXT:    ret
1479;
1480; RV32I-LABEL: fmadd_s_contract:
1481; RV32I:       # %bb.0:
1482; RV32I-NEXT:    addi sp, sp, -32
1483; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1484; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1485; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1486; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1487; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1488; RV32I-NEXT:    mv s2, a2
1489; RV32I-NEXT:    mv s3, a1
1490; RV32I-NEXT:    lui a1, 16
1491; RV32I-NEXT:    addi s1, a1, -1
1492; RV32I-NEXT:    and a0, a0, s1
1493; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1494; RV32I-NEXT:    mv s0, a0
1495; RV32I-NEXT:    and a0, s3, s1
1496; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1497; RV32I-NEXT:    mv a1, a0
1498; RV32I-NEXT:    mv a0, s0
1499; RV32I-NEXT:    call __mulsf3@plt
1500; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1501; RV32I-NEXT:    mv s0, a0
1502; RV32I-NEXT:    and a0, s2, s1
1503; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1504; RV32I-NEXT:    mv s2, a0
1505; RV32I-NEXT:    and a0, s0, s1
1506; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1507; RV32I-NEXT:    mv a1, s2
1508; RV32I-NEXT:    call __addsf3@plt
1509; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1510; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1511; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1512; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1513; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1514; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1515; RV32I-NEXT:    addi sp, sp, 32
1516; RV32I-NEXT:    ret
1517;
1518; RV64I-LABEL: fmadd_s_contract:
1519; RV64I:       # %bb.0:
1520; RV64I-NEXT:    addi sp, sp, -48
1521; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1522; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1523; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1524; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1525; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1526; RV64I-NEXT:    mv s2, a2
1527; RV64I-NEXT:    mv s3, a1
1528; RV64I-NEXT:    lui a1, 16
1529; RV64I-NEXT:    addiw s1, a1, -1
1530; RV64I-NEXT:    and a0, a0, s1
1531; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1532; RV64I-NEXT:    mv s0, a0
1533; RV64I-NEXT:    and a0, s3, s1
1534; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1535; RV64I-NEXT:    mv a1, a0
1536; RV64I-NEXT:    mv a0, s0
1537; RV64I-NEXT:    call __mulsf3@plt
1538; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1539; RV64I-NEXT:    mv s0, a0
1540; RV64I-NEXT:    and a0, s2, s1
1541; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1542; RV64I-NEXT:    mv s2, a0
1543; RV64I-NEXT:    and a0, s0, s1
1544; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1545; RV64I-NEXT:    mv a1, s2
1546; RV64I-NEXT:    call __addsf3@plt
1547; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1548; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1549; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1550; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1551; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1552; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1553; RV64I-NEXT:    addi sp, sp, 48
1554; RV64I-NEXT:    ret
1555  %1 = fmul contract half %a, %b
1556  %2 = fadd contract half %1, %c
1557  ret half %2
1558}
1559
1560define half @fmsub_s_contract(half %a, half %b, half %c) nounwind {
1561; RV32IZFH-LABEL: fmsub_s_contract:
1562; RV32IZFH:       # %bb.0:
1563; RV32IZFH-NEXT:    fmv.h.x ft0, zero
1564; RV32IZFH-NEXT:    fadd.h ft0, fa2, ft0
1565; RV32IZFH-NEXT:    fmsub.h fa0, fa0, fa1, ft0
1566; RV32IZFH-NEXT:    ret
1567;
1568; RV64IZFH-LABEL: fmsub_s_contract:
1569; RV64IZFH:       # %bb.0:
1570; RV64IZFH-NEXT:    fmv.h.x ft0, zero
1571; RV64IZFH-NEXT:    fadd.h ft0, fa2, ft0
1572; RV64IZFH-NEXT:    fmsub.h fa0, fa0, fa1, ft0
1573; RV64IZFH-NEXT:    ret
1574;
1575; RV32I-LABEL: fmsub_s_contract:
1576; RV32I:       # %bb.0:
1577; RV32I-NEXT:    addi sp, sp, -32
1578; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1579; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1580; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1581; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1582; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1583; RV32I-NEXT:    mv s3, a1
1584; RV32I-NEXT:    mv s1, a0
1585; RV32I-NEXT:    lui a0, 16
1586; RV32I-NEXT:    addi s0, a0, -1
1587; RV32I-NEXT:    and a0, a2, s0
1588; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1589; RV32I-NEXT:    li a1, 0
1590; RV32I-NEXT:    call __addsf3@plt
1591; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1592; RV32I-NEXT:    mv s2, a0
1593; RV32I-NEXT:    and a0, s1, s0
1594; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1595; RV32I-NEXT:    mv s1, a0
1596; RV32I-NEXT:    and a0, s3, s0
1597; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1598; RV32I-NEXT:    mv a1, a0
1599; RV32I-NEXT:    mv a0, s1
1600; RV32I-NEXT:    call __mulsf3@plt
1601; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1602; RV32I-NEXT:    and a0, a0, s0
1603; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1604; RV32I-NEXT:    mv s1, a0
1605; RV32I-NEXT:    and a0, s2, s0
1606; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1607; RV32I-NEXT:    mv a1, a0
1608; RV32I-NEXT:    mv a0, s1
1609; RV32I-NEXT:    call __subsf3@plt
1610; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1611; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1612; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1613; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1614; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1615; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1616; RV32I-NEXT:    addi sp, sp, 32
1617; RV32I-NEXT:    ret
1618;
1619; RV64I-LABEL: fmsub_s_contract:
1620; RV64I:       # %bb.0:
1621; RV64I-NEXT:    addi sp, sp, -48
1622; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1623; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1624; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1625; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1626; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1627; RV64I-NEXT:    mv s3, a1
1628; RV64I-NEXT:    mv s1, a0
1629; RV64I-NEXT:    lui a0, 16
1630; RV64I-NEXT:    addiw s0, a0, -1
1631; RV64I-NEXT:    and a0, a2, s0
1632; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1633; RV64I-NEXT:    li a1, 0
1634; RV64I-NEXT:    call __addsf3@plt
1635; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1636; RV64I-NEXT:    mv s2, a0
1637; RV64I-NEXT:    and a0, s1, s0
1638; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1639; RV64I-NEXT:    mv s1, a0
1640; RV64I-NEXT:    and a0, s3, s0
1641; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1642; RV64I-NEXT:    mv a1, a0
1643; RV64I-NEXT:    mv a0, s1
1644; RV64I-NEXT:    call __mulsf3@plt
1645; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1646; RV64I-NEXT:    and a0, a0, s0
1647; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1648; RV64I-NEXT:    mv s1, a0
1649; RV64I-NEXT:    and a0, s2, s0
1650; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1651; RV64I-NEXT:    mv a1, a0
1652; RV64I-NEXT:    mv a0, s1
1653; RV64I-NEXT:    call __subsf3@plt
1654; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1655; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1656; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1657; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1658; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1659; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1660; RV64I-NEXT:    addi sp, sp, 48
1661; RV64I-NEXT:    ret
1662  %c_ = fadd half 0.0, %c ; avoid negation using xor
1663  %1 = fmul contract half %a, %b
1664  %2 = fsub contract half %1, %c_
1665  ret half %2
1666}
1667
1668define half @fnmadd_s_contract(half %a, half %b, half %c) nounwind {
1669; RV32IZFH-LABEL: fnmadd_s_contract:
1670; RV32IZFH:       # %bb.0:
1671; RV32IZFH-NEXT:    fmv.h.x ft0, zero
1672; RV32IZFH-NEXT:    fadd.h ft1, fa0, ft0
1673; RV32IZFH-NEXT:    fadd.h ft2, fa1, ft0
1674; RV32IZFH-NEXT:    fadd.h ft0, fa2, ft0
1675; RV32IZFH-NEXT:    fnmadd.h fa0, ft1, ft2, ft0
1676; RV32IZFH-NEXT:    ret
1677;
1678; RV64IZFH-LABEL: fnmadd_s_contract:
1679; RV64IZFH:       # %bb.0:
1680; RV64IZFH-NEXT:    fmv.h.x ft0, zero
1681; RV64IZFH-NEXT:    fadd.h ft1, fa0, ft0
1682; RV64IZFH-NEXT:    fadd.h ft2, fa1, ft0
1683; RV64IZFH-NEXT:    fadd.h ft0, fa2, ft0
1684; RV64IZFH-NEXT:    fnmadd.h fa0, ft1, ft2, ft0
1685; RV64IZFH-NEXT:    ret
1686;
1687; RV32I-LABEL: fnmadd_s_contract:
1688; RV32I:       # %bb.0:
1689; RV32I-NEXT:    addi sp, sp, -32
1690; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1691; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1692; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1693; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1694; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1695; RV32I-NEXT:    sw s4, 8(sp) # 4-byte Folded Spill
1696; RV32I-NEXT:    mv s2, a2
1697; RV32I-NEXT:    mv s0, a1
1698; RV32I-NEXT:    lui a1, 16
1699; RV32I-NEXT:    addi s1, a1, -1
1700; RV32I-NEXT:    and a0, a0, s1
1701; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1702; RV32I-NEXT:    li a1, 0
1703; RV32I-NEXT:    call __addsf3@plt
1704; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1705; RV32I-NEXT:    mv s3, a0
1706; RV32I-NEXT:    and a0, s0, s1
1707; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1708; RV32I-NEXT:    li a1, 0
1709; RV32I-NEXT:    call __addsf3@plt
1710; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1711; RV32I-NEXT:    mv s4, a0
1712; RV32I-NEXT:    and a0, s2, s1
1713; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1714; RV32I-NEXT:    li a1, 0
1715; RV32I-NEXT:    call __addsf3@plt
1716; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1717; RV32I-NEXT:    mv s2, a0
1718; RV32I-NEXT:    and a0, s3, s1
1719; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1720; RV32I-NEXT:    mv s0, a0
1721; RV32I-NEXT:    and a0, s4, s1
1722; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1723; RV32I-NEXT:    mv a1, a0
1724; RV32I-NEXT:    mv a0, s0
1725; RV32I-NEXT:    call __mulsf3@plt
1726; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1727; RV32I-NEXT:    and a0, a0, s1
1728; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1729; RV32I-NEXT:    lui a1, 524288
1730; RV32I-NEXT:    xor a0, a0, a1
1731; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1732; RV32I-NEXT:    mv s0, a0
1733; RV32I-NEXT:    and a0, s2, s1
1734; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1735; RV32I-NEXT:    mv s2, a0
1736; RV32I-NEXT:    and a0, s0, s1
1737; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1738; RV32I-NEXT:    mv a1, s2
1739; RV32I-NEXT:    call __subsf3@plt
1740; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1741; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1742; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1743; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1744; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1745; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1746; RV32I-NEXT:    lw s4, 8(sp) # 4-byte Folded Reload
1747; RV32I-NEXT:    addi sp, sp, 32
1748; RV32I-NEXT:    ret
1749;
1750; RV64I-LABEL: fnmadd_s_contract:
1751; RV64I:       # %bb.0:
1752; RV64I-NEXT:    addi sp, sp, -48
1753; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1754; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1755; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1756; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1757; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1758; RV64I-NEXT:    sd s4, 0(sp) # 8-byte Folded Spill
1759; RV64I-NEXT:    mv s2, a2
1760; RV64I-NEXT:    mv s0, a1
1761; RV64I-NEXT:    lui a1, 16
1762; RV64I-NEXT:    addiw s1, a1, -1
1763; RV64I-NEXT:    and a0, a0, s1
1764; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1765; RV64I-NEXT:    li a1, 0
1766; RV64I-NEXT:    call __addsf3@plt
1767; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1768; RV64I-NEXT:    mv s3, a0
1769; RV64I-NEXT:    and a0, s0, s1
1770; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1771; RV64I-NEXT:    li a1, 0
1772; RV64I-NEXT:    call __addsf3@plt
1773; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1774; RV64I-NEXT:    mv s4, a0
1775; RV64I-NEXT:    and a0, s2, s1
1776; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1777; RV64I-NEXT:    li a1, 0
1778; RV64I-NEXT:    call __addsf3@plt
1779; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1780; RV64I-NEXT:    mv s2, a0
1781; RV64I-NEXT:    and a0, s3, s1
1782; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1783; RV64I-NEXT:    mv s0, a0
1784; RV64I-NEXT:    and a0, s4, s1
1785; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1786; RV64I-NEXT:    mv a1, a0
1787; RV64I-NEXT:    mv a0, s0
1788; RV64I-NEXT:    call __mulsf3@plt
1789; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1790; RV64I-NEXT:    and a0, a0, s1
1791; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1792; RV64I-NEXT:    lui a1, 524288
1793; RV64I-NEXT:    xor a0, a0, a1
1794; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1795; RV64I-NEXT:    mv s0, a0
1796; RV64I-NEXT:    and a0, s2, s1
1797; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1798; RV64I-NEXT:    mv s2, a0
1799; RV64I-NEXT:    and a0, s0, s1
1800; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1801; RV64I-NEXT:    mv a1, s2
1802; RV64I-NEXT:    call __subsf3@plt
1803; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1804; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1805; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1806; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1807; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1808; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1809; RV64I-NEXT:    ld s4, 0(sp) # 8-byte Folded Reload
1810; RV64I-NEXT:    addi sp, sp, 48
1811; RV64I-NEXT:    ret
1812  %a_ = fadd half 0.0, %a ; avoid negation using xor
1813  %b_ = fadd half 0.0, %b ; avoid negation using xor
1814  %c_ = fadd half 0.0, %c ; avoid negation using xor
1815  %1 = fmul contract half %a_, %b_
1816  %2 = fneg half %1
1817  %3 = fsub contract half %2, %c_
1818  ret half %3
1819}
1820
1821define half @fnmsub_s_contract(half %a, half %b, half %c) nounwind {
1822; RV32IZFH-LABEL: fnmsub_s_contract:
1823; RV32IZFH:       # %bb.0:
1824; RV32IZFH-NEXT:    fmv.h.x ft0, zero
1825; RV32IZFH-NEXT:    fadd.h ft1, fa0, ft0
1826; RV32IZFH-NEXT:    fadd.h ft0, fa1, ft0
1827; RV32IZFH-NEXT:    fnmsub.h fa0, ft1, ft0, fa2
1828; RV32IZFH-NEXT:    ret
1829;
1830; RV64IZFH-LABEL: fnmsub_s_contract:
1831; RV64IZFH:       # %bb.0:
1832; RV64IZFH-NEXT:    fmv.h.x ft0, zero
1833; RV64IZFH-NEXT:    fadd.h ft1, fa0, ft0
1834; RV64IZFH-NEXT:    fadd.h ft0, fa1, ft0
1835; RV64IZFH-NEXT:    fnmsub.h fa0, ft1, ft0, fa2
1836; RV64IZFH-NEXT:    ret
1837;
1838; RV32I-LABEL: fnmsub_s_contract:
1839; RV32I:       # %bb.0:
1840; RV32I-NEXT:    addi sp, sp, -32
1841; RV32I-NEXT:    sw ra, 28(sp) # 4-byte Folded Spill
1842; RV32I-NEXT:    sw s0, 24(sp) # 4-byte Folded Spill
1843; RV32I-NEXT:    sw s1, 20(sp) # 4-byte Folded Spill
1844; RV32I-NEXT:    sw s2, 16(sp) # 4-byte Folded Spill
1845; RV32I-NEXT:    sw s3, 12(sp) # 4-byte Folded Spill
1846; RV32I-NEXT:    mv s2, a2
1847; RV32I-NEXT:    mv s1, a1
1848; RV32I-NEXT:    lui a1, 16
1849; RV32I-NEXT:    addi s0, a1, -1
1850; RV32I-NEXT:    and a0, a0, s0
1851; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1852; RV32I-NEXT:    li a1, 0
1853; RV32I-NEXT:    call __addsf3@plt
1854; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1855; RV32I-NEXT:    mv s3, a0
1856; RV32I-NEXT:    and a0, s1, s0
1857; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1858; RV32I-NEXT:    li a1, 0
1859; RV32I-NEXT:    call __addsf3@plt
1860; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1861; RV32I-NEXT:    mv s1, a0
1862; RV32I-NEXT:    and a0, s3, s0
1863; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1864; RV32I-NEXT:    mv s3, a0
1865; RV32I-NEXT:    and a0, s1, s0
1866; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1867; RV32I-NEXT:    mv a1, a0
1868; RV32I-NEXT:    mv a0, s3
1869; RV32I-NEXT:    call __mulsf3@plt
1870; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1871; RV32I-NEXT:    mv s1, a0
1872; RV32I-NEXT:    and a0, s2, s0
1873; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1874; RV32I-NEXT:    mv s2, a0
1875; RV32I-NEXT:    and a0, s1, s0
1876; RV32I-NEXT:    call __gnu_h2f_ieee@plt
1877; RV32I-NEXT:    mv a1, a0
1878; RV32I-NEXT:    mv a0, s2
1879; RV32I-NEXT:    call __subsf3@plt
1880; RV32I-NEXT:    call __gnu_f2h_ieee@plt
1881; RV32I-NEXT:    lw ra, 28(sp) # 4-byte Folded Reload
1882; RV32I-NEXT:    lw s0, 24(sp) # 4-byte Folded Reload
1883; RV32I-NEXT:    lw s1, 20(sp) # 4-byte Folded Reload
1884; RV32I-NEXT:    lw s2, 16(sp) # 4-byte Folded Reload
1885; RV32I-NEXT:    lw s3, 12(sp) # 4-byte Folded Reload
1886; RV32I-NEXT:    addi sp, sp, 32
1887; RV32I-NEXT:    ret
1888;
1889; RV64I-LABEL: fnmsub_s_contract:
1890; RV64I:       # %bb.0:
1891; RV64I-NEXT:    addi sp, sp, -48
1892; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
1893; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
1894; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
1895; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
1896; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
1897; RV64I-NEXT:    mv s2, a2
1898; RV64I-NEXT:    mv s1, a1
1899; RV64I-NEXT:    lui a1, 16
1900; RV64I-NEXT:    addiw s0, a1, -1
1901; RV64I-NEXT:    and a0, a0, s0
1902; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1903; RV64I-NEXT:    li a1, 0
1904; RV64I-NEXT:    call __addsf3@plt
1905; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1906; RV64I-NEXT:    mv s3, a0
1907; RV64I-NEXT:    and a0, s1, s0
1908; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1909; RV64I-NEXT:    li a1, 0
1910; RV64I-NEXT:    call __addsf3@plt
1911; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1912; RV64I-NEXT:    mv s1, a0
1913; RV64I-NEXT:    and a0, s3, s0
1914; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1915; RV64I-NEXT:    mv s3, a0
1916; RV64I-NEXT:    and a0, s1, s0
1917; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1918; RV64I-NEXT:    mv a1, a0
1919; RV64I-NEXT:    mv a0, s3
1920; RV64I-NEXT:    call __mulsf3@plt
1921; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1922; RV64I-NEXT:    mv s1, a0
1923; RV64I-NEXT:    and a0, s2, s0
1924; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1925; RV64I-NEXT:    mv s2, a0
1926; RV64I-NEXT:    and a0, s1, s0
1927; RV64I-NEXT:    call __gnu_h2f_ieee@plt
1928; RV64I-NEXT:    mv a1, a0
1929; RV64I-NEXT:    mv a0, s2
1930; RV64I-NEXT:    call __subsf3@plt
1931; RV64I-NEXT:    call __gnu_f2h_ieee@plt
1932; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
1933; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
1934; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
1935; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
1936; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
1937; RV64I-NEXT:    addi sp, sp, 48
1938; RV64I-NEXT:    ret
1939  %a_ = fadd half 0.0, %a ; avoid negation using xor
1940  %b_ = fadd half 0.0, %b ; avoid negation using xor
1941  %1 = fmul contract half %a_, %b_
1942  %2 = fsub contract half %c, %1
1943  ret half %2
1944}
1945