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)
11 define dso_local half @t_vabdh_f16(half %a, half %b) {
12 ; CHECK-LABEL: t_vabdh_f16:
13 ; CHECK: fabd h0, h0, h1
16 %vabdh_f16 = tail call half @llvm.aarch64.sisd.fabd.f16(half %a, half %b)
20 define dso_local half @t_vabdh_f16_from_fsub_fabs(half %a, half %b) {
21 ; CHECK-LABEL: t_vabdh_f16_from_fsub_fabs:
22 ; CHECK: fabd h0, h0, h1
25 %sub = fsub half %a, %b
26 %abs = tail call half @llvm.fabs.f16(half %sub)
30 define dso_local i16 @t_vceqh_f16(half %a, half %b) {
31 ; CHECK-LABEL: t_vceqh_f16:
33 ; CHECK-NEXT: csetm w0, eq
36 %0 = fcmp oeq half %a, %b
37 %vcmpd = sext i1 %0 to i16
41 define dso_local i16 @t_vcgeh_f16(half %a, half %b) {
42 ; CHECK-LABEL: t_vcgeh_f16:
44 ; CHECK-NEXT: csetm w0, ge
47 %0 = fcmp oge half %a, %b
48 %vcmpd = sext i1 %0 to i16
52 define dso_local i16 @t_vcgth_f16(half %a, half %b) {
53 ; CHECK-LABEL: t_vcgth_f16:
55 ; CHECK-NEXT: csetm w0, gt
58 %0 = fcmp ogt half %a, %b
59 %vcmpd = sext i1 %0 to i16
63 define dso_local i16 @t_vcleh_f16(half %a, half %b) {
64 ; CHECK-LABEL: t_vcleh_f16:
66 ; CHECK-NEXT: csetm w0, ls
69 %0 = fcmp ole half %a, %b
70 %vcmpd = sext i1 %0 to i16
74 define dso_local i16 @t_vclth_f16(half %a, half %b) {
75 ; CHECK-LABEL: t_vclth_f16:
77 ; CHECK-NEXT: csetm w0, mi
80 %0 = fcmp olt half %a, %b
81 %vcmpd = sext i1 %0 to i16
85 define dso_local half @t_vmaxh_f16(half %a, half %b) {
86 ; CHECK-LABEL: t_vmaxh_f16:
87 ; CHECK: fmax h0, h0, h1
90 %vmax = tail call half @llvm.aarch64.neon.fmax.f16(half %a, half %b)
94 define dso_local half @t_vminh_f16(half %a, half %b) {
95 ; CHECK-LABEL: t_vminh_f16:
96 ; CHECK: fmin h0, h0, h1
99 %vmin = tail call half @llvm.aarch64.neon.fmin.f16(half %a, half %b)
103 define dso_local half @t_vmulxh_f16(half %a, half %b) {
104 ; CHECK-LABEL: t_vmulxh_f16:
105 ; CHECK: fmulx h0, h0, h1
108 %vmulxh_f16 = tail call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b)
112 define dso_local half @t_vrecpsh_f16(half %a, half %b) {
113 ; CHECK-LABEL: t_vrecpsh_f16:
114 ; CHECK: frecps h0, h0, h1
117 %vrecps = tail call half @llvm.aarch64.neon.frecps.f16(half %a, half %b)
121 define dso_local half @t_vrsqrtsh_f16(half %a, half %b) {
122 ; CHECK-LABEL: t_vrsqrtsh_f16:
123 ; CHECK: frsqrts h0, h0, h1
126 %vrsqrtsh_f16 = tail call half @llvm.aarch64.neon.frsqrts.f16(half %a, half %b)
127 ret half %vrsqrtsh_f16
130 declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32, i32) #1
131 declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64, i32) #1
132 declare i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half, i32) #1
133 declare i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half, i32) #1
134 declare half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32, i32) #1
135 declare i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half, i32) #1
137 define dso_local half @test_vcvth_n_f16_s16_1(i16 %a) {
138 ; CHECK-LABEL: test_vcvth_n_f16_s16_1:
139 ; CHECK: fmov s0, w[[wReg:[0-9]+]]
140 ; CHECK-NEXT: scvtf h0, h0, #1
143 %sext = sext i16 %a to i32
144 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 1)
148 define dso_local half @test_vcvth_n_f16_s16_16(i16 %a) {
149 ; CHECK-LABEL: test_vcvth_n_f16_s16_16:
150 ; CHECK: fmov s0, w[[wReg:[0-9]+]]
151 ; CHECK-NEXT: scvtf h0, h0, #16
154 %sext = sext i16 %a to i32
155 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 16)
159 define dso_local half @test_vcvth_n_f16_s32_1(i32 %a) {
160 ; CHECK-LABEL: test_vcvth_n_f16_s32_1:
162 ; CHECK-NEXT: scvtf h0, h0, #1
165 %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 1)
166 ret half %vcvth_n_f16_s32
169 define dso_local half @test_vcvth_n_f16_s32_16(i32 %a) {
170 ; CHECK-LABEL: test_vcvth_n_f16_s32_16:
172 ; CHECK-NEXT: scvtf h0, h0, #16
175 %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 16)
176 ret half %vcvth_n_f16_s32
179 define dso_local i16 @test_vcvth_n_s16_f16_1(half %a) {
180 ; CHECK-LABEL: test_vcvth_n_s16_f16_1:
181 ; CHECK: fcvtzs h0, h0, #1
182 ; CHECK-NEXT: fmov w0, s0
185 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
186 %0 = trunc i32 %fcvth_n to i16
190 define dso_local i16 @test_vcvth_n_s16_f16_16(half %a) {
191 ; CHECK-LABEL: test_vcvth_n_s16_f16_16:
192 ; CHECK: fcvtzs h0, h0, #16
193 ; CHECK-NEXT: fmov w0, s0
196 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16)
197 %0 = trunc i32 %fcvth_n to i16
201 define dso_local i32 @test_vcvth_n_s32_f16_1(half %a) {
202 ; CHECK-LABEL: test_vcvth_n_s32_f16_1:
203 ; CHECK: fcvtzs h0, h0, #1
204 ; CHECK-NEXT: fmov w0, s0
207 %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
208 ret i32 %vcvth_n_s32_f16
211 define dso_local i32 @test_vcvth_n_s32_f16_16(half %a) {
212 ; CHECK-LABEL: test_vcvth_n_s32_f16_16:
213 ; CHECK: fcvtzs h0, h0, #16
214 ; CHECK-NEXT: fmov w0, s0
217 %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16)
218 ret i32 %vcvth_n_s32_f16
221 define dso_local i64 @test_vcvth_n_s64_f16_1(half %a) {
222 ; CHECK-LABEL: test_vcvth_n_s64_f16_1:
223 ; CHECK: fcvtzs h0, h0, #1
224 ; CHECK-NEXT: fmov x0, d0
227 %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 1)
228 ret i64 %vcvth_n_s64_f16
231 define dso_local i64 @test_vcvth_n_s64_f16_32(half %a) {
232 ; CHECK-LABEL: test_vcvth_n_s64_f16_32:
233 ; CHECK: fcvtzs h0, h0, #32
234 ; CHECK-NEXT: fmov x0, d0
237 %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 32)
238 ret i64 %vcvth_n_s64_f16
241 define dso_local half @test_vcvth_n_f16_u16_1(i16 %a) {
242 ; CHECK-LABEL: test_vcvth_n_f16_u16_1:
243 ; CHECK: ucvtf h0, h0, #1
246 %0 = zext i16 %a to i32
247 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 1)
251 define dso_local half @test_vcvth_n_f16_u16_16(i16 %a) {
252 ; CHECK-LABEL: test_vcvth_n_f16_u16_16:
253 ; CHECK: ucvtf h0, h0, #16
256 %0 = zext i16 %a to i32
257 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 16)
261 define dso_local half @test_vcvth_n_f16_u32_1(i32 %a) {
262 ; CHECK-LABEL: test_vcvth_n_f16_u32_1:
264 ; CHECK-NEXT: ucvtf h0, h0, #1
267 %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 1)
268 ret half %vcvth_n_f16_u32
271 define dso_local half @test_vcvth_n_f16_u32_16(i32 %a) {
272 ; CHECK-LABEL: test_vcvth_n_f16_u32_16:
273 ; CHECK: ucvtf h0, h0, #16
276 %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 16)
277 ret half %vcvth_n_f16_u32
280 define dso_local i16 @test_vcvth_n_u16_f16_1(half %a) {
281 ; CHECK-LABEL: test_vcvth_n_u16_f16_1:
282 ; CHECK: fcvtzu h0, h0, #1
283 ; CHECK-NEXT: fmov w0, s0
286 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
287 %0 = trunc i32 %fcvth_n to i16
291 define dso_local i16 @test_vcvth_n_u16_f16_16(half %a) {
292 ; CHECK-LABEL: test_vcvth_n_u16_f16_16:
293 ; CHECK: fcvtzu h0, h0, #16
294 ; CHECK-NEXT: fmov w0, s0
297 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16)
298 %0 = trunc i32 %fcvth_n to i16
302 define dso_local i32 @test_vcvth_n_u32_f16_1(half %a) {
303 ; CHECK-LABEL: test_vcvth_n_u32_f16_1:
304 ; CHECK: fcvtzu h0, h0, #1
305 ; CHECK-NEXT: fmov w0, s0
308 %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
309 ret i32 %vcvth_n_u32_f16
312 define dso_local i32 @test_vcvth_n_u32_f16_16(half %a) {
313 ; CHECK-LABEL: test_vcvth_n_u32_f16_16:
314 ; CHECK: fcvtzu h0, h0, #16
315 ; CHECK-NEXT: fmov w0, s0
318 %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16)
319 ret i32 %vcvth_n_u32_f16