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