xref: /llvm-project/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c (revision 207e5ccceec8d3cc3f32723e78f2a142bc61b07d)
1 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +fullfp16\
2 // RUN: -disable-O0-optnone -emit-llvm -o - %s \
3 // RUN: | opt -S -passes=mem2reg \
4 // RUN: | FileCheck %s
5 
6 // REQUIRES: aarch64-registered-target
7 
8 #include <arm_fp16.h>
9 
10 // CHECK-LABEL: test_vabsh_f16
11 // CHECK:  [[ABS:%.*]] =  call half @llvm.fabs.f16(half %a)
12 // CHECK:  ret half [[ABS]]
13 float16_t test_vabsh_f16(float16_t a) {
14   return vabsh_f16(a);
15 }
16 
17 // CHECK-LABEL: test_vceqzh_f16
18 // CHECK:  [[TMP1:%.*]] = fcmp oeq half %a, 0xH0000
19 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
20 // CHECK:  ret i16 [[TMP2]]
21 uint16_t test_vceqzh_f16(float16_t a) {
22   return vceqzh_f16(a);
23 }
24 
25 // CHECK-LABEL: test_vcgezh_f16
26 // CHECK:  [[TMP1:%.*]] = fcmp oge half %a, 0xH0000
27 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
28 // CHECK:  ret i16 [[TMP2]]
29 uint16_t test_vcgezh_f16(float16_t a) {
30   return vcgezh_f16(a);
31 }
32 
33 // CHECK-LABEL: test_vcgtzh_f16
34 // CHECK:  [[TMP1:%.*]] = fcmp ogt half %a, 0xH0000
35 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
36 // CHECK:  ret i16 [[TMP2]]
37 uint16_t test_vcgtzh_f16(float16_t a) {
38   return vcgtzh_f16(a);
39 }
40 
41 // CHECK-LABEL: test_vclezh_f16
42 // CHECK:  [[TMP1:%.*]] = fcmp ole half %a, 0xH0000
43 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
44 // CHECK:  ret i16 [[TMP2]]
45 uint16_t test_vclezh_f16(float16_t a) {
46   return vclezh_f16(a);
47 }
48 
49 // CHECK-LABEL: test_vcltzh_f16
50 // CHECK:  [[TMP1:%.*]] = fcmp olt half %a, 0xH0000
51 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
52 // CHECK:  ret i16 [[TMP2]]
53 uint16_t test_vcltzh_f16(float16_t a) {
54   return vcltzh_f16(a);
55 }
56 
57 // CHECK-LABEL: test_vcvth_f16_s16
58 // CHECK:  [[VCVT:%.*]] = sitofp i16 %a to half
59 // CHECK:  ret half [[VCVT]]
60 float16_t test_vcvth_f16_s16 (int16_t a) {
61   return vcvth_f16_s16(a);
62 }
63 
64 // CHECK-LABEL: test_vcvth_f16_s32
65 // CHECK:  [[VCVT:%.*]] = sitofp i32 %a to half
66 // CHECK:  ret half [[VCVT]]
67 float16_t test_vcvth_f16_s32 (int32_t a) {
68   return vcvth_f16_s32(a);
69 }
70 
71 // CHECK-LABEL: test_vcvth_f16_s64
72 // CHECK:  [[VCVT:%.*]] = sitofp i64 %a to half
73 // CHECK:  ret half [[VCVT]]
74 float16_t test_vcvth_f16_s64 (int64_t a) {
75   return vcvth_f16_s64(a);
76 }
77 
78 // CHECK-LABEL: test_vcvth_f16_u16
79 // CHECK:  [[VCVT:%.*]] = uitofp i16 %a to half
80 // CHECK:  ret half [[VCVT]]
81 float16_t test_vcvth_f16_u16 (uint16_t a) {
82   return vcvth_f16_u16(a);
83 }
84 
85 // CHECK-LABEL: test_vcvth_f16_u32
86 // CHECK:  [[VCVT:%.*]] = uitofp i32 %a to half
87 // CHECK:  ret half [[VCVT]]
88 float16_t test_vcvth_f16_u32 (uint32_t a) {
89   return vcvth_f16_u32(a);
90 }
91 
92 // CHECK-LABEL: test_vcvth_f16_u64
93 // CHECK:  [[VCVT:%.*]] = uitofp i64 %a to half
94 // CHECK:  ret half [[VCVT]]
95 float16_t test_vcvth_f16_u64 (uint64_t a) {
96   return vcvth_f16_u64(a);
97 }
98 
99 // CHECK-LABEL: test_vcvth_s16_f16
100 // CHECK:  [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtzs.i32.f16(half %a)
101 // CHECK:  [[TRUNC:%.*]] = trunc i32 [[VCVT]] to i16
102 // CHECK:  ret i16 [[TRUNC]]
103 int16_t test_vcvth_s16_f16 (float16_t a) {
104   return vcvth_s16_f16(a);
105 }
106 
107 // CHECK-LABEL: test_vcvth_s32_f16
108 // CHECK:  [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtzs.i32.f16(half %a)
109 // CHECK:  ret i32 [[VCVT]]
110 int32_t test_vcvth_s32_f16 (float16_t a) {
111   return vcvth_s32_f16(a);
112 }
113 
114 // CHECK-LABEL: test_vcvth_s64_f16
115 // CHECK:  [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtzs.i64.f16(half %a)
116 // CHECK:  ret i64 [[VCVT]]
117 int64_t test_vcvth_s64_f16 (float16_t a) {
118   return vcvth_s64_f16(a);
119 }
120 
121 // CHECK-LABEL: test_vcvth_u16_f16
122 // CHECK:  [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtzu.i32.f16(half %a)
123 // CHECK:  [[TRUNC:%.*]] = trunc i32 [[VCVT]] to i16
124 // CHECK:  ret i16 [[TRUNC]]
125 uint16_t test_vcvth_u16_f16 (float16_t a) {
126   return vcvth_u16_f16(a);
127 }
128 
129 // CHECK-LABEL: test_vcvth_u32_f16
130 // CHECK:  [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtzu.i32.f16(half %a)
131 // CHECK:  ret i32 [[VCVT]]
132 uint32_t test_vcvth_u32_f16 (float16_t a) {
133   return vcvth_u32_f16(a);
134 }
135 
136 // CHECK-LABEL: test_vcvth_u64_f16
137 // CHECK:  [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtzu.i64.f16(half %a)
138 // CHECK:  ret i64 [[VCVT]]
139 uint64_t test_vcvth_u64_f16 (float16_t a) {
140   return vcvth_u64_f16(a);
141 }
142 
143 // CHECK-LABEL: test_vcvtah_s16_f16
144 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtas.i32.f16(half %a)
145 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
146 // CHECK: ret i16 [[RET]]
147 int16_t test_vcvtah_s16_f16 (float16_t a) {
148   return vcvtah_s16_f16(a);
149 }
150 
151 // CHECK-LABEL: test_vcvtah_s32_f16
152 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtas.i32.f16(half %a)
153 // CHECK: ret i32 [[VCVT]]
154 int32_t test_vcvtah_s32_f16 (float16_t a) {
155   return vcvtah_s32_f16(a);
156 }
157 
158 // CHECK-LABEL: test_vcvtah_s64_f16
159 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtas.i64.f16(half %a)
160 // CHECK: ret i64 [[VCVT]]
161 int64_t test_vcvtah_s64_f16 (float16_t a) {
162   return vcvtah_s64_f16(a);
163 }
164 
165 // CHECK-LABEL: test_vcvtah_u16_f16
166 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtau.i32.f16(half %a)
167 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
168 // CHECK: ret i16 [[RET]]
169 uint16_t test_vcvtah_u16_f16 (float16_t a) {
170   return vcvtah_u16_f16(a);
171 }
172 
173 // CHECK-LABEL: test_vcvtah_u32_f16
174 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtau.i32.f16(half %a)
175 // CHECK: ret i32 [[VCVT]]
176 uint32_t test_vcvtah_u32_f16 (float16_t a) {
177   return vcvtah_u32_f16(a);
178 }
179 
180 // CHECK-LABEL: test_vcvtah_u64_f16
181 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtau.i64.f16(half %a)
182 // CHECK: ret i64 [[VCVT]]
183 uint64_t test_vcvtah_u64_f16 (float16_t a) {
184   return vcvtah_u64_f16(a);
185 }
186 
187 // CHECK-LABEL: test_vcvtmh_s16_f16
188 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtms.i32.f16(half %a)
189 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
190 // CHECK: ret i16 [[RET]]
191 int16_t test_vcvtmh_s16_f16 (float16_t a) {
192   return vcvtmh_s16_f16(a);
193 }
194 
195 // CHECK-LABEL: test_vcvtmh_s32_f16
196 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtms.i32.f16(half %a)
197 // CHECK: ret i32 [[VCVT]]
198 int32_t test_vcvtmh_s32_f16 (float16_t a) {
199   return vcvtmh_s32_f16(a);
200 }
201 
202 // CHECK-LABEL: test_vcvtmh_s64_f16
203 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtms.i64.f16(half %a)
204 // CHECK: ret i64 [[VCVT]]
205 int64_t test_vcvtmh_s64_f16 (float16_t a) {
206   return vcvtmh_s64_f16(a);
207 }
208 
209 // CHECK-LABEL: test_vcvtmh_u16_f16
210 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtmu.i32.f16(half %a)
211 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
212 // CHECK: ret i16 [[RET]]
213 uint16_t test_vcvtmh_u16_f16 (float16_t a) {
214   return vcvtmh_u16_f16(a);
215 }
216 
217 // CHECK-LABEL: test_vcvtmh_u32_f16
218 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtmu.i32.f16(half %a)
219 // CHECK: ret i32 [[VCVT]]
220 uint32_t test_vcvtmh_u32_f16 (float16_t a) {
221   return vcvtmh_u32_f16(a);
222 }
223 
224 // CHECK-LABEL: test_vcvtmh_u64_f16
225 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtmu.i64.f16(half %a)
226 // CHECK: ret i64 [[VCVT]]
227 uint64_t test_vcvtmh_u64_f16 (float16_t a) {
228   return vcvtmh_u64_f16(a);
229 }
230 
231 // CHECK-LABEL: test_vcvtnh_s16_f16
232 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtns.i32.f16(half %a)
233 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
234 // CHECK: ret i16 [[RET]]
235 int16_t test_vcvtnh_s16_f16 (float16_t a) {
236   return vcvtnh_s16_f16(a);
237 }
238 
239 // CHECK-LABEL: test_vcvtnh_s32_f16
240 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtns.i32.f16(half %a)
241 // CHECK: ret i32 [[VCVT]]
242 int32_t test_vcvtnh_s32_f16 (float16_t a) {
243   return vcvtnh_s32_f16(a);
244 }
245 
246 // CHECK-LABEL: test_vcvtnh_s64_f16
247 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtns.i64.f16(half %a)
248 // CHECK: ret i64 [[VCVT]]
249 int64_t test_vcvtnh_s64_f16 (float16_t a) {
250   return vcvtnh_s64_f16(a);
251 }
252 
253 // CHECK-LABEL: test_vcvtnh_u16_f16
254 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtnu.i32.f16(half %a)
255 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
256 // CHECK: ret i16 [[RET]]
257 uint16_t test_vcvtnh_u16_f16 (float16_t a) {
258   return vcvtnh_u16_f16(a);
259 }
260 
261 // CHECK-LABEL: test_vcvtnh_u32_f16
262 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtnu.i32.f16(half %a)
263 // CHECK: ret i32 [[VCVT]]
264 uint32_t test_vcvtnh_u32_f16 (float16_t a) {
265   return vcvtnh_u32_f16(a);
266 }
267 
268 // CHECK-LABEL: test_vcvtnh_u64_f16
269 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtnu.i64.f16(half %a)
270 // CHECK: ret i64 [[VCVT]]
271 uint64_t test_vcvtnh_u64_f16 (float16_t a) {
272   return vcvtnh_u64_f16(a);
273 }
274 
275 // CHECK-LABEL: test_vcvtph_s16_f16
276 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtps.i32.f16(half %a)
277 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
278 // CHECK: ret i16 [[RET]]
279 int16_t test_vcvtph_s16_f16 (float16_t a) {
280   return vcvtph_s16_f16(a);
281 }
282 
283 // CHECK-LABEL: test_vcvtph_s32_f16
284 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtps.i32.f16(half %a)
285 // CHECK: ret i32 [[VCVT]]
286 int32_t test_vcvtph_s32_f16 (float16_t a) {
287   return vcvtph_s32_f16(a);
288 }
289 
290 // CHECK-LABEL: test_vcvtph_s64_f16
291 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtps.i64.f16(half %a)
292 // CHECK: ret i64 [[VCVT]]
293 int64_t test_vcvtph_s64_f16 (float16_t a) {
294   return vcvtph_s64_f16(a);
295 }
296 
297 // CHECK-LABEL: test_vcvtph_u16_f16
298 // CHECK: [[FCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtpu.i32.f16(half %a)
299 // CHECK: [[RET:%.*]] = trunc i32 [[FCVT]] to i16
300 // CHECK: ret i16 [[RET]]
301 uint16_t test_vcvtph_u16_f16 (float16_t a) {
302   return vcvtph_u16_f16(a);
303 }
304 
305 // CHECK-LABEL: test_vcvtph_u32_f16
306 // CHECK: [[VCVT:%.*]] = call i32 @llvm.aarch64.neon.fcvtpu.i32.f16(half %a)
307 // CHECK: ret i32 [[VCVT]]
308 uint32_t test_vcvtph_u32_f16 (float16_t a) {
309   return vcvtph_u32_f16(a);
310 }
311 
312 // CHECK-LABEL: test_vcvtph_u64_f16
313 // CHECK: [[VCVT:%.*]] = call i64 @llvm.aarch64.neon.fcvtpu.i64.f16(half %a)
314 // CHECK: ret i64 [[VCVT]]
315 uint64_t test_vcvtph_u64_f16 (float16_t a) {
316   return vcvtph_u64_f16(a);
317 }
318 
319 // CHECK-LABEL: test_vnegh_f16
320 // CHECK: [[NEG:%.*]] = fneg half %a
321 // CHECK: ret half [[NEG]]
322 float16_t test_vnegh_f16(float16_t a) {
323   return vnegh_f16(a);
324 }
325 
326 // CHECK-LABEL: test_vrecpeh_f16
327 // CHECK: [[VREC:%.*]] = call half @llvm.aarch64.neon.frecpe.f16(half %a)
328 // CHECK: ret half [[VREC]]
329 float16_t test_vrecpeh_f16(float16_t a) {
330   return vrecpeh_f16(a);
331 }
332 
333 // CHECK-LABEL: test_vrecpxh_f16
334 // CHECK: [[VREC:%.*]] = call half @llvm.aarch64.neon.frecpx.f16(half %a)
335 // CHECK: ret half [[VREC]]
336 float16_t test_vrecpxh_f16(float16_t a) {
337   return vrecpxh_f16(a);
338 }
339 
340 // CHECK-LABEL: test_vrndh_f16
341 // CHECK:  [[RND:%.*]] =  call half @llvm.trunc.f16(half %a)
342 // CHECK:  ret half [[RND]]
343 float16_t test_vrndh_f16(float16_t a) {
344   return vrndh_f16(a);
345 }
346 
347 // CHECK-LABEL: test_vrndah_f16
348 // CHECK:  [[RND:%.*]] =  call half @llvm.round.f16(half %a)
349 // CHECK:  ret half [[RND]]
350 float16_t test_vrndah_f16(float16_t a) {
351   return vrndah_f16(a);
352 }
353 
354 // CHECK-LABEL: test_vrndih_f16
355 // CHECK:  [[RND:%.*]] =  call half @llvm.nearbyint.f16(half %a)
356 // CHECK:  ret half [[RND]]
357 float16_t test_vrndih_f16(float16_t a) {
358   return vrndih_f16(a);
359 }
360 
361 // CHECK-LABEL: test_vrndmh_f16
362 // CHECK:  [[RND:%.*]] =  call half @llvm.floor.f16(half %a)
363 // CHECK:  ret half [[RND]]
364 float16_t test_vrndmh_f16(float16_t a) {
365   return vrndmh_f16(a);
366 }
367 
368 // CHECK-LABEL: test_vrndnh_f16
369 // CHECK:  [[RND:%.*]] =  call half @llvm.roundeven.f16(half %a)
370 // CHECK:  ret half [[RND]]
371 float16_t test_vrndnh_f16(float16_t a) {
372   return vrndnh_f16(a);
373 }
374 
375 // CHECK-LABEL: test_vrndph_f16
376 // CHECK:  [[RND:%.*]] =  call half @llvm.ceil.f16(half %a)
377 // CHECK:  ret half [[RND]]
378 float16_t test_vrndph_f16(float16_t a) {
379   return vrndph_f16(a);
380 }
381 
382 // CHECK-LABEL: test_vrndxh_f16
383 // CHECK:  [[RND:%.*]] =  call half @llvm.rint.f16(half %a)
384 // CHECK:  ret half [[RND]]
385 float16_t test_vrndxh_f16(float16_t a) {
386   return vrndxh_f16(a);
387 }
388 
389 // CHECK-LABEL: test_vrsqrteh_f16
390 // CHECK:  [[RND:%.*]] = call half @llvm.aarch64.neon.frsqrte.f16(half %a)
391 // CHECK:  ret half [[RND]]
392 float16_t test_vrsqrteh_f16(float16_t a) {
393   return vrsqrteh_f16(a);
394 }
395 
396 // CHECK-LABEL: test_vsqrth_f16
397 // CHECK:  [[SQR:%.*]] = call half @llvm.sqrt.f16(half %a)
398 // CHECK:  ret half [[SQR]]
399 float16_t test_vsqrth_f16(float16_t a) {
400   return vsqrth_f16(a);
401 }
402 
403 // CHECK-LABEL: test_vaddh_f16
404 // CHECK:  [[ADD:%.*]] = fadd half %a, %b
405 // CHECK:  ret half [[ADD]]
406 float16_t test_vaddh_f16(float16_t a, float16_t b) {
407   return vaddh_f16(a, b);
408 }
409 
410 // CHECK-LABEL: test_vabdh_f16
411 // CHECK:  [[ABD:%.*]] = call half @llvm.aarch64.sisd.fabd.f16(half %a, half %b)
412 // CHECK:  ret half [[ABD]]
413 float16_t test_vabdh_f16(float16_t a, float16_t b) {
414   return vabdh_f16(a, b);
415 }
416 
417 // CHECK-LABEL: test_vcageh_f16
418 // CHECK:  [[FACG:%.*]] = call i32 @llvm.aarch64.neon.facge.i32.f16(half %a, half %b)
419 // CHECK: [[RET:%.*]] = trunc i32 [[FACG]] to i16
420 // CHECK: ret i16 [[RET]]
421 uint16_t test_vcageh_f16(float16_t a, float16_t b) {
422   return vcageh_f16(a, b);
423 }
424 
425 // CHECK-LABEL: test_vcagth_f16
426 // CHECK:  [[FACG:%.*]] = call i32 @llvm.aarch64.neon.facgt.i32.f16(half %a, half %b)
427 // CHECK: [[RET:%.*]] = trunc i32 [[FACG]] to i16
428 // CHECK: ret i16 [[RET]]
429 uint16_t test_vcagth_f16(float16_t a, float16_t b) {
430   return vcagth_f16(a, b);
431 }
432 
433 // CHECK-LABEL: test_vcaleh_f16
434 // CHECK:  [[FACG:%.*]] = call i32 @llvm.aarch64.neon.facge.i32.f16(half %b, half %a)
435 // CHECK: [[RET:%.*]] = trunc i32 [[FACG]] to i16
436 // CHECK: ret i16 [[RET]]
437 uint16_t test_vcaleh_f16(float16_t a, float16_t b) {
438   return vcaleh_f16(a, b);
439 }
440 
441 // CHECK-LABEL: test_vcalth_f16
442 // CHECK:  [[FACG:%.*]] = call i32 @llvm.aarch64.neon.facgt.i32.f16(half %b, half %a)
443 // CHECK: [[RET:%.*]] = trunc i32 [[FACG]] to i16
444 // CHECK: ret i16 [[RET]]
445 uint16_t test_vcalth_f16(float16_t a, float16_t b) {
446   return vcalth_f16(a, b);
447 }
448 
449 // CHECK-LABEL: test_vceqh_f16
450 // CHECK:  [[TMP1:%.*]] = fcmp oeq half %a, %b
451 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
452 // CHECK:  ret i16 [[TMP2]]
453 uint16_t test_vceqh_f16(float16_t a, float16_t b) {
454   return vceqh_f16(a, b);
455 }
456 
457 // CHECK-LABEL: test_vcgeh_f16
458 // CHECK:  [[TMP1:%.*]] = fcmp oge half %a, %b
459 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
460 // CHECK:  ret i16 [[TMP2]]
461 uint16_t test_vcgeh_f16(float16_t a, float16_t b) {
462   return vcgeh_f16(a, b);
463 }
464 
465 // CHECK-LABEL: test_vcgth_f16
466 //CHECK:  [[TMP1:%.*]] = fcmp ogt half %a, %b
467 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
468 // CHECK:  ret i16 [[TMP2]]
469 uint16_t test_vcgth_f16(float16_t a, float16_t b) {
470   return vcgth_f16(a, b);
471 }
472 
473 // CHECK-LABEL: test_vcleh_f16
474 // CHECK:  [[TMP1:%.*]] = fcmp ole half %a, %b
475 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
476 // CHECK:  ret i16 [[TMP2]]
477 uint16_t test_vcleh_f16(float16_t a, float16_t b) {
478   return vcleh_f16(a, b);
479 }
480 
481 // CHECK-LABEL: test_vclth_f16
482 // CHECK:  [[TMP1:%.*]] = fcmp olt half %a, %b
483 // CHECK:  [[TMP2:%.*]] = sext i1 [[TMP1]] to i16
484 // CHECK:  ret i16 [[TMP2]]
485 uint16_t test_vclth_f16(float16_t a, float16_t b) {
486   return vclth_f16(a, b);
487 }
488 
489 // CHECK-LABEL: test_vcvth_n_f16_s16
490 // CHECK: [[SEXT:%.*]] = sext i16 %a to i32
491 // CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 [[SEXT]], i32 1)
492 // CHECK:  ret half [[CVT]]
493 float16_t test_vcvth_n_f16_s16(int16_t a) {
494   return vcvth_n_f16_s16(a, 1);
495 }
496 
497 // CHECK-LABEL: test_vcvth_n_f16_s32
498 // CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 1)
499 // CHECK:  ret half [[CVT]]
500 float16_t test_vcvth_n_f16_s32(int32_t a) {
501   return vcvth_n_f16_s32(a, 1);
502 }
503 
504 // CHECK-LABEL: test_vcvth_n_f16_s64
505 // CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64 %a, i32 1)
506 // CHECK:  ret half [[CVT]]
507 float16_t test_vcvth_n_f16_s64(int64_t a) {
508   return vcvth_n_f16_s64(a, 1);
509 }
510 
511 // CHECK-LABEL: test_vcvth_n_s16_f16
512 // CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
513 // CHECK: [[RET:%.*]] = trunc i32 [[CVT]] to i16
514 // CHECK: ret i16 [[RET]]
515 int16_t test_vcvth_n_s16_f16(float16_t a) {
516   return vcvth_n_s16_f16(a, 1);
517 }
518 
519 // CHECK-LABEL: test_vcvth_n_s32_f16
520 // CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
521 // CHECK:  ret i32 [[CVT]]
522 int32_t test_vcvth_n_s32_f16(float16_t a) {
523   return vcvth_n_s32_f16(a, 1);
524 }
525 
526 // CHECK-LABEL: test_vcvth_n_s64_f16
527 // CHECK:  [[CVT:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 1)
528 // CHECK:  ret i64 [[CVT]]
529 int64_t test_vcvth_n_s64_f16(float16_t a) {
530   return vcvth_n_s64_f16(a, 1);
531 }
532 
533 // CHECK-LABEL: test_vcvth_n_f16_u16
534 // CHECK: [[SEXT:%.*]] = zext i16 %a to i32
535 // CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 [[SEXT]], i32 1)
536 // CHECK:  ret half [[CVT]]
537 float16_t test_vcvth_n_f16_u16(int16_t a) {
538   return vcvth_n_f16_u16(a, 1);
539 }
540 
541 // CHECK-LABEL: test_vcvth_n_f16_u32
542 // CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 1)
543 // CHECK:  ret half [[CVT]]
544 float16_t test_vcvth_n_f16_u32(int32_t a) {
545   return vcvth_n_f16_u32(a, 1);
546 }
547 
548 // CHECK-LABEL: test_vcvth_n_f16_u64
549 // CHECK:  [[CVT:%.*]] = call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i64(i64 %a, i32 1)
550 // CHECK:  ret half [[CVT]]
551 float16_t test_vcvth_n_f16_u64(int64_t a) {
552   return vcvth_n_f16_u64(a, 1);
553 }
554 
555 // CHECK-LABEL: test_vcvth_n_u16_f16
556 // CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
557 // CHECK: [[RET:%.*]] = trunc i32 [[CVT]] to i16
558 // CHECK: ret i16 [[RET]]
559 int16_t test_vcvth_n_u16_f16(float16_t a) {
560   return vcvth_n_u16_f16(a, 1);
561 }
562 
563 // CHECK-LABEL: test_vcvth_n_u32_f16
564 // CHECK:  [[CVT:%.*]] = call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
565 // CHECK:  ret i32 [[CVT]]
566 int32_t test_vcvth_n_u32_f16(float16_t a) {
567   return vcvth_n_u32_f16(a, 1);
568 }
569 
570 // CHECK-LABEL: test_vcvth_n_u64_f16
571 // CHECK:  [[CVT:%.*]] = call i64 @llvm.aarch64.neon.vcvtfp2fxu.i64.f16(half %a, i32 1)
572 // CHECK:  ret i64 [[CVT]]
573 int64_t test_vcvth_n_u64_f16(float16_t a) {
574   return vcvth_n_u64_f16(a, 1);
575 }
576 
577 // CHECK-LABEL: test_vdivh_f16
578 // CHECK:  [[DIV:%.*]] = fdiv half %a, %b
579 // CHECK:  ret half [[DIV]]
580 float16_t test_vdivh_f16(float16_t a, float16_t b) {
581   return vdivh_f16(a, b);
582 }
583 
584 // CHECK-LABEL: test_vmaxh_f16
585 // CHECK:  [[MAX:%.*]] = call half @llvm.aarch64.neon.fmax.f16(half %a, half %b)
586 // CHECK:  ret half [[MAX]]
587 float16_t test_vmaxh_f16(float16_t a, float16_t b) {
588   return vmaxh_f16(a, b);
589 }
590 
591 // CHECK-LABEL: test_vmaxnmh_f16
592 // CHECK:  [[MAX:%.*]] = call half @llvm.aarch64.neon.fmaxnm.f16(half %a, half %b)
593 // CHECK:  ret half [[MAX]]
594 float16_t test_vmaxnmh_f16(float16_t a, float16_t b) {
595   return vmaxnmh_f16(a, b);
596 }
597 
598 // CHECK-LABEL: test_vminh_f16
599 // CHECK:  [[MIN:%.*]] = call half @llvm.aarch64.neon.fmin.f16(half %a, half %b)
600 // CHECK:  ret half [[MIN]]
601 float16_t test_vminh_f16(float16_t a, float16_t b) {
602   return vminh_f16(a, b);
603 }
604 
605 // CHECK-LABEL: test_vminnmh_f16
606 // CHECK:  [[MIN:%.*]] = call half @llvm.aarch64.neon.fminnm.f16(half %a, half %b)
607 // CHECK:  ret half [[MIN]]
608 float16_t test_vminnmh_f16(float16_t a, float16_t b) {
609   return vminnmh_f16(a, b);
610 }
611 
612 // CHECK-LABEL: test_vmulh_f16
613 // CHECK:  [[MUL:%.*]] = fmul half %a, %b
614 // CHECK:  ret half [[MUL]]
615 float16_t test_vmulh_f16(float16_t a, float16_t b) {
616   return vmulh_f16(a, b);
617 }
618 
619 // CHECK-LABEL: test_vmulxh_f16
620 // CHECK:  [[MUL:%.*]] = call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b)
621 // CHECK:  ret half [[MUL]]
622 float16_t test_vmulxh_f16(float16_t a, float16_t b) {
623   return vmulxh_f16(a, b);
624 }
625 
626 // CHECK-LABEL: test_vrecpsh_f16
627 // CHECK: [[RECPS:%.*]] = call half @llvm.aarch64.neon.frecps.f16(half %a, half %b)
628 // CHECK: ret half [[RECPS]]
629 float16_t test_vrecpsh_f16(float16_t a, float16_t b) {
630   return vrecpsh_f16(a, b);
631 }
632 
633 // CHECK-LABEL: test_vrsqrtsh_f16
634 // CHECK:  [[RSQRTS:%.*]] = call half @llvm.aarch64.neon.frsqrts.f16(half %a, half %b)
635 // CHECK:  ret half [[RSQRTS]]
636 float16_t test_vrsqrtsh_f16(float16_t a, float16_t b) {
637   return vrsqrtsh_f16(a, b);
638 }
639 
640 // CHECK-LABEL: test_vsubh_f16
641 // CHECK:  [[SUB:%.*]] = fsub half %a, %b
642 // CHECK:  ret half [[SUB]]
643 float16_t test_vsubh_f16(float16_t a, float16_t b) {
644   return vsubh_f16(a, b);
645 }
646 
647 // CHECK-LABEL: test_vfmah_f16
648 // CHECK:  [[FMA:%.*]] = call half @llvm.fma.f16(half %b, half %c, half %a)
649 // CHECK:  ret half [[FMA]]
650 float16_t test_vfmah_f16(float16_t a, float16_t b, float16_t c) {
651   return vfmah_f16(a, b, c);
652 }
653 
654 // CHECK-LABEL: test_vfmsh_f16
655 // CHECK:  [[SUB:%.*]] = fneg half %b
656 // CHECK:  [[ADD:%.*]] = call half @llvm.fma.f16(half [[SUB]], half %c, half %a)
657 // CHECK:  ret half [[ADD]]
658 float16_t test_vfmsh_f16(float16_t a, float16_t b, float16_t c) {
659   return vfmsh_f16(a, b, c);
660 }
661 
662