xref: /llvm-project/llvm/test/CodeGen/RISCV/float-arith.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
3; RUN:   -target-abi=ilp32f | FileCheck -check-prefix=CHECKIF %s
4; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
5; RUN:   -target-abi=lp64f | FileCheck -check-prefix=CHECKIF %s
6; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \
7; RUN:   -target-abi=ilp32 | FileCheck -check-prefixes=CHECKIZFINX,RV32IZFINX %s
8; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \
9; RUN:   -target-abi=lp64 | FileCheck -check-prefixes=CHECKIZFINX,RV64IZFINX %s
10; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
11; RUN:   | FileCheck -check-prefix=RV32I %s
12; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
13; RUN:   | FileCheck -check-prefix=RV64I %s
14
15; These tests are each targeted at a particular RISC-V FPU instruction.
16; Compares and conversions can be found in float-fcmp.ll and float-convert.ll
17; respectively. Some other float-*.ll files in this folder exercise LLVM IR
18; instructions that don't directly match a RISC-V instruction.
19
20define float @fadd_s(float %a, float %b) nounwind {
21; CHECKIF-LABEL: fadd_s:
22; CHECKIF:       # %bb.0:
23; CHECKIF-NEXT:    fadd.s fa0, fa0, fa1
24; CHECKIF-NEXT:    ret
25;
26; CHECKIZFINX-LABEL: fadd_s:
27; CHECKIZFINX:       # %bb.0:
28; CHECKIZFINX-NEXT:    fadd.s a0, a0, a1
29; CHECKIZFINX-NEXT:    ret
30;
31; RV32I-LABEL: fadd_s:
32; RV32I:       # %bb.0:
33; RV32I-NEXT:    addi sp, sp, -16
34; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
35; RV32I-NEXT:    call __addsf3
36; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
37; RV32I-NEXT:    addi sp, sp, 16
38; RV32I-NEXT:    ret
39;
40; RV64I-LABEL: fadd_s:
41; RV64I:       # %bb.0:
42; RV64I-NEXT:    addi sp, sp, -16
43; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
44; RV64I-NEXT:    call __addsf3
45; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
46; RV64I-NEXT:    addi sp, sp, 16
47; RV64I-NEXT:    ret
48  %1 = fadd float %a, %b
49  ret float %1
50}
51
52define float @fsub_s(float %a, float %b) nounwind {
53; CHECKIF-LABEL: fsub_s:
54; CHECKIF:       # %bb.0:
55; CHECKIF-NEXT:    fsub.s fa0, fa0, fa1
56; CHECKIF-NEXT:    ret
57;
58; CHECKIZFINX-LABEL: fsub_s:
59; CHECKIZFINX:       # %bb.0:
60; CHECKIZFINX-NEXT:    fsub.s a0, a0, a1
61; CHECKIZFINX-NEXT:    ret
62;
63; RV32I-LABEL: fsub_s:
64; RV32I:       # %bb.0:
65; RV32I-NEXT:    addi sp, sp, -16
66; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
67; RV32I-NEXT:    call __subsf3
68; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
69; RV32I-NEXT:    addi sp, sp, 16
70; RV32I-NEXT:    ret
71;
72; RV64I-LABEL: fsub_s:
73; RV64I:       # %bb.0:
74; RV64I-NEXT:    addi sp, sp, -16
75; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
76; RV64I-NEXT:    call __subsf3
77; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
78; RV64I-NEXT:    addi sp, sp, 16
79; RV64I-NEXT:    ret
80  %1 = fsub float %a, %b
81  ret float %1
82}
83
84define float @fmul_s(float %a, float %b) nounwind {
85; CHECKIF-LABEL: fmul_s:
86; CHECKIF:       # %bb.0:
87; CHECKIF-NEXT:    fmul.s fa0, fa0, fa1
88; CHECKIF-NEXT:    ret
89;
90; CHECKIZFINX-LABEL: fmul_s:
91; CHECKIZFINX:       # %bb.0:
92; CHECKIZFINX-NEXT:    fmul.s a0, a0, a1
93; CHECKIZFINX-NEXT:    ret
94;
95; RV32I-LABEL: fmul_s:
96; RV32I:       # %bb.0:
97; RV32I-NEXT:    addi sp, sp, -16
98; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
99; RV32I-NEXT:    call __mulsf3
100; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
101; RV32I-NEXT:    addi sp, sp, 16
102; RV32I-NEXT:    ret
103;
104; RV64I-LABEL: fmul_s:
105; RV64I:       # %bb.0:
106; RV64I-NEXT:    addi sp, sp, -16
107; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
108; RV64I-NEXT:    call __mulsf3
109; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
110; RV64I-NEXT:    addi sp, sp, 16
111; RV64I-NEXT:    ret
112  %1 = fmul float %a, %b
113  ret float %1
114}
115
116define float @fdiv_s(float %a, float %b) nounwind {
117; CHECKIF-LABEL: fdiv_s:
118; CHECKIF:       # %bb.0:
119; CHECKIF-NEXT:    fdiv.s fa0, fa0, fa1
120; CHECKIF-NEXT:    ret
121;
122; CHECKIZFINX-LABEL: fdiv_s:
123; CHECKIZFINX:       # %bb.0:
124; CHECKIZFINX-NEXT:    fdiv.s a0, a0, a1
125; CHECKIZFINX-NEXT:    ret
126;
127; RV32I-LABEL: fdiv_s:
128; RV32I:       # %bb.0:
129; RV32I-NEXT:    addi sp, sp, -16
130; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
131; RV32I-NEXT:    call __divsf3
132; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
133; RV32I-NEXT:    addi sp, sp, 16
134; RV32I-NEXT:    ret
135;
136; RV64I-LABEL: fdiv_s:
137; RV64I:       # %bb.0:
138; RV64I-NEXT:    addi sp, sp, -16
139; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
140; RV64I-NEXT:    call __divsf3
141; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
142; RV64I-NEXT:    addi sp, sp, 16
143; RV64I-NEXT:    ret
144  %1 = fdiv float %a, %b
145  ret float %1
146}
147
148declare float @llvm.sqrt.f32(float)
149
150define float @fsqrt_s(float %a) nounwind {
151; CHECKIF-LABEL: fsqrt_s:
152; CHECKIF:       # %bb.0:
153; CHECKIF-NEXT:    fsqrt.s fa0, fa0
154; CHECKIF-NEXT:    ret
155;
156; CHECKIZFINX-LABEL: fsqrt_s:
157; CHECKIZFINX:       # %bb.0:
158; CHECKIZFINX-NEXT:    fsqrt.s a0, a0
159; CHECKIZFINX-NEXT:    ret
160;
161; RV32I-LABEL: fsqrt_s:
162; RV32I:       # %bb.0:
163; RV32I-NEXT:    addi sp, sp, -16
164; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
165; RV32I-NEXT:    call sqrtf
166; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
167; RV32I-NEXT:    addi sp, sp, 16
168; RV32I-NEXT:    ret
169;
170; RV64I-LABEL: fsqrt_s:
171; RV64I:       # %bb.0:
172; RV64I-NEXT:    addi sp, sp, -16
173; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
174; RV64I-NEXT:    call sqrtf
175; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
176; RV64I-NEXT:    addi sp, sp, 16
177; RV64I-NEXT:    ret
178  %1 = call float @llvm.sqrt.f32(float %a)
179  ret float %1
180}
181
182declare float @llvm.copysign.f32(float, float)
183
184define float @fsgnj_s(float %a, float %b) nounwind {
185; CHECKIF-LABEL: fsgnj_s:
186; CHECKIF:       # %bb.0:
187; CHECKIF-NEXT:    fsgnj.s fa0, fa0, fa1
188; CHECKIF-NEXT:    ret
189;
190; CHECKIZFINX-LABEL: fsgnj_s:
191; CHECKIZFINX:       # %bb.0:
192; CHECKIZFINX-NEXT:    fsgnj.s a0, a0, a1
193; CHECKIZFINX-NEXT:    ret
194;
195; RV32I-LABEL: fsgnj_s:
196; RV32I:       # %bb.0:
197; RV32I-NEXT:    lui a2, 524288
198; RV32I-NEXT:    slli a0, a0, 1
199; RV32I-NEXT:    and a1, a1, a2
200; RV32I-NEXT:    srli a0, a0, 1
201; RV32I-NEXT:    or a0, a0, a1
202; RV32I-NEXT:    ret
203;
204; RV64I-LABEL: fsgnj_s:
205; RV64I:       # %bb.0:
206; RV64I-NEXT:    lui a2, 524288
207; RV64I-NEXT:    slli a0, a0, 33
208; RV64I-NEXT:    and a1, a1, a2
209; RV64I-NEXT:    srli a0, a0, 33
210; RV64I-NEXT:    or a0, a0, a1
211; RV64I-NEXT:    ret
212  %1 = call float @llvm.copysign.f32(float %a, float %b)
213  ret float %1
214}
215
216define i32 @fneg_s(float %a, float %b) nounwind {
217; CHECKIF-LABEL: fneg_s:
218; CHECKIF:       # %bb.0:
219; CHECKIF-NEXT:    fadd.s fa5, fa0, fa0
220; CHECKIF-NEXT:    fneg.s fa4, fa5
221; CHECKIF-NEXT:    feq.s a0, fa5, fa4
222; CHECKIF-NEXT:    ret
223;
224; CHECKIZFINX-LABEL: fneg_s:
225; CHECKIZFINX:       # %bb.0:
226; CHECKIZFINX-NEXT:    fadd.s a0, a0, a0
227; CHECKIZFINX-NEXT:    fneg.s a1, a0
228; CHECKIZFINX-NEXT:    feq.s a0, a0, a1
229; CHECKIZFINX-NEXT:    ret
230;
231; RV32I-LABEL: fneg_s:
232; RV32I:       # %bb.0:
233; RV32I-NEXT:    addi sp, sp, -16
234; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
235; RV32I-NEXT:    mv a1, a0
236; RV32I-NEXT:    call __addsf3
237; RV32I-NEXT:    lui a1, 524288
238; RV32I-NEXT:    xor a1, a0, a1
239; RV32I-NEXT:    call __eqsf2
240; RV32I-NEXT:    seqz a0, a0
241; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
242; RV32I-NEXT:    addi sp, sp, 16
243; RV32I-NEXT:    ret
244;
245; RV64I-LABEL: fneg_s:
246; RV64I:       # %bb.0:
247; RV64I-NEXT:    addi sp, sp, -16
248; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
249; RV64I-NEXT:    mv a1, a0
250; RV64I-NEXT:    call __addsf3
251; RV64I-NEXT:    lui a1, 524288
252; RV64I-NEXT:    xor a1, a0, a1
253; RV64I-NEXT:    call __eqsf2
254; RV64I-NEXT:    seqz a0, a0
255; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
256; RV64I-NEXT:    addi sp, sp, 16
257; RV64I-NEXT:    ret
258  %1 = fadd float %a, %a
259  %2 = fneg float %1
260  %3 = fcmp oeq float %1, %2
261  %4 = zext i1 %3 to i32
262  ret i32 %4
263}
264
265define float @fsgnjn_s(float %a, float %b) nounwind {
266; CHECKIF-LABEL: fsgnjn_s:
267; CHECKIF:       # %bb.0:
268; CHECKIF-NEXT:    fadd.s fa5, fa0, fa1
269; CHECKIF-NEXT:    fsgnjn.s fa0, fa0, fa5
270; CHECKIF-NEXT:    ret
271;
272; CHECKIZFINX-LABEL: fsgnjn_s:
273; CHECKIZFINX:       # %bb.0:
274; CHECKIZFINX-NEXT:    fadd.s a1, a0, a1
275; CHECKIZFINX-NEXT:    fsgnjn.s a0, a0, a1
276; CHECKIZFINX-NEXT:    ret
277;
278; RV32I-LABEL: fsgnjn_s:
279; RV32I:       # %bb.0:
280; RV32I-NEXT:    addi sp, sp, -16
281; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
282; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
283; RV32I-NEXT:    mv s0, a0
284; RV32I-NEXT:    call __addsf3
285; RV32I-NEXT:    not a0, a0
286; RV32I-NEXT:    lui a1, 524288
287; RV32I-NEXT:    slli s0, s0, 1
288; RV32I-NEXT:    and a0, a0, a1
289; RV32I-NEXT:    srli s0, s0, 1
290; RV32I-NEXT:    or a0, s0, a0
291; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
292; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
293; RV32I-NEXT:    addi sp, sp, 16
294; RV32I-NEXT:    ret
295;
296; RV64I-LABEL: fsgnjn_s:
297; RV64I:       # %bb.0:
298; RV64I-NEXT:    addi sp, sp, -16
299; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
300; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
301; RV64I-NEXT:    mv s0, a0
302; RV64I-NEXT:    call __addsf3
303; RV64I-NEXT:    not a0, a0
304; RV64I-NEXT:    lui a1, 524288
305; RV64I-NEXT:    slli s0, s0, 33
306; RV64I-NEXT:    and a0, a0, a1
307; RV64I-NEXT:    srli s0, s0, 33
308; RV64I-NEXT:    or a0, s0, a0
309; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
310; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
311; RV64I-NEXT:    addi sp, sp, 16
312; RV64I-NEXT:    ret
313  %1 = fadd float %a, %b
314  %2 = fneg float %1
315  %3 = call float @llvm.copysign.f32(float %a, float %2)
316  ret float %3
317}
318
319declare float @llvm.fabs.f32(float)
320
321define float @fabs_s(float %a, float %b) nounwind {
322; CHECKIF-LABEL: fabs_s:
323; CHECKIF:       # %bb.0:
324; CHECKIF-NEXT:    fadd.s fa5, fa0, fa1
325; CHECKIF-NEXT:    fabs.s fa4, fa5
326; CHECKIF-NEXT:    fadd.s fa0, fa4, fa5
327; CHECKIF-NEXT:    ret
328;
329; CHECKIZFINX-LABEL: fabs_s:
330; CHECKIZFINX:       # %bb.0:
331; CHECKIZFINX-NEXT:    fadd.s a0, a0, a1
332; CHECKIZFINX-NEXT:    fabs.s a1, a0
333; CHECKIZFINX-NEXT:    fadd.s a0, a1, a0
334; CHECKIZFINX-NEXT:    ret
335;
336; RV32I-LABEL: fabs_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:    call __addsf3
341; RV32I-NEXT:    mv a1, a0
342; RV32I-NEXT:    slli a0, a0, 1
343; RV32I-NEXT:    srli a0, a0, 1
344; RV32I-NEXT:    call __addsf3
345; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
346; RV32I-NEXT:    addi sp, sp, 16
347; RV32I-NEXT:    ret
348;
349; RV64I-LABEL: fabs_s:
350; RV64I:       # %bb.0:
351; RV64I-NEXT:    addi sp, sp, -16
352; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
353; RV64I-NEXT:    call __addsf3
354; RV64I-NEXT:    mv a1, a0
355; RV64I-NEXT:    slli a0, a0, 33
356; RV64I-NEXT:    srli a0, a0, 33
357; RV64I-NEXT:    call __addsf3
358; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
359; RV64I-NEXT:    addi sp, sp, 16
360; RV64I-NEXT:    ret
361  %1 = fadd float %a, %b
362  %2 = call float @llvm.fabs.f32(float %1)
363  %3 = fadd float %2, %1
364  ret float %3
365}
366
367declare float @llvm.minnum.f32(float, float)
368
369define float @fmin_s(float %a, float %b) nounwind {
370; CHECKIF-LABEL: fmin_s:
371; CHECKIF:       # %bb.0:
372; CHECKIF-NEXT:    fmin.s fa0, fa0, fa1
373; CHECKIF-NEXT:    ret
374;
375; CHECKIZFINX-LABEL: fmin_s:
376; CHECKIZFINX:       # %bb.0:
377; CHECKIZFINX-NEXT:    fmin.s a0, a0, a1
378; CHECKIZFINX-NEXT:    ret
379;
380; RV32I-LABEL: fmin_s:
381; RV32I:       # %bb.0:
382; RV32I-NEXT:    addi sp, sp, -16
383; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
384; RV32I-NEXT:    call fminf
385; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
386; RV32I-NEXT:    addi sp, sp, 16
387; RV32I-NEXT:    ret
388;
389; RV64I-LABEL: fmin_s:
390; RV64I:       # %bb.0:
391; RV64I-NEXT:    addi sp, sp, -16
392; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
393; RV64I-NEXT:    call fminf
394; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
395; RV64I-NEXT:    addi sp, sp, 16
396; RV64I-NEXT:    ret
397  %1 = call float @llvm.minnum.f32(float %a, float %b)
398  ret float %1
399}
400
401declare float @llvm.maxnum.f32(float, float)
402
403define float @fmax_s(float %a, float %b) nounwind {
404; CHECKIF-LABEL: fmax_s:
405; CHECKIF:       # %bb.0:
406; CHECKIF-NEXT:    fmax.s fa0, fa0, fa1
407; CHECKIF-NEXT:    ret
408;
409; CHECKIZFINX-LABEL: fmax_s:
410; CHECKIZFINX:       # %bb.0:
411; CHECKIZFINX-NEXT:    fmax.s a0, a0, a1
412; CHECKIZFINX-NEXT:    ret
413;
414; RV32I-LABEL: fmax_s:
415; RV32I:       # %bb.0:
416; RV32I-NEXT:    addi sp, sp, -16
417; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
418; RV32I-NEXT:    call fmaxf
419; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
420; RV32I-NEXT:    addi sp, sp, 16
421; RV32I-NEXT:    ret
422;
423; RV64I-LABEL: fmax_s:
424; RV64I:       # %bb.0:
425; RV64I-NEXT:    addi sp, sp, -16
426; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
427; RV64I-NEXT:    call fmaxf
428; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
429; RV64I-NEXT:    addi sp, sp, 16
430; RV64I-NEXT:    ret
431  %1 = call float @llvm.maxnum.f32(float %a, float %b)
432  ret float %1
433}
434
435declare float @llvm.fma.f32(float, float, float)
436
437define float @fmadd_s(float %a, float %b, float %c) nounwind {
438; CHECKIF-LABEL: fmadd_s:
439; CHECKIF:       # %bb.0:
440; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
441; CHECKIF-NEXT:    ret
442;
443; CHECKIZFINX-LABEL: fmadd_s:
444; CHECKIZFINX:       # %bb.0:
445; CHECKIZFINX-NEXT:    fmadd.s a0, a0, a1, a2
446; CHECKIZFINX-NEXT:    ret
447;
448; RV32I-LABEL: fmadd_s:
449; RV32I:       # %bb.0:
450; RV32I-NEXT:    addi sp, sp, -16
451; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
452; RV32I-NEXT:    call fmaf
453; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
454; RV32I-NEXT:    addi sp, sp, 16
455; RV32I-NEXT:    ret
456;
457; RV64I-LABEL: fmadd_s:
458; RV64I:       # %bb.0:
459; RV64I-NEXT:    addi sp, sp, -16
460; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
461; RV64I-NEXT:    call fmaf
462; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
463; RV64I-NEXT:    addi sp, sp, 16
464; RV64I-NEXT:    ret
465  %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
466  ret float %1
467}
468
469define float @fmsub_s(float %a, float %b, float %c) nounwind {
470; CHECKIF-LABEL: fmsub_s:
471; CHECKIF:       # %bb.0:
472; CHECKIF-NEXT:    fmv.w.x fa5, zero
473; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
474; CHECKIF-NEXT:    fmsub.s fa0, fa0, fa1, fa5
475; CHECKIF-NEXT:    ret
476;
477; CHECKIZFINX-LABEL: fmsub_s:
478; CHECKIZFINX:       # %bb.0:
479; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
480; CHECKIZFINX-NEXT:    fmsub.s a0, a0, a1, a2
481; CHECKIZFINX-NEXT:    ret
482;
483; RV32I-LABEL: fmsub_s:
484; RV32I:       # %bb.0:
485; RV32I-NEXT:    addi sp, sp, -16
486; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
487; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
488; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
489; RV32I-NEXT:    mv s0, a1
490; RV32I-NEXT:    mv s1, a0
491; RV32I-NEXT:    mv a0, a2
492; RV32I-NEXT:    li a1, 0
493; RV32I-NEXT:    call __addsf3
494; RV32I-NEXT:    lui a2, 524288
495; RV32I-NEXT:    xor a2, a0, a2
496; RV32I-NEXT:    mv a0, s1
497; RV32I-NEXT:    mv a1, s0
498; RV32I-NEXT:    call fmaf
499; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
500; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
501; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
502; RV32I-NEXT:    addi sp, sp, 16
503; RV32I-NEXT:    ret
504;
505; RV64I-LABEL: fmsub_s:
506; RV64I:       # %bb.0:
507; RV64I-NEXT:    addi sp, sp, -32
508; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
509; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
510; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
511; RV64I-NEXT:    mv s0, a1
512; RV64I-NEXT:    mv s1, a0
513; RV64I-NEXT:    mv a0, a2
514; RV64I-NEXT:    li a1, 0
515; RV64I-NEXT:    call __addsf3
516; RV64I-NEXT:    lui a2, 524288
517; RV64I-NEXT:    xor a2, a0, a2
518; RV64I-NEXT:    mv a0, s1
519; RV64I-NEXT:    mv a1, s0
520; RV64I-NEXT:    call fmaf
521; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
522; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
523; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
524; RV64I-NEXT:    addi sp, sp, 32
525; RV64I-NEXT:    ret
526  %c_ = fadd float 0.0, %c ; avoid negation using xor
527  %negc = fsub float -0.0, %c_
528  %1 = call float @llvm.fma.f32(float %a, float %b, float %negc)
529  ret float %1
530}
531
532define float @fnmadd_s(float %a, float %b, float %c) nounwind {
533; CHECKIF-LABEL: fnmadd_s:
534; CHECKIF:       # %bb.0:
535; CHECKIF-NEXT:    fmv.w.x fa5, zero
536; CHECKIF-NEXT:    fadd.s fa4, fa0, fa5
537; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
538; CHECKIF-NEXT:    fnmadd.s fa0, fa4, fa1, fa5
539; CHECKIF-NEXT:    ret
540;
541; CHECKIZFINX-LABEL: fnmadd_s:
542; CHECKIZFINX:       # %bb.0:
543; CHECKIZFINX-NEXT:    fadd.s a0, a0, zero
544; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
545; CHECKIZFINX-NEXT:    fnmadd.s a0, a0, a1, a2
546; CHECKIZFINX-NEXT:    ret
547;
548; RV32I-LABEL: fnmadd_s:
549; RV32I:       # %bb.0:
550; RV32I-NEXT:    addi sp, sp, -16
551; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
552; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
553; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
554; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
555; RV32I-NEXT:    mv s0, a2
556; RV32I-NEXT:    mv s1, a1
557; RV32I-NEXT:    li a1, 0
558; RV32I-NEXT:    call __addsf3
559; RV32I-NEXT:    mv s2, a0
560; RV32I-NEXT:    mv a0, s0
561; RV32I-NEXT:    li a1, 0
562; RV32I-NEXT:    call __addsf3
563; RV32I-NEXT:    lui a2, 524288
564; RV32I-NEXT:    xor a1, s2, a2
565; RV32I-NEXT:    xor a2, a0, a2
566; RV32I-NEXT:    mv a0, a1
567; RV32I-NEXT:    mv a1, s1
568; RV32I-NEXT:    call fmaf
569; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
570; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
571; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
572; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
573; RV32I-NEXT:    addi sp, sp, 16
574; RV32I-NEXT:    ret
575;
576; RV64I-LABEL: fnmadd_s:
577; RV64I:       # %bb.0:
578; RV64I-NEXT:    addi sp, sp, -32
579; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
580; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
581; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
582; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
583; RV64I-NEXT:    mv s0, a2
584; RV64I-NEXT:    mv s1, a1
585; RV64I-NEXT:    li a1, 0
586; RV64I-NEXT:    call __addsf3
587; RV64I-NEXT:    mv s2, a0
588; RV64I-NEXT:    mv a0, s0
589; RV64I-NEXT:    li a1, 0
590; RV64I-NEXT:    call __addsf3
591; RV64I-NEXT:    lui a2, 524288
592; RV64I-NEXT:    xor a1, s2, a2
593; RV64I-NEXT:    xor a2, a0, a2
594; RV64I-NEXT:    mv a0, a1
595; RV64I-NEXT:    mv a1, s1
596; RV64I-NEXT:    call fmaf
597; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
598; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
599; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
600; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
601; RV64I-NEXT:    addi sp, sp, 32
602; RV64I-NEXT:    ret
603  %a_ = fadd float 0.0, %a
604  %c_ = fadd float 0.0, %c
605  %nega = fsub float -0.0, %a_
606  %negc = fsub float -0.0, %c_
607  %1 = call float @llvm.fma.f32(float %nega, float %b, float %negc)
608  ret float %1
609}
610
611define float @fnmadd_s_2(float %a, float %b, float %c) nounwind {
612; CHECKIF-LABEL: fnmadd_s_2:
613; CHECKIF:       # %bb.0:
614; CHECKIF-NEXT:    fmv.w.x fa5, zero
615; CHECKIF-NEXT:    fadd.s fa4, fa1, fa5
616; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
617; CHECKIF-NEXT:    fnmadd.s fa0, fa4, fa0, fa5
618; CHECKIF-NEXT:    ret
619;
620; CHECKIZFINX-LABEL: fnmadd_s_2:
621; CHECKIZFINX:       # %bb.0:
622; CHECKIZFINX-NEXT:    fadd.s a1, a1, zero
623; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
624; CHECKIZFINX-NEXT:    fnmadd.s a0, a1, a0, a2
625; CHECKIZFINX-NEXT:    ret
626;
627; RV32I-LABEL: fnmadd_s_2:
628; RV32I:       # %bb.0:
629; RV32I-NEXT:    addi sp, sp, -16
630; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
631; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
632; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
633; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
634; RV32I-NEXT:    mv s0, a2
635; RV32I-NEXT:    mv s1, a0
636; RV32I-NEXT:    mv a0, a1
637; RV32I-NEXT:    li a1, 0
638; RV32I-NEXT:    call __addsf3
639; RV32I-NEXT:    mv s2, a0
640; RV32I-NEXT:    mv a0, s0
641; RV32I-NEXT:    li a1, 0
642; RV32I-NEXT:    call __addsf3
643; RV32I-NEXT:    lui a2, 524288
644; RV32I-NEXT:    xor a1, s2, a2
645; RV32I-NEXT:    xor a2, a0, a2
646; RV32I-NEXT:    mv a0, s1
647; RV32I-NEXT:    call fmaf
648; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
649; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
650; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
651; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
652; RV32I-NEXT:    addi sp, sp, 16
653; RV32I-NEXT:    ret
654;
655; RV64I-LABEL: fnmadd_s_2:
656; RV64I:       # %bb.0:
657; RV64I-NEXT:    addi sp, sp, -32
658; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
659; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
660; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
661; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
662; RV64I-NEXT:    mv s0, a2
663; RV64I-NEXT:    mv s1, a0
664; RV64I-NEXT:    mv a0, a1
665; RV64I-NEXT:    li a1, 0
666; RV64I-NEXT:    call __addsf3
667; RV64I-NEXT:    mv s2, a0
668; RV64I-NEXT:    mv a0, s0
669; RV64I-NEXT:    li a1, 0
670; RV64I-NEXT:    call __addsf3
671; RV64I-NEXT:    lui a2, 524288
672; RV64I-NEXT:    xor a1, s2, a2
673; RV64I-NEXT:    xor a2, a0, a2
674; RV64I-NEXT:    mv a0, s1
675; RV64I-NEXT:    call fmaf
676; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
677; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
678; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
679; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
680; RV64I-NEXT:    addi sp, sp, 32
681; RV64I-NEXT:    ret
682  %b_ = fadd float 0.0, %b
683  %c_ = fadd float 0.0, %c
684  %negb = fsub float -0.0, %b_
685  %negc = fsub float -0.0, %c_
686  %1 = call float @llvm.fma.f32(float %a, float %negb, float %negc)
687  ret float %1
688}
689
690define float @fnmadd_s_3(float %a, float %b, float %c) nounwind {
691; RV32IF-LABEL: fnmadd_s_3:
692; RV32IF:       # %bb.0:
693; RV32IF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
694; RV32IF-NEXT:    fneg.s fa0, ft0
695; RV32IF-NEXT:    ret
696;
697; RV64IF-LABEL: fnmadd_s_3:
698; RV64IF:       # %bb.0:
699; RV64IF-NEXT:    fmadd.s ft0, fa0, fa1, fa2
700; RV64IF-NEXT:    fneg.s fa0, ft0
701; RV64IF-NEXT:    ret
702;
703; CHECKIF-LABEL: fnmadd_s_3:
704; CHECKIF:       # %bb.0:
705; CHECKIF-NEXT:    fmadd.s fa5, fa0, fa1, fa2
706; CHECKIF-NEXT:    fneg.s fa0, fa5
707; CHECKIF-NEXT:    ret
708;
709; CHECKIZFINX-LABEL: fnmadd_s_3:
710; CHECKIZFINX:       # %bb.0:
711; CHECKIZFINX-NEXT:    fmadd.s a0, a0, a1, a2
712; CHECKIZFINX-NEXT:    fneg.s a0, a0
713; CHECKIZFINX-NEXT:    ret
714;
715; RV32I-LABEL: fnmadd_s_3:
716; RV32I:       # %bb.0:
717; RV32I-NEXT:    addi sp, sp, -16
718; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
719; RV32I-NEXT:    call fmaf
720; RV32I-NEXT:    lui a1, 524288
721; RV32I-NEXT:    xor a0, a0, a1
722; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
723; RV32I-NEXT:    addi sp, sp, 16
724; RV32I-NEXT:    ret
725;
726; RV64I-LABEL: fnmadd_s_3:
727; RV64I:       # %bb.0:
728; RV64I-NEXT:    addi sp, sp, -16
729; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
730; RV64I-NEXT:    call fmaf
731; RV64I-NEXT:    lui a1, 524288
732; RV64I-NEXT:    xor a0, a0, a1
733; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
734; RV64I-NEXT:    addi sp, sp, 16
735; RV64I-NEXT:    ret
736  %1 = call float @llvm.fma.f32(float %a, float %b, float %c)
737  %neg = fneg float %1
738  ret float %neg
739}
740
741define float @fnmadd_nsz(float %a, float %b, float %c) nounwind {
742; RV32IF-LABEL: fnmadd_nsz:
743; RV32IF:       # %bb.0:
744; RV32IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
745; RV32IF-NEXT:    ret
746;
747; RV64IF-LABEL: fnmadd_nsz:
748; RV64IF:       # %bb.0:
749; RV64IF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
750; RV64IF-NEXT:    ret
751;
752; CHECKIF-LABEL: fnmadd_nsz:
753; CHECKIF:       # %bb.0:
754; CHECKIF-NEXT:    fnmadd.s fa0, fa0, fa1, fa2
755; CHECKIF-NEXT:    ret
756;
757; CHECKIZFINX-LABEL: fnmadd_nsz:
758; CHECKIZFINX:       # %bb.0:
759; CHECKIZFINX-NEXT:    fnmadd.s a0, a0, a1, a2
760; CHECKIZFINX-NEXT:    ret
761;
762; RV32I-LABEL: fnmadd_nsz:
763; RV32I:       # %bb.0:
764; RV32I-NEXT:    addi sp, sp, -16
765; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
766; RV32I-NEXT:    call fmaf
767; RV32I-NEXT:    lui a1, 524288
768; RV32I-NEXT:    xor a0, a0, a1
769; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
770; RV32I-NEXT:    addi sp, sp, 16
771; RV32I-NEXT:    ret
772;
773; RV64I-LABEL: fnmadd_nsz:
774; RV64I:       # %bb.0:
775; RV64I-NEXT:    addi sp, sp, -16
776; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
777; RV64I-NEXT:    call fmaf
778; RV64I-NEXT:    lui a1, 524288
779; RV64I-NEXT:    xor a0, a0, a1
780; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
781; RV64I-NEXT:    addi sp, sp, 16
782; RV64I-NEXT:    ret
783  %1 = call nsz float @llvm.fma.f32(float %a, float %b, float %c)
784  %neg = fneg nsz float %1
785  ret float %neg
786}
787
788define float @fnmsub_s(float %a, float %b, float %c) nounwind {
789; CHECKIF-LABEL: fnmsub_s:
790; CHECKIF:       # %bb.0:
791; CHECKIF-NEXT:    fmv.w.x fa5, zero
792; CHECKIF-NEXT:    fadd.s fa5, fa0, fa5
793; CHECKIF-NEXT:    fnmsub.s fa0, fa5, fa1, fa2
794; CHECKIF-NEXT:    ret
795;
796; CHECKIZFINX-LABEL: fnmsub_s:
797; CHECKIZFINX:       # %bb.0:
798; CHECKIZFINX-NEXT:    fadd.s a0, a0, zero
799; CHECKIZFINX-NEXT:    fnmsub.s a0, a0, a1, a2
800; CHECKIZFINX-NEXT:    ret
801;
802; RV32I-LABEL: fnmsub_s:
803; RV32I:       # %bb.0:
804; RV32I-NEXT:    addi sp, sp, -16
805; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
806; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
807; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
808; RV32I-NEXT:    mv s0, a2
809; RV32I-NEXT:    mv s1, a1
810; RV32I-NEXT:    li a1, 0
811; RV32I-NEXT:    call __addsf3
812; RV32I-NEXT:    lui a1, 524288
813; RV32I-NEXT:    xor a0, a0, a1
814; RV32I-NEXT:    mv a1, s1
815; RV32I-NEXT:    mv a2, s0
816; RV32I-NEXT:    call fmaf
817; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
818; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
819; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
820; RV32I-NEXT:    addi sp, sp, 16
821; RV32I-NEXT:    ret
822;
823; RV64I-LABEL: fnmsub_s:
824; RV64I:       # %bb.0:
825; RV64I-NEXT:    addi sp, sp, -32
826; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
827; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
828; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
829; RV64I-NEXT:    mv s0, a2
830; RV64I-NEXT:    mv s1, a1
831; RV64I-NEXT:    li a1, 0
832; RV64I-NEXT:    call __addsf3
833; RV64I-NEXT:    lui a1, 524288
834; RV64I-NEXT:    xor a0, a0, a1
835; RV64I-NEXT:    mv a1, s1
836; RV64I-NEXT:    mv a2, s0
837; RV64I-NEXT:    call fmaf
838; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
839; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
840; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
841; RV64I-NEXT:    addi sp, sp, 32
842; RV64I-NEXT:    ret
843  %a_ = fadd float 0.0, %a
844  %nega = fsub float -0.0, %a_
845  %1 = call float @llvm.fma.f32(float %nega, float %b, float %c)
846  ret float %1
847}
848
849define float @fnmsub_s_2(float %a, float %b, float %c) nounwind {
850; CHECKIF-LABEL: fnmsub_s_2:
851; CHECKIF:       # %bb.0:
852; CHECKIF-NEXT:    fmv.w.x fa5, zero
853; CHECKIF-NEXT:    fadd.s fa5, fa1, fa5
854; CHECKIF-NEXT:    fnmsub.s fa0, fa5, fa0, fa2
855; CHECKIF-NEXT:    ret
856;
857; CHECKIZFINX-LABEL: fnmsub_s_2:
858; CHECKIZFINX:       # %bb.0:
859; CHECKIZFINX-NEXT:    fadd.s a1, a1, zero
860; CHECKIZFINX-NEXT:    fnmsub.s a0, a1, a0, a2
861; CHECKIZFINX-NEXT:    ret
862;
863; RV32I-LABEL: fnmsub_s_2:
864; RV32I:       # %bb.0:
865; RV32I-NEXT:    addi sp, sp, -16
866; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
867; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
868; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
869; RV32I-NEXT:    mv s0, a2
870; RV32I-NEXT:    mv s1, a0
871; RV32I-NEXT:    mv a0, a1
872; RV32I-NEXT:    li a1, 0
873; RV32I-NEXT:    call __addsf3
874; RV32I-NEXT:    lui a1, 524288
875; RV32I-NEXT:    xor a1, a0, a1
876; RV32I-NEXT:    mv a0, s1
877; RV32I-NEXT:    mv a2, s0
878; RV32I-NEXT:    call fmaf
879; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
880; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
881; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
882; RV32I-NEXT:    addi sp, sp, 16
883; RV32I-NEXT:    ret
884;
885; RV64I-LABEL: fnmsub_s_2:
886; RV64I:       # %bb.0:
887; RV64I-NEXT:    addi sp, sp, -32
888; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
889; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
890; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
891; RV64I-NEXT:    mv s0, a2
892; RV64I-NEXT:    mv s1, a0
893; RV64I-NEXT:    mv a0, a1
894; RV64I-NEXT:    li a1, 0
895; RV64I-NEXT:    call __addsf3
896; RV64I-NEXT:    lui a1, 524288
897; RV64I-NEXT:    xor a1, a0, a1
898; RV64I-NEXT:    mv a0, s1
899; RV64I-NEXT:    mv a2, s0
900; RV64I-NEXT:    call fmaf
901; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
902; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
903; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
904; RV64I-NEXT:    addi sp, sp, 32
905; RV64I-NEXT:    ret
906  %b_ = fadd float 0.0, %b
907  %negb = fsub float -0.0, %b_
908  %1 = call float @llvm.fma.f32(float %a, float %negb, float %c)
909  ret float %1
910}
911
912define float @fmadd_s_contract(float %a, float %b, float %c) nounwind {
913; CHECKIF-LABEL: fmadd_s_contract:
914; CHECKIF:       # %bb.0:
915; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
916; CHECKIF-NEXT:    ret
917;
918; CHECKIZFINX-LABEL: fmadd_s_contract:
919; CHECKIZFINX:       # %bb.0:
920; CHECKIZFINX-NEXT:    fmadd.s a0, a0, a1, a2
921; CHECKIZFINX-NEXT:    ret
922;
923; RV32I-LABEL: fmadd_s_contract:
924; RV32I:       # %bb.0:
925; RV32I-NEXT:    addi sp, sp, -16
926; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
927; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
928; RV32I-NEXT:    mv s0, a2
929; RV32I-NEXT:    call __mulsf3
930; RV32I-NEXT:    mv a1, s0
931; RV32I-NEXT:    call __addsf3
932; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
933; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
934; RV32I-NEXT:    addi sp, sp, 16
935; RV32I-NEXT:    ret
936;
937; RV64I-LABEL: fmadd_s_contract:
938; RV64I:       # %bb.0:
939; RV64I-NEXT:    addi sp, sp, -16
940; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
941; RV64I-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
942; RV64I-NEXT:    mv s0, a2
943; RV64I-NEXT:    call __mulsf3
944; RV64I-NEXT:    mv a1, s0
945; RV64I-NEXT:    call __addsf3
946; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
947; RV64I-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
948; RV64I-NEXT:    addi sp, sp, 16
949; RV64I-NEXT:    ret
950  %1 = fmul contract float %a, %b
951  %2 = fadd contract float %1, %c
952  ret float %2
953}
954
955define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
956; CHECKIF-LABEL: fmsub_s_contract:
957; CHECKIF:       # %bb.0:
958; CHECKIF-NEXT:    fmv.w.x fa5, zero
959; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
960; CHECKIF-NEXT:    fmsub.s fa0, fa0, fa1, fa5
961; CHECKIF-NEXT:    ret
962;
963; CHECKIZFINX-LABEL: fmsub_s_contract:
964; CHECKIZFINX:       # %bb.0:
965; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
966; CHECKIZFINX-NEXT:    fmsub.s a0, a0, a1, a2
967; CHECKIZFINX-NEXT:    ret
968;
969; RV32I-LABEL: fmsub_s_contract:
970; RV32I:       # %bb.0:
971; RV32I-NEXT:    addi sp, sp, -16
972; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
973; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
974; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
975; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
976; RV32I-NEXT:    mv s0, a1
977; RV32I-NEXT:    mv s1, a0
978; RV32I-NEXT:    mv a0, a2
979; RV32I-NEXT:    li a1, 0
980; RV32I-NEXT:    call __addsf3
981; RV32I-NEXT:    mv s2, a0
982; RV32I-NEXT:    mv a0, s1
983; RV32I-NEXT:    mv a1, s0
984; RV32I-NEXT:    call __mulsf3
985; RV32I-NEXT:    mv a1, s2
986; RV32I-NEXT:    call __subsf3
987; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
988; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
989; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
990; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
991; RV32I-NEXT:    addi sp, sp, 16
992; RV32I-NEXT:    ret
993;
994; RV64I-LABEL: fmsub_s_contract:
995; RV64I:       # %bb.0:
996; RV64I-NEXT:    addi sp, sp, -32
997; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
998; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
999; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1000; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1001; RV64I-NEXT:    mv s0, a1
1002; RV64I-NEXT:    mv s1, a0
1003; RV64I-NEXT:    mv a0, a2
1004; RV64I-NEXT:    li a1, 0
1005; RV64I-NEXT:    call __addsf3
1006; RV64I-NEXT:    mv s2, a0
1007; RV64I-NEXT:    mv a0, s1
1008; RV64I-NEXT:    mv a1, s0
1009; RV64I-NEXT:    call __mulsf3
1010; RV64I-NEXT:    mv a1, s2
1011; RV64I-NEXT:    call __subsf3
1012; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1013; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1014; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1015; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1016; RV64I-NEXT:    addi sp, sp, 32
1017; RV64I-NEXT:    ret
1018  %c_ = fadd float 0.0, %c ; avoid negation using xor
1019  %1 = fmul contract float %a, %b
1020  %2 = fsub contract float %1, %c_
1021  ret float %2
1022}
1023
1024define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind {
1025; CHECKIF-LABEL: fnmadd_s_contract:
1026; CHECKIF:       # %bb.0:
1027; CHECKIF-NEXT:    fmv.w.x fa5, zero
1028; CHECKIF-NEXT:    fadd.s fa4, fa0, fa5
1029; CHECKIF-NEXT:    fadd.s fa3, fa1, fa5
1030; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
1031; CHECKIF-NEXT:    fnmadd.s fa0, fa4, fa3, fa5
1032; CHECKIF-NEXT:    ret
1033;
1034; CHECKIZFINX-LABEL: fnmadd_s_contract:
1035; CHECKIZFINX:       # %bb.0:
1036; CHECKIZFINX-NEXT:    fadd.s a0, a0, zero
1037; CHECKIZFINX-NEXT:    fadd.s a1, a1, zero
1038; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
1039; CHECKIZFINX-NEXT:    fnmadd.s a0, a0, a1, a2
1040; CHECKIZFINX-NEXT:    ret
1041;
1042; RV32I-LABEL: fnmadd_s_contract:
1043; RV32I:       # %bb.0:
1044; RV32I-NEXT:    addi sp, sp, -16
1045; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1046; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
1047; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
1048; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
1049; RV32I-NEXT:    mv s0, a2
1050; RV32I-NEXT:    mv s1, a1
1051; RV32I-NEXT:    li a1, 0
1052; RV32I-NEXT:    call __addsf3
1053; RV32I-NEXT:    mv s2, a0
1054; RV32I-NEXT:    mv a0, s1
1055; RV32I-NEXT:    li a1, 0
1056; RV32I-NEXT:    call __addsf3
1057; RV32I-NEXT:    mv s1, a0
1058; RV32I-NEXT:    mv a0, s0
1059; RV32I-NEXT:    li a1, 0
1060; RV32I-NEXT:    call __addsf3
1061; RV32I-NEXT:    mv s0, a0
1062; RV32I-NEXT:    mv a0, s2
1063; RV32I-NEXT:    mv a1, s1
1064; RV32I-NEXT:    call __mulsf3
1065; RV32I-NEXT:    lui a1, 524288
1066; RV32I-NEXT:    xor a0, a0, a1
1067; RV32I-NEXT:    mv a1, s0
1068; RV32I-NEXT:    call __subsf3
1069; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1070; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1071; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1072; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
1073; RV32I-NEXT:    addi sp, sp, 16
1074; RV32I-NEXT:    ret
1075;
1076; RV64I-LABEL: fnmadd_s_contract:
1077; RV64I:       # %bb.0:
1078; RV64I-NEXT:    addi sp, sp, -32
1079; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1080; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1081; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1082; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1083; RV64I-NEXT:    mv s0, a2
1084; RV64I-NEXT:    mv s1, a1
1085; RV64I-NEXT:    li a1, 0
1086; RV64I-NEXT:    call __addsf3
1087; RV64I-NEXT:    mv s2, a0
1088; RV64I-NEXT:    mv a0, s1
1089; RV64I-NEXT:    li a1, 0
1090; RV64I-NEXT:    call __addsf3
1091; RV64I-NEXT:    mv s1, a0
1092; RV64I-NEXT:    mv a0, s0
1093; RV64I-NEXT:    li a1, 0
1094; RV64I-NEXT:    call __addsf3
1095; RV64I-NEXT:    mv s0, a0
1096; RV64I-NEXT:    mv a0, s2
1097; RV64I-NEXT:    mv a1, s1
1098; RV64I-NEXT:    call __mulsf3
1099; RV64I-NEXT:    lui a1, 524288
1100; RV64I-NEXT:    xor a0, a0, a1
1101; RV64I-NEXT:    mv a1, s0
1102; RV64I-NEXT:    call __subsf3
1103; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1104; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1105; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1106; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1107; RV64I-NEXT:    addi sp, sp, 32
1108; RV64I-NEXT:    ret
1109  %a_ = fadd float 0.0, %a ; avoid negation using xor
1110  %b_ = fadd float 0.0, %b ; avoid negation using xor
1111  %c_ = fadd float 0.0, %c ; avoid negation using xor
1112  %1 = fmul contract float %a_, %b_
1113  %2 = fneg float %1
1114  %3 = fsub contract float %2, %c_
1115  ret float %3
1116}
1117
1118define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind {
1119; CHECKIF-LABEL: fnmsub_s_contract:
1120; CHECKIF:       # %bb.0:
1121; CHECKIF-NEXT:    fmv.w.x fa5, zero
1122; CHECKIF-NEXT:    fadd.s fa4, fa0, fa5
1123; CHECKIF-NEXT:    fadd.s fa5, fa1, fa5
1124; CHECKIF-NEXT:    fnmsub.s fa0, fa4, fa5, fa2
1125; CHECKIF-NEXT:    ret
1126;
1127; CHECKIZFINX-LABEL: fnmsub_s_contract:
1128; CHECKIZFINX:       # %bb.0:
1129; CHECKIZFINX-NEXT:    fadd.s a0, a0, zero
1130; CHECKIZFINX-NEXT:    fadd.s a1, a1, zero
1131; CHECKIZFINX-NEXT:    fnmsub.s a0, a0, a1, a2
1132; CHECKIZFINX-NEXT:    ret
1133;
1134; RV32I-LABEL: fnmsub_s_contract:
1135; RV32I:       # %bb.0:
1136; RV32I-NEXT:    addi sp, sp, -16
1137; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1138; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
1139; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
1140; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
1141; RV32I-NEXT:    mv s0, a2
1142; RV32I-NEXT:    mv s1, a1
1143; RV32I-NEXT:    li a1, 0
1144; RV32I-NEXT:    call __addsf3
1145; RV32I-NEXT:    mv s2, a0
1146; RV32I-NEXT:    mv a0, s1
1147; RV32I-NEXT:    li a1, 0
1148; RV32I-NEXT:    call __addsf3
1149; RV32I-NEXT:    mv a1, a0
1150; RV32I-NEXT:    mv a0, s2
1151; RV32I-NEXT:    call __mulsf3
1152; RV32I-NEXT:    mv a1, a0
1153; RV32I-NEXT:    mv a0, s0
1154; RV32I-NEXT:    call __subsf3
1155; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1156; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
1157; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
1158; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
1159; RV32I-NEXT:    addi sp, sp, 16
1160; RV32I-NEXT:    ret
1161;
1162; RV64I-LABEL: fnmsub_s_contract:
1163; RV64I:       # %bb.0:
1164; RV64I-NEXT:    addi sp, sp, -32
1165; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1166; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1167; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1168; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
1169; RV64I-NEXT:    mv s0, a2
1170; RV64I-NEXT:    mv s1, a1
1171; RV64I-NEXT:    li a1, 0
1172; RV64I-NEXT:    call __addsf3
1173; RV64I-NEXT:    mv s2, a0
1174; RV64I-NEXT:    mv a0, s1
1175; RV64I-NEXT:    li a1, 0
1176; RV64I-NEXT:    call __addsf3
1177; RV64I-NEXT:    mv a1, a0
1178; RV64I-NEXT:    mv a0, s2
1179; RV64I-NEXT:    call __mulsf3
1180; RV64I-NEXT:    mv a1, a0
1181; RV64I-NEXT:    mv a0, s0
1182; RV64I-NEXT:    call __subsf3
1183; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1184; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1185; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1186; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
1187; RV64I-NEXT:    addi sp, sp, 32
1188; RV64I-NEXT:    ret
1189  %a_ = fadd float 0.0, %a ; avoid negation using xor
1190  %b_ = fadd float 0.0, %b ; avoid negation using xor
1191  %1 = fmul contract float %a_, %b_
1192  %2 = fsub contract float %c, %1
1193  ret float %2
1194}
1195
1196define float @fsgnjx_f32(float %x, float %y) nounwind {
1197; CHECKIF-LABEL: fsgnjx_f32:
1198; CHECKIF:       # %bb.0:
1199; CHECKIF-NEXT:    fsgnjx.s fa0, fa1, fa0
1200; CHECKIF-NEXT:    ret
1201;
1202; CHECKIZFINX-LABEL: fsgnjx_f32:
1203; CHECKIZFINX:       # %bb.0:
1204; CHECKIZFINX-NEXT:    fsgnjx.s a0, a1, a0
1205; CHECKIZFINX-NEXT:    ret
1206;
1207; RV32I-LABEL: fsgnjx_f32:
1208; RV32I:       # %bb.0:
1209; RV32I-NEXT:    addi sp, sp, -16
1210; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
1211; RV32I-NEXT:    lui a2, 524288
1212; RV32I-NEXT:    and a0, a0, a2
1213; RV32I-NEXT:    lui a2, 260096
1214; RV32I-NEXT:    or a0, a0, a2
1215; RV32I-NEXT:    call __mulsf3
1216; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
1217; RV32I-NEXT:    addi sp, sp, 16
1218; RV32I-NEXT:    ret
1219;
1220; RV64I-LABEL: fsgnjx_f32:
1221; RV64I:       # %bb.0:
1222; RV64I-NEXT:    addi sp, sp, -16
1223; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1224; RV64I-NEXT:    lui a2, 524288
1225; RV64I-NEXT:    and a0, a0, a2
1226; RV64I-NEXT:    lui a2, 260096
1227; RV64I-NEXT:    or a0, a0, a2
1228; RV64I-NEXT:    call __mulsf3
1229; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1230; RV64I-NEXT:    addi sp, sp, 16
1231; RV64I-NEXT:    ret
1232  %z = call float @llvm.copysign.f32(float 1.0, float %x)
1233  %mul = fmul float %z, %y
1234  ret float %mul
1235}
1236;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
1237; RV32IZFINX: {{.*}}
1238; RV64IZFINX: {{.*}}
1239