xref: /llvm-project/llvm/test/CodeGen/RISCV/float-arith-strict.ll (revision eabaee0c59110d0e11b33a69db54ccda526b35fd)
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:   -disable-strictnode-mutation -target-abi=ilp32f \
4; RUN:   | FileCheck -check-prefixes=CHECKIF,RV32IF %s
5; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
6; RUN:   -disable-strictnode-mutation -target-abi=lp64f \
7; RUN:   | FileCheck -check-prefixes=CHECKIF,RV64IF %s
8; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
9; RUN:   -disable-strictnode-mutation | FileCheck -check-prefix=RV32I %s
10; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
11; RUN:   -disable-strictnode-mutation | FileCheck -check-prefix=RV64I %s
12; RUN: llc -mtriple=riscv32 -mattr=+zfinx -verify-machineinstrs < %s \
13; RUN:   -disable-strictnode-mutation -target-abi=ilp32 \
14; RUN:   | FileCheck -check-prefixes=CHECKIZFINX,RV32IZFINX %s
15; RUN: llc -mtriple=riscv64 -mattr=+zfinx -verify-machineinstrs < %s \
16; RUN:   -disable-strictnode-mutation -target-abi=lp64 \
17; RUN:   | FileCheck -check-prefixes=CHECKIZFINX,RV64IZFINX %s
18
19define float @fadd_s(float %a, float %b) nounwind strictfp {
20; CHECKIF-LABEL: fadd_s:
21; CHECKIF:       # %bb.0:
22; CHECKIF-NEXT:    fadd.s fa0, fa0, fa1
23; CHECKIF-NEXT:    ret
24;
25; RV32I-LABEL: fadd_s:
26; RV32I:       # %bb.0:
27; RV32I-NEXT:    addi sp, sp, -16
28; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
29; RV32I-NEXT:    call __addsf3
30; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
31; RV32I-NEXT:    addi sp, sp, 16
32; RV32I-NEXT:    ret
33;
34; RV64I-LABEL: fadd_s:
35; RV64I:       # %bb.0:
36; RV64I-NEXT:    addi sp, sp, -16
37; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
38; RV64I-NEXT:    call __addsf3
39; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
40; RV64I-NEXT:    addi sp, sp, 16
41; RV64I-NEXT:    ret
42;
43; CHECKIZFINX-LABEL: fadd_s:
44; CHECKIZFINX:       # %bb.0:
45; CHECKIZFINX-NEXT:    fadd.s a0, a0, a1
46; CHECKIZFINX-NEXT:    ret
47  %1 = call float @llvm.experimental.constrained.fadd.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
48  ret float %1
49}
50declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
51
52define float @fsub_s(float %a, float %b) nounwind strictfp {
53; CHECKIF-LABEL: fsub_s:
54; CHECKIF:       # %bb.0:
55; CHECKIF-NEXT:    fsub.s fa0, fa0, fa1
56; CHECKIF-NEXT:    ret
57;
58; RV32I-LABEL: fsub_s:
59; RV32I:       # %bb.0:
60; RV32I-NEXT:    addi sp, sp, -16
61; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
62; RV32I-NEXT:    call __subsf3
63; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
64; RV32I-NEXT:    addi sp, sp, 16
65; RV32I-NEXT:    ret
66;
67; RV64I-LABEL: fsub_s:
68; RV64I:       # %bb.0:
69; RV64I-NEXT:    addi sp, sp, -16
70; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
71; RV64I-NEXT:    call __subsf3
72; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
73; RV64I-NEXT:    addi sp, sp, 16
74; RV64I-NEXT:    ret
75;
76; CHECKIZFINX-LABEL: fsub_s:
77; CHECKIZFINX:       # %bb.0:
78; CHECKIZFINX-NEXT:    fsub.s a0, a0, a1
79; CHECKIZFINX-NEXT:    ret
80  %1 = call float @llvm.experimental.constrained.fsub.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
81  ret float %1
82}
83declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
84
85define float @fmul_s(float %a, float %b) nounwind strictfp {
86; CHECKIF-LABEL: fmul_s:
87; CHECKIF:       # %bb.0:
88; CHECKIF-NEXT:    fmul.s fa0, fa0, fa1
89; CHECKIF-NEXT:    ret
90;
91; RV32I-LABEL: fmul_s:
92; RV32I:       # %bb.0:
93; RV32I-NEXT:    addi sp, sp, -16
94; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
95; RV32I-NEXT:    call __mulsf3
96; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
97; RV32I-NEXT:    addi sp, sp, 16
98; RV32I-NEXT:    ret
99;
100; RV64I-LABEL: fmul_s:
101; RV64I:       # %bb.0:
102; RV64I-NEXT:    addi sp, sp, -16
103; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
104; RV64I-NEXT:    call __mulsf3
105; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
106; RV64I-NEXT:    addi sp, sp, 16
107; RV64I-NEXT:    ret
108;
109; CHECKIZFINX-LABEL: fmul_s:
110; CHECKIZFINX:       # %bb.0:
111; CHECKIZFINX-NEXT:    fmul.s a0, a0, a1
112; CHECKIZFINX-NEXT:    ret
113  %1 = call float @llvm.experimental.constrained.fmul.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
114  ret float %1
115}
116declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata)
117
118define float @fdiv_s(float %a, float %b) nounwind strictfp {
119; CHECKIF-LABEL: fdiv_s:
120; CHECKIF:       # %bb.0:
121; CHECKIF-NEXT:    fdiv.s fa0, fa0, fa1
122; CHECKIF-NEXT:    ret
123;
124; RV32I-LABEL: fdiv_s:
125; RV32I:       # %bb.0:
126; RV32I-NEXT:    addi sp, sp, -16
127; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
128; RV32I-NEXT:    call __divsf3
129; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
130; RV32I-NEXT:    addi sp, sp, 16
131; RV32I-NEXT:    ret
132;
133; RV64I-LABEL: fdiv_s:
134; RV64I:       # %bb.0:
135; RV64I-NEXT:    addi sp, sp, -16
136; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
137; RV64I-NEXT:    call __divsf3
138; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
139; RV64I-NEXT:    addi sp, sp, 16
140; RV64I-NEXT:    ret
141;
142; CHECKIZFINX-LABEL: fdiv_s:
143; CHECKIZFINX:       # %bb.0:
144; CHECKIZFINX-NEXT:    fdiv.s a0, a0, a1
145; CHECKIZFINX-NEXT:    ret
146  %1 = call float @llvm.experimental.constrained.fdiv.f32(float %a, float %b, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
147  ret float %1
148}
149declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata)
150
151define float @fsqrt_s(float %a) nounwind strictfp {
152; CHECKIF-LABEL: fsqrt_s:
153; CHECKIF:       # %bb.0:
154; CHECKIF-NEXT:    fsqrt.s fa0, fa0
155; CHECKIF-NEXT:    ret
156;
157; RV32I-LABEL: fsqrt_s:
158; RV32I:       # %bb.0:
159; RV32I-NEXT:    addi sp, sp, -16
160; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
161; RV32I-NEXT:    call sqrtf
162; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
163; RV32I-NEXT:    addi sp, sp, 16
164; RV32I-NEXT:    ret
165;
166; RV64I-LABEL: fsqrt_s:
167; RV64I:       # %bb.0:
168; RV64I-NEXT:    addi sp, sp, -16
169; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
170; RV64I-NEXT:    call sqrtf
171; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
172; RV64I-NEXT:    addi sp, sp, 16
173; RV64I-NEXT:    ret
174;
175; CHECKIZFINX-LABEL: fsqrt_s:
176; CHECKIZFINX:       # %bb.0:
177; CHECKIZFINX-NEXT:    fsqrt.s a0, a0
178; CHECKIZFINX-NEXT:    ret
179  %1 = call float @llvm.experimental.constrained.sqrt.f32(float %a, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
180  ret float %1
181}
182declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
183
184define float @fmin_s(float %a, float %b) nounwind strictfp {
185; RV32IF-LABEL: fmin_s:
186; RV32IF:       # %bb.0:
187; RV32IF-NEXT:    addi sp, sp, -16
188; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
189; RV32IF-NEXT:    call fminf
190; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
191; RV32IF-NEXT:    addi sp, sp, 16
192; RV32IF-NEXT:    ret
193;
194; RV64IF-LABEL: fmin_s:
195; RV64IF:       # %bb.0:
196; RV64IF-NEXT:    addi sp, sp, -16
197; RV64IF-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
198; RV64IF-NEXT:    call fminf
199; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
200; RV64IF-NEXT:    addi sp, sp, 16
201; RV64IF-NEXT:    ret
202;
203; RV32I-LABEL: fmin_s:
204; RV32I:       # %bb.0:
205; RV32I-NEXT:    addi sp, sp, -16
206; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
207; RV32I-NEXT:    call fminf
208; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
209; RV32I-NEXT:    addi sp, sp, 16
210; RV32I-NEXT:    ret
211;
212; RV64I-LABEL: fmin_s:
213; RV64I:       # %bb.0:
214; RV64I-NEXT:    addi sp, sp, -16
215; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
216; RV64I-NEXT:    call fminf
217; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
218; RV64I-NEXT:    addi sp, sp, 16
219; RV64I-NEXT:    ret
220;
221; RV32IZFINX-LABEL: fmin_s:
222; RV32IZFINX:       # %bb.0:
223; RV32IZFINX-NEXT:    addi sp, sp, -16
224; RV32IZFINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
225; RV32IZFINX-NEXT:    call fminf
226; RV32IZFINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
227; RV32IZFINX-NEXT:    addi sp, sp, 16
228; RV32IZFINX-NEXT:    ret
229;
230; RV64IZFINX-LABEL: fmin_s:
231; RV64IZFINX:       # %bb.0:
232; RV64IZFINX-NEXT:    addi sp, sp, -16
233; RV64IZFINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
234; RV64IZFINX-NEXT:    call fminf
235; RV64IZFINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
236; RV64IZFINX-NEXT:    addi sp, sp, 16
237; RV64IZFINX-NEXT:    ret
238  %1 = call float @llvm.experimental.constrained.minnum.f32(float %a, float %b, metadata !"fpexcept.strict") strictfp
239  ret float %1
240}
241declare float @llvm.experimental.constrained.minnum.f32(float, float, metadata) strictfp
242
243define float @fmax_s(float %a, float %b) nounwind strictfp {
244; RV32IF-LABEL: fmax_s:
245; RV32IF:       # %bb.0:
246; RV32IF-NEXT:    addi sp, sp, -16
247; RV32IF-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
248; RV32IF-NEXT:    call fmaxf
249; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
250; RV32IF-NEXT:    addi sp, sp, 16
251; RV32IF-NEXT:    ret
252;
253; RV64IF-LABEL: fmax_s:
254; RV64IF:       # %bb.0:
255; RV64IF-NEXT:    addi sp, sp, -16
256; RV64IF-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
257; RV64IF-NEXT:    call fmaxf
258; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
259; RV64IF-NEXT:    addi sp, sp, 16
260; RV64IF-NEXT:    ret
261;
262; RV32I-LABEL: fmax_s:
263; RV32I:       # %bb.0:
264; RV32I-NEXT:    addi sp, sp, -16
265; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
266; RV32I-NEXT:    call fmaxf
267; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
268; RV32I-NEXT:    addi sp, sp, 16
269; RV32I-NEXT:    ret
270;
271; RV64I-LABEL: fmax_s:
272; RV64I:       # %bb.0:
273; RV64I-NEXT:    addi sp, sp, -16
274; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
275; RV64I-NEXT:    call fmaxf
276; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
277; RV64I-NEXT:    addi sp, sp, 16
278; RV64I-NEXT:    ret
279;
280; RV32IZFINX-LABEL: fmax_s:
281; RV32IZFINX:       # %bb.0:
282; RV32IZFINX-NEXT:    addi sp, sp, -16
283; RV32IZFINX-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
284; RV32IZFINX-NEXT:    call fmaxf
285; RV32IZFINX-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
286; RV32IZFINX-NEXT:    addi sp, sp, 16
287; RV32IZFINX-NEXT:    ret
288;
289; RV64IZFINX-LABEL: fmax_s:
290; RV64IZFINX:       # %bb.0:
291; RV64IZFINX-NEXT:    addi sp, sp, -16
292; RV64IZFINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
293; RV64IZFINX-NEXT:    call fmaxf
294; RV64IZFINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
295; RV64IZFINX-NEXT:    addi sp, sp, 16
296; RV64IZFINX-NEXT:    ret
297  %1 = call float @llvm.experimental.constrained.maxnum.f32(float %a, float %b, metadata !"fpexcept.strict") strictfp
298  ret float %1
299}
300declare float @llvm.experimental.constrained.maxnum.f32(float, float, metadata) strictfp
301
302define float @fmadd_s(float %a, float %b, float %c) nounwind strictfp {
303; CHECKIF-LABEL: fmadd_s:
304; CHECKIF:       # %bb.0:
305; CHECKIF-NEXT:    fmadd.s fa0, fa0, fa1, fa2
306; CHECKIF-NEXT:    ret
307;
308; RV32I-LABEL: fmadd_s:
309; RV32I:       # %bb.0:
310; RV32I-NEXT:    addi sp, sp, -16
311; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
312; RV32I-NEXT:    call fmaf
313; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
314; RV32I-NEXT:    addi sp, sp, 16
315; RV32I-NEXT:    ret
316;
317; RV64I-LABEL: fmadd_s:
318; RV64I:       # %bb.0:
319; RV64I-NEXT:    addi sp, sp, -16
320; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
321; RV64I-NEXT:    call fmaf
322; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
323; RV64I-NEXT:    addi sp, sp, 16
324; RV64I-NEXT:    ret
325;
326; CHECKIZFINX-LABEL: fmadd_s:
327; CHECKIZFINX:       # %bb.0:
328; CHECKIZFINX-NEXT:    fmadd.s a0, a0, a1, a2
329; CHECKIZFINX-NEXT:    ret
330  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %b, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
331  ret float %1
332}
333declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata) strictfp
334
335define float @fmsub_s(float %a, float %b, float %c) nounwind strictfp {
336; CHECKIF-LABEL: fmsub_s:
337; CHECKIF:       # %bb.0:
338; CHECKIF-NEXT:    fmv.w.x fa5, zero
339; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
340; CHECKIF-NEXT:    fmsub.s fa0, fa0, fa1, fa5
341; CHECKIF-NEXT:    ret
342;
343; RV32I-LABEL: fmsub_s:
344; RV32I:       # %bb.0:
345; RV32I-NEXT:    addi sp, sp, -16
346; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
347; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
348; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
349; RV32I-NEXT:    mv s0, a1
350; RV32I-NEXT:    mv s1, a0
351; RV32I-NEXT:    mv a0, a2
352; RV32I-NEXT:    li a1, 0
353; RV32I-NEXT:    call __addsf3
354; RV32I-NEXT:    lui a2, 524288
355; RV32I-NEXT:    xor a2, a0, a2
356; RV32I-NEXT:    mv a0, s1
357; RV32I-NEXT:    mv a1, s0
358; RV32I-NEXT:    call fmaf
359; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
360; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
361; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
362; RV32I-NEXT:    addi sp, sp, 16
363; RV32I-NEXT:    ret
364;
365; RV64I-LABEL: fmsub_s:
366; RV64I:       # %bb.0:
367; RV64I-NEXT:    addi sp, sp, -32
368; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
369; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
370; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
371; RV64I-NEXT:    mv s0, a1
372; RV64I-NEXT:    mv s1, a0
373; RV64I-NEXT:    mv a0, a2
374; RV64I-NEXT:    li a1, 0
375; RV64I-NEXT:    call __addsf3
376; RV64I-NEXT:    lui a2, 524288
377; RV64I-NEXT:    xor a2, a0, a2
378; RV64I-NEXT:    mv a0, s1
379; RV64I-NEXT:    mv a1, s0
380; RV64I-NEXT:    call fmaf
381; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
382; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
383; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
384; RV64I-NEXT:    addi sp, sp, 32
385; RV64I-NEXT:    ret
386;
387; CHECKIZFINX-LABEL: fmsub_s:
388; CHECKIZFINX:       # %bb.0:
389; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
390; CHECKIZFINX-NEXT:    fmsub.s a0, a0, a1, a2
391; CHECKIZFINX-NEXT:    ret
392  %c_ = fadd float 0.0, %c ; avoid negation using xor
393  %negc = fneg float %c_
394  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %b, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
395  ret float %1
396}
397
398define float @fnmadd_s(float %a, float %b, float %c) nounwind strictfp {
399; CHECKIF-LABEL: fnmadd_s:
400; CHECKIF:       # %bb.0:
401; CHECKIF-NEXT:    fmv.w.x fa5, zero
402; CHECKIF-NEXT:    fadd.s fa4, fa0, fa5
403; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
404; CHECKIF-NEXT:    fnmadd.s fa0, fa4, fa1, fa5
405; CHECKIF-NEXT:    ret
406;
407; RV32I-LABEL: fnmadd_s:
408; RV32I:       # %bb.0:
409; RV32I-NEXT:    addi sp, sp, -16
410; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
411; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
412; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
413; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
414; RV32I-NEXT:    mv s0, a2
415; RV32I-NEXT:    mv s1, a1
416; RV32I-NEXT:    li a1, 0
417; RV32I-NEXT:    call __addsf3
418; RV32I-NEXT:    mv s2, a0
419; RV32I-NEXT:    mv a0, s0
420; RV32I-NEXT:    li a1, 0
421; RV32I-NEXT:    call __addsf3
422; RV32I-NEXT:    lui a2, 524288
423; RV32I-NEXT:    xor a1, s2, a2
424; RV32I-NEXT:    xor a2, a0, a2
425; RV32I-NEXT:    mv a0, a1
426; RV32I-NEXT:    mv a1, s1
427; RV32I-NEXT:    call fmaf
428; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
429; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
430; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
431; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
432; RV32I-NEXT:    addi sp, sp, 16
433; RV32I-NEXT:    ret
434;
435; RV64I-LABEL: fnmadd_s:
436; RV64I:       # %bb.0:
437; RV64I-NEXT:    addi sp, sp, -32
438; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
439; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
440; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
441; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
442; RV64I-NEXT:    mv s0, a2
443; RV64I-NEXT:    mv s1, a1
444; RV64I-NEXT:    li a1, 0
445; RV64I-NEXT:    call __addsf3
446; RV64I-NEXT:    mv s2, a0
447; RV64I-NEXT:    mv a0, s0
448; RV64I-NEXT:    li a1, 0
449; RV64I-NEXT:    call __addsf3
450; RV64I-NEXT:    lui a2, 524288
451; RV64I-NEXT:    xor a1, s2, a2
452; RV64I-NEXT:    xor a2, a0, a2
453; RV64I-NEXT:    mv a0, a1
454; RV64I-NEXT:    mv a1, s1
455; RV64I-NEXT:    call fmaf
456; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
457; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
458; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
459; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
460; RV64I-NEXT:    addi sp, sp, 32
461; RV64I-NEXT:    ret
462;
463; CHECKIZFINX-LABEL: fnmadd_s:
464; CHECKIZFINX:       # %bb.0:
465; CHECKIZFINX-NEXT:    fadd.s a0, a0, zero
466; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
467; CHECKIZFINX-NEXT:    fnmadd.s a0, a0, a1, a2
468; CHECKIZFINX-NEXT:    ret
469  %a_ = fadd float 0.0, %a
470  %c_ = fadd float 0.0, %c
471  %nega = fneg float %a_
472  %negc = fneg float %c_
473  %1 = call float @llvm.experimental.constrained.fma.f32(float %nega, float %b, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
474  ret float %1
475}
476
477define float @fnmadd_s_2(float %a, float %b, float %c) nounwind strictfp {
478; CHECKIF-LABEL: fnmadd_s_2:
479; CHECKIF:       # %bb.0:
480; CHECKIF-NEXT:    fmv.w.x fa5, zero
481; CHECKIF-NEXT:    fadd.s fa4, fa1, fa5
482; CHECKIF-NEXT:    fadd.s fa5, fa2, fa5
483; CHECKIF-NEXT:    fnmadd.s fa0, fa4, fa0, fa5
484; CHECKIF-NEXT:    ret
485;
486; RV32I-LABEL: fnmadd_s_2:
487; RV32I:       # %bb.0:
488; RV32I-NEXT:    addi sp, sp, -16
489; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
490; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
491; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
492; RV32I-NEXT:    sw s2, 0(sp) # 4-byte Folded Spill
493; RV32I-NEXT:    mv s0, a2
494; RV32I-NEXT:    mv s1, a0
495; RV32I-NEXT:    mv a0, a1
496; RV32I-NEXT:    li a1, 0
497; RV32I-NEXT:    call __addsf3
498; RV32I-NEXT:    mv s2, a0
499; RV32I-NEXT:    mv a0, s0
500; RV32I-NEXT:    li a1, 0
501; RV32I-NEXT:    call __addsf3
502; RV32I-NEXT:    lui a2, 524288
503; RV32I-NEXT:    xor a1, s2, a2
504; RV32I-NEXT:    xor a2, a0, a2
505; RV32I-NEXT:    mv a0, s1
506; RV32I-NEXT:    call fmaf
507; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
508; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
509; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
510; RV32I-NEXT:    lw s2, 0(sp) # 4-byte Folded Reload
511; RV32I-NEXT:    addi sp, sp, 16
512; RV32I-NEXT:    ret
513;
514; RV64I-LABEL: fnmadd_s_2:
515; RV64I:       # %bb.0:
516; RV64I-NEXT:    addi sp, sp, -32
517; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
518; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
519; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
520; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
521; RV64I-NEXT:    mv s0, a2
522; RV64I-NEXT:    mv s1, a0
523; RV64I-NEXT:    mv a0, a1
524; RV64I-NEXT:    li a1, 0
525; RV64I-NEXT:    call __addsf3
526; RV64I-NEXT:    mv s2, a0
527; RV64I-NEXT:    mv a0, s0
528; RV64I-NEXT:    li a1, 0
529; RV64I-NEXT:    call __addsf3
530; RV64I-NEXT:    lui a2, 524288
531; RV64I-NEXT:    xor a1, s2, a2
532; RV64I-NEXT:    xor a2, a0, a2
533; RV64I-NEXT:    mv a0, s1
534; RV64I-NEXT:    call fmaf
535; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
536; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
537; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
538; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
539; RV64I-NEXT:    addi sp, sp, 32
540; RV64I-NEXT:    ret
541;
542; CHECKIZFINX-LABEL: fnmadd_s_2:
543; CHECKIZFINX:       # %bb.0:
544; CHECKIZFINX-NEXT:    fadd.s a1, a1, zero
545; CHECKIZFINX-NEXT:    fadd.s a2, a2, zero
546; CHECKIZFINX-NEXT:    fnmadd.s a0, a1, a0, a2
547; CHECKIZFINX-NEXT:    ret
548  %b_ = fadd float 0.0, %b
549  %c_ = fadd float 0.0, %c
550  %negb = fneg float %b_
551  %negc = fneg float %c_
552  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %negb, float %negc, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
553  ret float %1
554}
555
556define float @fnmsub_s(float %a, float %b, float %c) nounwind strictfp {
557; CHECKIF-LABEL: fnmsub_s:
558; CHECKIF:       # %bb.0:
559; CHECKIF-NEXT:    fmv.w.x fa5, zero
560; CHECKIF-NEXT:    fadd.s fa5, fa0, fa5
561; CHECKIF-NEXT:    fnmsub.s fa0, fa5, fa1, fa2
562; CHECKIF-NEXT:    ret
563;
564; RV32I-LABEL: fnmsub_s:
565; RV32I:       # %bb.0:
566; RV32I-NEXT:    addi sp, sp, -16
567; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
568; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
569; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
570; RV32I-NEXT:    mv s0, a2
571; RV32I-NEXT:    mv s1, a1
572; RV32I-NEXT:    li a1, 0
573; RV32I-NEXT:    call __addsf3
574; RV32I-NEXT:    lui a1, 524288
575; RV32I-NEXT:    xor a0, a0, a1
576; RV32I-NEXT:    mv a1, s1
577; RV32I-NEXT:    mv a2, s0
578; RV32I-NEXT:    call fmaf
579; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
580; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
581; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
582; RV32I-NEXT:    addi sp, sp, 16
583; RV32I-NEXT:    ret
584;
585; RV64I-LABEL: fnmsub_s:
586; RV64I:       # %bb.0:
587; RV64I-NEXT:    addi sp, sp, -32
588; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
589; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
590; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
591; RV64I-NEXT:    mv s0, a2
592; RV64I-NEXT:    mv s1, a1
593; RV64I-NEXT:    li a1, 0
594; RV64I-NEXT:    call __addsf3
595; RV64I-NEXT:    lui a1, 524288
596; RV64I-NEXT:    xor a0, a0, a1
597; RV64I-NEXT:    mv a1, s1
598; RV64I-NEXT:    mv a2, s0
599; RV64I-NEXT:    call fmaf
600; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
601; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
602; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
603; RV64I-NEXT:    addi sp, sp, 32
604; RV64I-NEXT:    ret
605;
606; CHECKIZFINX-LABEL: fnmsub_s:
607; CHECKIZFINX:       # %bb.0:
608; CHECKIZFINX-NEXT:    fadd.s a0, a0, zero
609; CHECKIZFINX-NEXT:    fnmsub.s a0, a0, a1, a2
610; CHECKIZFINX-NEXT:    ret
611  %a_ = fadd float 0.0, %a
612  %nega = fneg float %a_
613  %1 = call float @llvm.experimental.constrained.fma.f32(float %nega, float %b, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
614  ret float %1
615}
616
617define float @fnmsub_s_2(float %a, float %b, float %c) nounwind strictfp {
618; CHECKIF-LABEL: fnmsub_s_2:
619; CHECKIF:       # %bb.0:
620; CHECKIF-NEXT:    fmv.w.x fa5, zero
621; CHECKIF-NEXT:    fadd.s fa5, fa1, fa5
622; CHECKIF-NEXT:    fnmsub.s fa0, fa5, fa0, fa2
623; CHECKIF-NEXT:    ret
624;
625; RV32I-LABEL: fnmsub_s_2:
626; RV32I:       # %bb.0:
627; RV32I-NEXT:    addi sp, sp, -16
628; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
629; RV32I-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
630; RV32I-NEXT:    sw s1, 4(sp) # 4-byte Folded Spill
631; RV32I-NEXT:    mv s0, a2
632; RV32I-NEXT:    mv s1, a0
633; RV32I-NEXT:    mv a0, a1
634; RV32I-NEXT:    li a1, 0
635; RV32I-NEXT:    call __addsf3
636; RV32I-NEXT:    lui a1, 524288
637; RV32I-NEXT:    xor a1, a0, a1
638; RV32I-NEXT:    mv a0, s1
639; RV32I-NEXT:    mv a2, s0
640; RV32I-NEXT:    call fmaf
641; RV32I-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
642; RV32I-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
643; RV32I-NEXT:    lw s1, 4(sp) # 4-byte Folded Reload
644; RV32I-NEXT:    addi sp, sp, 16
645; RV32I-NEXT:    ret
646;
647; RV64I-LABEL: fnmsub_s_2:
648; RV64I:       # %bb.0:
649; RV64I-NEXT:    addi sp, sp, -32
650; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
651; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
652; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
653; RV64I-NEXT:    mv s0, a2
654; RV64I-NEXT:    mv s1, a0
655; RV64I-NEXT:    mv a0, a1
656; RV64I-NEXT:    li a1, 0
657; RV64I-NEXT:    call __addsf3
658; RV64I-NEXT:    lui a1, 524288
659; RV64I-NEXT:    xor a1, a0, a1
660; RV64I-NEXT:    mv a0, s1
661; RV64I-NEXT:    mv a2, s0
662; RV64I-NEXT:    call fmaf
663; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
664; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
665; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
666; RV64I-NEXT:    addi sp, sp, 32
667; RV64I-NEXT:    ret
668;
669; CHECKIZFINX-LABEL: fnmsub_s_2:
670; CHECKIZFINX:       # %bb.0:
671; CHECKIZFINX-NEXT:    fadd.s a1, a1, zero
672; CHECKIZFINX-NEXT:    fnmsub.s a0, a1, a0, a2
673; CHECKIZFINX-NEXT:    ret
674  %b_ = fadd float 0.0, %b
675  %negb = fneg float %b_
676  %1 = call float @llvm.experimental.constrained.fma.f32(float %a, float %negb, float %c, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
677  ret float %1
678}
679