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