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 \
4 ; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfh < %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
11 declare half @llvm.minimum.f16(half, half)
13 define half @fminm_h(half %a, half %b) nounwind {
14 ; CHECK-LABEL: fminm_h:
16 ; CHECK-NEXT: fminm.h fa0, fa0, fa1
19 ; ZFHMIN-LABEL: fminm_h:
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
26 %1 = call half @llvm.minimum.f16(half %a, half %b)
30 declare half @llvm.maximum.f16(half, half)
32 define half @fmaxm_h(half %a, half %b) nounwind {
33 ; CHECK-LABEL: fmaxm_h:
35 ; CHECK-NEXT: fmaxm.h fa0, fa0, fa1
38 ; ZFHMIN-LABEL: fmaxm_h:
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
45 %1 = tail call half @llvm.maximum.f16(half %a, half %b)
49 define half @fround_h_1(half %a) nounwind {
50 ; CHECK-LABEL: fround_h_1:
52 ; CHECK-NEXT: fround.h fa0, fa0, rmm
55 ; ZFHMIN-LABEL: fround_h_1:
57 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
58 ; ZFHMIN-NEXT: fround.s fa5, fa5, rmm
59 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
61 %call = tail call half @llvm.round.f16(half %a) nounwind readnone
65 declare half @llvm.round.f16(half) nounwind readnone
68 define half @fround_h_2(half %a) nounwind {
69 ; CHECK-LABEL: fround_h_2:
71 ; CHECK-NEXT: fround.h fa0, fa0, rdn
74 ; ZFHMIN-LABEL: fround_h_2:
76 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
77 ; ZFHMIN-NEXT: fround.s fa5, fa5, rdn
78 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
80 %call = tail call half @llvm.floor.f16(half %a) nounwind readnone
84 declare half @llvm.floor.f16(half) nounwind readnone
87 define half @fround_h_3(half %a) nounwind {
88 ; CHECK-LABEL: fround_h_3:
90 ; CHECK-NEXT: fround.h fa0, fa0, rup
93 ; ZFHMIN-LABEL: fround_h_3:
95 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
96 ; ZFHMIN-NEXT: fround.s fa5, fa5, rup
97 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
99 %call = tail call half @llvm.ceil.f16(half %a) nounwind readnone
103 declare half @llvm.ceil.f16(half) nounwind readnone
106 define half @fround_h_4(half %a) nounwind {
107 ; CHECK-LABEL: fround_h_4:
109 ; CHECK-NEXT: fround.h fa0, fa0, rtz
112 ; ZFHMIN-LABEL: fround_h_4:
114 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
115 ; ZFHMIN-NEXT: fround.s fa5, fa5, rtz
116 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
118 %call = tail call half @llvm.trunc.f16(half %a) nounwind readnone
122 declare half @llvm.trunc.f16(half) nounwind readnone
125 define half @fround_h_5(half %a) nounwind {
126 ; CHECK-LABEL: fround_h_5:
128 ; CHECK-NEXT: fround.h fa0, fa0
131 ; ZFHMIN-LABEL: fround_h_5:
133 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
134 ; ZFHMIN-NEXT: fround.s fa5, fa5
135 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
137 %call = tail call half @llvm.nearbyint.f16(half %a) nounwind readnone
141 declare half @llvm.nearbyint.f16(half) nounwind readnone
144 define half @froundnx_h(half %a) nounwind {
145 ; CHECK-LABEL: froundnx_h:
147 ; CHECK-NEXT: froundnx.h fa0, fa0
150 ; ZFHMIN-LABEL: froundnx_h:
152 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
153 ; ZFHMIN-NEXT: froundnx.s fa5, fa5
154 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
156 %call = tail call half @llvm.rint.f16(half %a) nounwind readnone
160 declare half @llvm.rint.f16(half) nounwind readnone
162 declare i1 @llvm.experimental.constrained.fcmp.f16(half, half, metadata, metadata)
164 define i32 @fcmp_olt_q(half %a, half %b) nounwind strictfp {
165 ; CHECK-LABEL: fcmp_olt_q:
167 ; CHECK-NEXT: fltq.h a0, fa0, fa1
170 ; ZFHMIN-LABEL: fcmp_olt_q:
172 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
173 ; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
174 ; ZFHMIN-NEXT: fltq.s a0, fa4, fa5
176 %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") strictfp
177 %2 = zext i1 %1 to i32
181 define i32 @fcmp_ole_q(half %a, half %b) nounwind strictfp {
182 ; CHECK-LABEL: fcmp_ole_q:
184 ; CHECK-NEXT: fleq.h a0, fa0, fa1
187 ; ZFHMIN-LABEL: fcmp_ole_q:
189 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
190 ; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
191 ; ZFHMIN-NEXT: fleq.s a0, fa4, fa5
193 %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") strictfp
194 %2 = zext i1 %1 to i32
198 define i32 @fcmp_one_q(half %a, half %b) nounwind strictfp {
199 ; CHECK-LABEL: fcmp_one_q:
201 ; CHECK-NEXT: fltq.h a0, fa0, fa1
202 ; CHECK-NEXT: fltq.h a1, fa1, fa0
203 ; CHECK-NEXT: or a0, a1, a0
206 ; ZFHMIN-LABEL: fcmp_one_q:
208 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
209 ; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
210 ; ZFHMIN-NEXT: fltq.s a0, fa4, fa5
211 ; ZFHMIN-NEXT: fltq.s a1, fa5, fa4
212 ; ZFHMIN-NEXT: or a0, a1, a0
214 %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") strictfp
215 %2 = zext i1 %1 to i32
219 define i32 @fcmp_ueq_q(half %a, half %b) nounwind strictfp {
220 ; CHECK-LABEL: fcmp_ueq_q:
222 ; CHECK-NEXT: fltq.h a0, fa0, fa1
223 ; CHECK-NEXT: fltq.h a1, fa1, fa0
224 ; CHECK-NEXT: or a0, a1, a0
225 ; CHECK-NEXT: xori a0, a0, 1
228 ; ZFHMIN-LABEL: fcmp_ueq_q:
230 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
231 ; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
232 ; ZFHMIN-NEXT: fltq.s a0, fa4, fa5
233 ; ZFHMIN-NEXT: fltq.s a1, fa5, fa4
234 ; ZFHMIN-NEXT: or a0, a1, a0
235 ; ZFHMIN-NEXT: xori a0, a0, 1
237 %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp
238 %2 = zext i1 %1 to i32
242 define half @fadd_neg_0p5(half %x) {
243 ; CHECK-LABEL: fadd_neg_0p5:
245 ; CHECK-NEXT: fli.h fa5, 0.5
246 ; CHECK-NEXT: fsub.h fa0, fa0, fa5
249 ; ZFHMIN-LABEL: fadd_neg_0p5:
251 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
252 ; ZFHMIN-NEXT: fli.s fa4, 0.5
253 ; ZFHMIN-NEXT: fsub.s fa5, fa5, fa4
254 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
256 %a = fadd half %x, -0.5
260 define half @fma_neg_addend(half %x, half %y) nounwind {
261 ; CHECK-LABEL: fma_neg_addend:
263 ; CHECK-NEXT: fli.h fa5, 0.5
264 ; CHECK-NEXT: fmsub.h fa0, fa0, fa1, fa5
267 ; ZFHMIN-LABEL: fma_neg_addend:
269 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
270 ; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
271 ; ZFHMIN-NEXT: fli.s fa3, 0.5
272 ; ZFHMIN-NEXT: fmsub.s fa5, fa4, fa5, fa3
273 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
275 %a = call half @llvm.fma.f32(half %x, half %y, half -0.5)
279 define half @fma_neg_multiplicand(half %x, half %y) nounwind {
280 ; CHECK-LABEL: fma_neg_multiplicand:
282 ; CHECK-NEXT: fli.h fa5, 0.125
283 ; CHECK-NEXT: fnmsub.h fa0, fa5, fa0, fa1
286 ; ZFHMIN-LABEL: fma_neg_multiplicand:
288 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa1
289 ; ZFHMIN-NEXT: fcvt.s.h fa4, fa0
290 ; ZFHMIN-NEXT: fli.s fa3, 0.125
291 ; ZFHMIN-NEXT: fnmsub.s fa5, fa3, fa4, fa5
292 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
294 %a = call half @llvm.fma.f32(half %x, half -0.125, half %y)
298 define half @fma_neg_addend_multiplicand(half %x) nounwind {
299 ; CHECK-LABEL: fma_neg_addend_multiplicand:
301 ; CHECK-NEXT: fli.h fa5, 0.25
302 ; CHECK-NEXT: fli.h fa4, 0.5
303 ; CHECK-NEXT: fnmadd.h fa0, fa4, fa0, fa5
306 ; ZFHMIN-LABEL: fma_neg_addend_multiplicand:
308 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
309 ; ZFHMIN-NEXT: fli.s fa4, 0.25
310 ; ZFHMIN-NEXT: fli.s fa3, 0.5
311 ; ZFHMIN-NEXT: fnmadd.s fa5, fa3, fa5, fa4
312 ; ZFHMIN-NEXT: fcvt.h.s fa0, fa5
314 %a = call half @llvm.fma.f32(half %x, half -0.5, half -0.25)
318 define half @select_loadfpimm(half %x) nounwind {
319 ; CHECK-LABEL: select_loadfpimm:
320 ; CHECK: # %bb.0: # %entry
321 ; CHECK-NEXT: fmv.h.x fa5, zero
322 ; CHECK-NEXT: fle.h a0, fa5, fa0
323 ; CHECK-NEXT: fli.h fa0, 0.5
324 ; CHECK-NEXT: bnez a0, .LBB16_2
325 ; CHECK-NEXT: # %bb.1:
326 ; CHECK-NEXT: fneg.h fa0, fa0
327 ; CHECK-NEXT: .LBB16_2: # %entry
330 ; ZFHMIN-LABEL: select_loadfpimm:
331 ; ZFHMIN: # %bb.0: # %entry
332 ; ZFHMIN-NEXT: fcvt.s.h fa5, fa0
333 ; ZFHMIN-NEXT: fmv.w.x fa4, zero
334 ; ZFHMIN-NEXT: fle.s a0, fa4, fa5
335 ; ZFHMIN-NEXT: xori a0, a0, 1
336 ; ZFHMIN-NEXT: slli a0, a0, 1
337 ; ZFHMIN-NEXT: lui a1, %hi(.LCPI16_0)
338 ; ZFHMIN-NEXT: addi a1, a1, %lo(.LCPI16_0)
339 ; ZFHMIN-NEXT: add a0, a1, a0
340 ; ZFHMIN-NEXT: flh fa0, 0(a0)
343 %cmp = fcmp ult half %x, 0.000000e+00
344 %sel = select i1 %cmp, half -5.000000e-01, half 5.000000e-01