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