1 ; RUN: llc < %s -mtriple=aarch64-eabi -mattr=+v8.2a,+fullfp16 | FileCheck %s
3 declare half @llvm.aarch64.sisd.fabd.f16(half, half)
4 declare half @llvm.aarch64.neon.fmax.f16(half, half)
5 declare half @llvm.aarch64.neon.fmin.f16(half, half)
6 declare half @llvm.aarch64.neon.frsqrts.f16(half, half)
7 declare half @llvm.aarch64.neon.frecps.f16(half, half)
8 declare half @llvm.aarch64.neon.fmulx.f16(half, half)
9 declare half @llvm.fabs.f16(half)
10 declare i32 @llvm.aarch64.neon.facge.i32.f16(half, half)
11 declare i32 @llvm.aarch64.neon.facgt.i32.f16(half, half)
13 define dso_local half @t_vabdh_f16(half %a, half %b) {
14 ; CHECK-LABEL: t_vabdh_f16:
15 ; CHECK: fabd h0, h0, h1
18 %vabdh_f16 = tail call half @llvm.aarch64.sisd.fabd.f16(half %a, half %b)
22 define dso_local half @t_vabdh_f16_from_fsub_fabs(half %a, half %b) {
23 ; CHECK-LABEL: t_vabdh_f16_from_fsub_fabs:
24 ; CHECK: fabd h0, h0, h1
27 %sub = fsub half %a, %b
28 %abs = tail call half @llvm.fabs.f16(half %sub)
32 define dso_local i16 @t_vceqh_f16(half %a, half %b) {
33 ; CHECK-LABEL: t_vceqh_f16:
35 ; CHECK-NEXT: csetm w0, eq
38 %0 = fcmp oeq half %a, %b
39 %vcmpd = sext i1 %0 to i16
43 define dso_local i16 @t_vcgeh_f16(half %a, half %b) {
44 ; CHECK-LABEL: t_vcgeh_f16:
46 ; CHECK-NEXT: csetm w0, ge
49 %0 = fcmp oge half %a, %b
50 %vcmpd = sext i1 %0 to i16
54 define dso_local i16 @t_vcgth_f16(half %a, half %b) {
55 ; CHECK-LABEL: t_vcgth_f16:
57 ; CHECK-NEXT: csetm w0, gt
60 %0 = fcmp ogt half %a, %b
61 %vcmpd = sext i1 %0 to i16
65 define dso_local i16 @t_vcleh_f16(half %a, half %b) {
66 ; CHECK-LABEL: t_vcleh_f16:
68 ; CHECK-NEXT: csetm w0, ls
71 %0 = fcmp ole half %a, %b
72 %vcmpd = sext i1 %0 to i16
76 define dso_local i16 @t_vclth_f16(half %a, half %b) {
77 ; CHECK-LABEL: t_vclth_f16:
79 ; CHECK-NEXT: csetm w0, mi
82 %0 = fcmp olt half %a, %b
83 %vcmpd = sext i1 %0 to i16
87 define dso_local half @t_vmaxh_f16(half %a, half %b) {
88 ; CHECK-LABEL: t_vmaxh_f16:
89 ; CHECK: fmax h0, h0, h1
92 %vmax = tail call half @llvm.aarch64.neon.fmax.f16(half %a, half %b)
96 define dso_local half @t_vminh_f16(half %a, half %b) {
97 ; CHECK-LABEL: t_vminh_f16:
98 ; CHECK: fmin h0, h0, h1
101 %vmin = tail call half @llvm.aarch64.neon.fmin.f16(half %a, half %b)
105 define dso_local half @t_vmulxh_f16(half %a, half %b) {
106 ; CHECK-LABEL: t_vmulxh_f16:
107 ; CHECK: fmulx h0, h0, h1
110 %vmulxh_f16 = tail call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b)
114 define dso_local half @t_vrecpsh_f16(half %a, half %b) {
115 ; CHECK-LABEL: t_vrecpsh_f16:
116 ; CHECK: frecps h0, h0, h1
119 %vrecps = tail call half @llvm.aarch64.neon.frecps.f16(half %a, half %b)
123 define dso_local half @t_vrsqrtsh_f16(half %a, half %b) {
124 ; CHECK-LABEL: t_vrsqrtsh_f16:
125 ; CHECK: frsqrts h0, h0, h1
128 %vrsqrtsh_f16 = tail call half @llvm.aarch64.neon.frsqrts.f16(half %a, half %b)
129 ret half %vrsqrtsh_f16
132 declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32, i32) #1
133 declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64, i32) #1
134 declare i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half, i32) #1
135 declare i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half, i32) #1
136 declare half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32, i32) #1
137 declare i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half, i32) #1
139 define dso_local half @test_vcvth_n_f16_s16_1(i16 %a) {
140 ; CHECK-LABEL: test_vcvth_n_f16_s16_1:
141 ; CHECK: fmov s0, w[[wReg:[0-9]+]]
142 ; CHECK-NEXT: scvtf h0, h0, #1
145 %sext = sext i16 %a to i32
146 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 1)
150 define dso_local half @test_vcvth_n_f16_s16_16(i16 %a) {
151 ; CHECK-LABEL: test_vcvth_n_f16_s16_16:
152 ; CHECK: fmov s0, w[[wReg:[0-9]+]]
153 ; CHECK-NEXT: scvtf h0, h0, #16
156 %sext = sext i16 %a to i32
157 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 16)
161 define dso_local half @test_vcvth_n_f16_s32_1(i32 %a) {
162 ; CHECK-LABEL: test_vcvth_n_f16_s32_1:
164 ; CHECK-NEXT: scvtf h0, h0, #1
167 %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 1)
168 ret half %vcvth_n_f16_s32
171 define dso_local half @test_vcvth_n_f16_s32_16(i32 %a) {
172 ; CHECK-LABEL: test_vcvth_n_f16_s32_16:
174 ; CHECK-NEXT: scvtf h0, h0, #16
177 %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 16)
178 ret half %vcvth_n_f16_s32
181 define dso_local i16 @test_vcvth_n_s16_f16_1(half %a) {
182 ; CHECK-LABEL: test_vcvth_n_s16_f16_1:
183 ; CHECK: fcvtzs h0, h0, #1
184 ; CHECK-NEXT: fmov w0, s0
187 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
188 %0 = trunc i32 %fcvth_n to i16
192 define dso_local i16 @test_vcvth_n_s16_f16_16(half %a) {
193 ; CHECK-LABEL: test_vcvth_n_s16_f16_16:
194 ; CHECK: fcvtzs h0, h0, #16
195 ; CHECK-NEXT: fmov w0, s0
198 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16)
199 %0 = trunc i32 %fcvth_n to i16
203 define dso_local i32 @test_vcvth_n_s32_f16_1(half %a) {
204 ; CHECK-LABEL: test_vcvth_n_s32_f16_1:
205 ; CHECK: fcvtzs h0, h0, #1
206 ; CHECK-NEXT: fmov w0, s0
209 %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
210 ret i32 %vcvth_n_s32_f16
213 define dso_local i32 @test_vcvth_n_s32_f16_16(half %a) {
214 ; CHECK-LABEL: test_vcvth_n_s32_f16_16:
215 ; CHECK: fcvtzs h0, h0, #16
216 ; CHECK-NEXT: fmov w0, s0
219 %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16)
220 ret i32 %vcvth_n_s32_f16
223 define dso_local i64 @test_vcvth_n_s64_f16_1(half %a) {
224 ; CHECK-LABEL: test_vcvth_n_s64_f16_1:
225 ; CHECK: fcvtzs h0, h0, #1
226 ; CHECK-NEXT: fmov x0, d0
229 %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 1)
230 ret i64 %vcvth_n_s64_f16
233 define dso_local i64 @test_vcvth_n_s64_f16_32(half %a) {
234 ; CHECK-LABEL: test_vcvth_n_s64_f16_32:
235 ; CHECK: fcvtzs h0, h0, #32
236 ; CHECK-NEXT: fmov x0, d0
239 %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 32)
240 ret i64 %vcvth_n_s64_f16
243 define dso_local half @test_vcvth_n_f16_u16_1(i16 %a) {
244 ; CHECK-LABEL: test_vcvth_n_f16_u16_1:
245 ; CHECK: ucvtf h0, h0, #1
248 %0 = zext i16 %a to i32
249 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 1)
253 define dso_local half @test_vcvth_n_f16_u16_16(i16 %a) {
254 ; CHECK-LABEL: test_vcvth_n_f16_u16_16:
255 ; CHECK: ucvtf h0, h0, #16
258 %0 = zext i16 %a to i32
259 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 16)
263 define dso_local half @test_vcvth_n_f16_u32_1(i32 %a) {
264 ; CHECK-LABEL: test_vcvth_n_f16_u32_1:
266 ; CHECK-NEXT: ucvtf h0, h0, #1
269 %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 1)
270 ret half %vcvth_n_f16_u32
273 define dso_local half @test_vcvth_n_f16_u32_16(i32 %a) {
274 ; CHECK-LABEL: test_vcvth_n_f16_u32_16:
275 ; CHECK: ucvtf h0, h0, #16
278 %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 16)
279 ret half %vcvth_n_f16_u32
282 define dso_local i16 @test_vcvth_n_u16_f16_1(half %a) {
283 ; CHECK-LABEL: test_vcvth_n_u16_f16_1:
284 ; CHECK: fcvtzu h0, h0, #1
285 ; CHECK-NEXT: fmov w0, s0
288 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
289 %0 = trunc i32 %fcvth_n to i16
293 define dso_local i16 @test_vcvth_n_u16_f16_16(half %a) {
294 ; CHECK-LABEL: test_vcvth_n_u16_f16_16:
295 ; CHECK: fcvtzu h0, h0, #16
296 ; CHECK-NEXT: fmov w0, s0
299 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16)
300 %0 = trunc i32 %fcvth_n to i16
304 define dso_local i32 @test_vcvth_n_u32_f16_1(half %a) {
305 ; CHECK-LABEL: test_vcvth_n_u32_f16_1:
306 ; CHECK: fcvtzu h0, h0, #1
307 ; CHECK-NEXT: fmov w0, s0
310 %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
311 ret i32 %vcvth_n_u32_f16
314 define dso_local i32 @test_vcvth_n_u32_f16_16(half %a) {
315 ; CHECK-LABEL: test_vcvth_n_u32_f16_16:
316 ; CHECK: fcvtzu h0, h0, #16
317 ; CHECK-NEXT: fmov w0, s0
320 %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16)
321 ret i32 %vcvth_n_u32_f16
324 define dso_local i16 @vcageh_f16_test(half %a, half %b) {
325 ; CHECK-LABEL: vcageh_f16_test:
326 ; CHECK: facge h0, h0, h1
327 ; CHECK-NEXT: fmov w0, s0
330 %facg = tail call i32 @llvm.aarch64.neon.facge.i32.f16(half %a, half %b)
331 %0 = trunc i32 %facg to i16
335 define dso_local i16 @vcagth_f16_test(half %a, half %b) {
336 ; CHECK-LABEL: vcagth_f16_test:
337 ; CHECK: facgt h0, h0, h1
338 ; CHECK-NEXT: fmov w0, s0
341 %facg = tail call i32 @llvm.aarch64.neon.facgt.i32.f16(half %a, half %b)
342 %0 = trunc i32 %facg to i16
346 define dso_local half @vcvth_n_f16_s64_test(i64 %a) {
347 ; CHECK-LABEL: vcvth_n_f16_s64_test:
349 ; CHECK-NEXT: scvtf h0, h0, #16
352 %vcvth_n_f16_s64 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64 %a, i32 16)
353 ret half %vcvth_n_f16_s64