xref: /llvm-project/llvm/test/CodeGen/RISCV/half-zfa.ll (revision 261d4bbb3bb847b90b9734daefe13618dea91613)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zfa,+zfh < %s \
3; RUN:     | FileCheck %s
4; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfh < %s \
5; RUN:     | FileCheck %s
6; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zfa,+zfhmin < %s \
7; RUN:     | FileCheck %s --check-prefix=ZFHMIN
8; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfhmin < %s \
9; RUN:     | FileCheck %s --check-prefix=ZFHMIN
10
11declare half @llvm.minimum.f16(half, half)
12
13define half @fminm_h(half %a, half %b) nounwind {
14; CHECK-LABEL: fminm_h:
15; CHECK:       # %bb.0:
16; CHECK-NEXT:    fminm.h fa0, fa0, fa1
17; CHECK-NEXT:    ret
18;
19; ZFHMIN-LABEL: fminm_h:
20; ZFHMIN:       # %bb.0:
21; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
22; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
23; ZFHMIN-NEXT:    fminm.s fa5, fa4, fa5
24; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
25; ZFHMIN-NEXT:    ret
26  %1 = call half @llvm.minimum.f16(half %a, half %b)
27  ret half %1
28}
29
30declare half @llvm.maximum.f16(half, half)
31
32define half @fmaxm_h(half %a, half %b) nounwind {
33; CHECK-LABEL: fmaxm_h:
34; CHECK:       # %bb.0:
35; CHECK-NEXT:    fmaxm.h fa0, fa0, fa1
36; CHECK-NEXT:    ret
37;
38; ZFHMIN-LABEL: fmaxm_h:
39; ZFHMIN:       # %bb.0:
40; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
41; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
42; ZFHMIN-NEXT:    fmaxm.s fa5, fa4, fa5
43; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
44; ZFHMIN-NEXT:    ret
45  %1 = tail call half @llvm.maximum.f16(half %a, half %b)
46  ret half %1
47}
48
49define half @fround_h_1(half %a) nounwind {
50; CHECK-LABEL: fround_h_1:
51; CHECK:       # %bb.0:
52; CHECK-NEXT:    fround.h fa0, fa0, rmm
53; CHECK-NEXT:    ret
54;
55; ZFHMIN-LABEL: fround_h_1:
56; ZFHMIN:       # %bb.0:
57; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
58; ZFHMIN-NEXT:    fround.s fa5, fa5, rmm
59; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
60; ZFHMIN-NEXT:    ret
61  %call = tail call half @llvm.round.f16(half %a) nounwind readnone
62  ret half %call
63}
64
65declare half @llvm.round.f16(half) nounwind readnone
66
67
68define half @fround_h_2(half %a) nounwind {
69; CHECK-LABEL: fround_h_2:
70; CHECK:       # %bb.0:
71; CHECK-NEXT:    fround.h fa0, fa0, rdn
72; CHECK-NEXT:    ret
73;
74; ZFHMIN-LABEL: fround_h_2:
75; ZFHMIN:       # %bb.0:
76; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
77; ZFHMIN-NEXT:    fround.s fa5, fa5, rdn
78; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
79; ZFHMIN-NEXT:    ret
80  %call = tail call half @llvm.floor.f16(half %a) nounwind readnone
81  ret half %call
82}
83
84declare half @llvm.floor.f16(half) nounwind readnone
85
86
87define half @fround_h_3(half %a) nounwind {
88; CHECK-LABEL: fround_h_3:
89; CHECK:       # %bb.0:
90; CHECK-NEXT:    fround.h fa0, fa0, rup
91; CHECK-NEXT:    ret
92;
93; ZFHMIN-LABEL: fround_h_3:
94; ZFHMIN:       # %bb.0:
95; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
96; ZFHMIN-NEXT:    fround.s fa5, fa5, rup
97; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
98; ZFHMIN-NEXT:    ret
99  %call = tail call half @llvm.ceil.f16(half %a) nounwind readnone
100  ret half %call
101}
102
103declare half @llvm.ceil.f16(half) nounwind readnone
104
105
106define half @fround_h_4(half %a) nounwind {
107; CHECK-LABEL: fround_h_4:
108; CHECK:       # %bb.0:
109; CHECK-NEXT:    fround.h fa0, fa0, rtz
110; CHECK-NEXT:    ret
111;
112; ZFHMIN-LABEL: fround_h_4:
113; ZFHMIN:       # %bb.0:
114; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
115; ZFHMIN-NEXT:    fround.s fa5, fa5, rtz
116; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
117; ZFHMIN-NEXT:    ret
118  %call = tail call half @llvm.trunc.f16(half %a) nounwind readnone
119  ret half %call
120}
121
122declare half @llvm.trunc.f16(half) nounwind readnone
123
124
125define half @fround_h_5(half %a) nounwind {
126; CHECK-LABEL: fround_h_5:
127; CHECK:       # %bb.0:
128; CHECK-NEXT:    fround.h fa0, fa0
129; CHECK-NEXT:    ret
130;
131; ZFHMIN-LABEL: fround_h_5:
132; ZFHMIN:       # %bb.0:
133; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
134; ZFHMIN-NEXT:    fround.s fa5, fa5
135; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
136; ZFHMIN-NEXT:    ret
137  %call = tail call half @llvm.nearbyint.f16(half %a) nounwind readnone
138  ret half %call
139}
140
141declare half @llvm.nearbyint.f16(half) nounwind readnone
142
143define half @fround_h_6(half %a) nounwind {
144; CHECK-LABEL: fround_h_6:
145; CHECK:       # %bb.0:
146; CHECK-NEXT:    fround.h fa0, fa0, rne
147; CHECK-NEXT:    ret
148;
149; ZFHMIN-LABEL: fround_h_6:
150; ZFHMIN:       # %bb.0:
151; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
152; ZFHMIN-NEXT:    fround.s fa5, fa5, rne
153; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
154; ZFHMIN-NEXT:    ret
155  %call = tail call half @llvm.roundeven.f16(half %a) nounwind readnone
156  ret half %call
157}
158
159declare half @llvm.roundeven.f16(half) nounwind readnone
160
161
162define half @froundnx_h(half %a) nounwind {
163; CHECK-LABEL: froundnx_h:
164; CHECK:       # %bb.0:
165; CHECK-NEXT:    froundnx.h fa0, fa0
166; CHECK-NEXT:    ret
167;
168; ZFHMIN-LABEL: froundnx_h:
169; ZFHMIN:       # %bb.0:
170; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
171; ZFHMIN-NEXT:    froundnx.s fa5, fa5
172; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
173; ZFHMIN-NEXT:    ret
174  %call = tail call half @llvm.rint.f16(half %a) nounwind readnone
175  ret half %call
176}
177
178declare half @llvm.rint.f16(half) nounwind readnone
179
180declare i1 @llvm.experimental.constrained.fcmp.f16(half, half, metadata, metadata)
181
182define i32 @fcmp_olt_q(half %a, half %b) nounwind strictfp {
183; CHECK-LABEL: fcmp_olt_q:
184; CHECK:       # %bb.0:
185; CHECK-NEXT:    fltq.h a0, fa0, fa1
186; CHECK-NEXT:    ret
187;
188; ZFHMIN-LABEL: fcmp_olt_q:
189; ZFHMIN:       # %bb.0:
190; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
191; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
192; ZFHMIN-NEXT:    fltq.s a0, fa4, fa5
193; ZFHMIN-NEXT:    ret
194  %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") strictfp
195  %2 = zext i1 %1 to i32
196  ret i32 %2
197}
198
199define i32 @fcmp_ole_q(half %a, half %b) nounwind strictfp {
200; CHECK-LABEL: fcmp_ole_q:
201; CHECK:       # %bb.0:
202; CHECK-NEXT:    fleq.h a0, fa0, fa1
203; CHECK-NEXT:    ret
204;
205; ZFHMIN-LABEL: fcmp_ole_q:
206; ZFHMIN:       # %bb.0:
207; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
208; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
209; ZFHMIN-NEXT:    fleq.s a0, fa4, fa5
210; ZFHMIN-NEXT:    ret
211  %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") strictfp
212  %2 = zext i1 %1 to i32
213  ret i32 %2
214}
215
216define i32 @fcmp_one_q(half %a, half %b) nounwind strictfp {
217; CHECK-LABEL: fcmp_one_q:
218; CHECK:       # %bb.0:
219; CHECK-NEXT:    fltq.h a0, fa0, fa1
220; CHECK-NEXT:    fltq.h a1, fa1, fa0
221; CHECK-NEXT:    or a0, a1, a0
222; CHECK-NEXT:    ret
223;
224; ZFHMIN-LABEL: fcmp_one_q:
225; ZFHMIN:       # %bb.0:
226; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
227; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
228; ZFHMIN-NEXT:    fltq.s a0, fa4, fa5
229; ZFHMIN-NEXT:    fltq.s a1, fa5, fa4
230; ZFHMIN-NEXT:    or a0, a1, a0
231; ZFHMIN-NEXT:    ret
232  %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") strictfp
233  %2 = zext i1 %1 to i32
234  ret i32 %2
235}
236
237define i32 @fcmp_ueq_q(half %a, half %b) nounwind strictfp {
238; CHECK-LABEL: fcmp_ueq_q:
239; CHECK:       # %bb.0:
240; CHECK-NEXT:    fltq.h a0, fa0, fa1
241; CHECK-NEXT:    fltq.h a1, fa1, fa0
242; CHECK-NEXT:    or a0, a1, a0
243; CHECK-NEXT:    xori a0, a0, 1
244; CHECK-NEXT:    ret
245;
246; ZFHMIN-LABEL: fcmp_ueq_q:
247; ZFHMIN:       # %bb.0:
248; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
249; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
250; ZFHMIN-NEXT:    fltq.s a0, fa4, fa5
251; ZFHMIN-NEXT:    fltq.s a1, fa5, fa4
252; ZFHMIN-NEXT:    or a0, a1, a0
253; ZFHMIN-NEXT:    xori a0, a0, 1
254; ZFHMIN-NEXT:    ret
255  %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp
256  %2 = zext i1 %1 to i32
257  ret i32 %2
258}
259
260define half @fadd_neg_0p5(half %x) {
261; CHECK-LABEL: fadd_neg_0p5:
262; CHECK:       # %bb.0:
263; CHECK-NEXT:    fli.h fa5, 0.5
264; CHECK-NEXT:    fsub.h fa0, fa0, fa5
265; CHECK-NEXT:    ret
266;
267; ZFHMIN-LABEL: fadd_neg_0p5:
268; ZFHMIN:       # %bb.0:
269; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
270; ZFHMIN-NEXT:    fli.s fa4, 0.5
271; ZFHMIN-NEXT:    fsub.s fa5, fa5, fa4
272; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
273; ZFHMIN-NEXT:    ret
274  %a = fadd half %x, -0.5
275  ret half %a
276}
277
278define half @fma_neg_addend(half %x, half %y) nounwind {
279; CHECK-LABEL: fma_neg_addend:
280; CHECK:       # %bb.0:
281; CHECK-NEXT:    fli.h fa5, 0.5
282; CHECK-NEXT:    fmsub.h fa0, fa0, fa1, fa5
283; CHECK-NEXT:    ret
284;
285; ZFHMIN-LABEL: fma_neg_addend:
286; ZFHMIN:       # %bb.0:
287; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
288; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
289; ZFHMIN-NEXT:    fli.s fa3, 0.5
290; ZFHMIN-NEXT:    fmsub.s fa5, fa4, fa5, fa3
291; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
292; ZFHMIN-NEXT:    ret
293  %a = call half @llvm.fma.f32(half %x, half %y, half -0.5)
294  ret half %a
295}
296
297define half @fma_neg_multiplicand(half %x, half %y) nounwind {
298; CHECK-LABEL: fma_neg_multiplicand:
299; CHECK:       # %bb.0:
300; CHECK-NEXT:    fli.h fa5, 0.125
301; CHECK-NEXT:    fnmsub.h fa0, fa5, fa0, fa1
302; CHECK-NEXT:    ret
303;
304; ZFHMIN-LABEL: fma_neg_multiplicand:
305; ZFHMIN:       # %bb.0:
306; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
307; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
308; ZFHMIN-NEXT:    fli.s fa3, 0.125
309; ZFHMIN-NEXT:    fnmsub.s fa5, fa3, fa4, fa5
310; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
311; ZFHMIN-NEXT:    ret
312  %a = call half @llvm.fma.f32(half %x, half -0.125, half %y)
313  ret half %a
314}
315
316define half @fma_neg_addend_multiplicand(half %x) nounwind {
317; CHECK-LABEL: fma_neg_addend_multiplicand:
318; CHECK:       # %bb.0:
319; CHECK-NEXT:    fli.h fa5, 0.25
320; CHECK-NEXT:    fli.h fa4, 0.5
321; CHECK-NEXT:    fnmadd.h fa0, fa4, fa0, fa5
322; CHECK-NEXT:    ret
323;
324; ZFHMIN-LABEL: fma_neg_addend_multiplicand:
325; ZFHMIN:       # %bb.0:
326; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
327; ZFHMIN-NEXT:    fli.s fa4, 0.25
328; ZFHMIN-NEXT:    fli.s fa3, 0.5
329; ZFHMIN-NEXT:    fnmadd.s fa5, fa3, fa5, fa4
330; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
331; ZFHMIN-NEXT:    ret
332  %a = call half @llvm.fma.f32(half %x, half -0.5, half -0.25)
333  ret half %a
334}
335
336define half @select_loadfpimm(half %x) nounwind {
337; CHECK-LABEL: select_loadfpimm:
338; CHECK:       # %bb.0: # %entry
339; CHECK-NEXT:    fmv.h.x fa5, zero
340; CHECK-NEXT:    fle.h a0, fa5, fa0
341; CHECK-NEXT:    fli.h fa0, 0.5
342; CHECK-NEXT:    bnez a0, .LBB17_2
343; CHECK-NEXT:  # %bb.1:
344; CHECK-NEXT:    fneg.h fa0, fa0
345; CHECK-NEXT:  .LBB17_2: # %entry
346; CHECK-NEXT:    ret
347;
348; ZFHMIN-LABEL: select_loadfpimm:
349; ZFHMIN:       # %bb.0: # %entry
350; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
351; ZFHMIN-NEXT:    fmv.w.x fa4, zero
352; ZFHMIN-NEXT:    fle.s a0, fa4, fa5
353; ZFHMIN-NEXT:    xori a0, a0, 1
354; ZFHMIN-NEXT:    slli a0, a0, 1
355; ZFHMIN-NEXT:    lui a1, %hi(.LCPI17_0)
356; ZFHMIN-NEXT:    addi a1, a1, %lo(.LCPI17_0)
357; ZFHMIN-NEXT:    add a0, a1, a0
358; ZFHMIN-NEXT:    flh fa0, 0(a0)
359; ZFHMIN-NEXT:    ret
360entry:
361  %cmp = fcmp ult half %x, 0.000000e+00
362  %sel = select i1 %cmp, half -5.000000e-01, half 5.000000e-01
363  ret half %sel
364}
365