1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple aarch64-unknown-unknown -aarch64-neon-syntax=apple -asm-verbose=false -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=CHECK-CVT --check-prefix=CHECK-COMMON
3 ; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 -aarch64-neon-syntax=apple -asm-verbose=false -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-FP16
5 ; RUN: llc < %s -mtriple aarch64-unknown-unknown -aarch64-neon-syntax=apple \
6 ; RUN: -asm-verbose=false -disable-post-ra -frame-pointer=non-leaf -global-isel \
7 ; RUN: -global-isel-abort=2 -pass-remarks-missed=gisel-* 2>&1 | FileCheck %s \
8 ; RUN: --check-prefixes=FALLBACK,GISEL-CVT,GISEL
10 ; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 \
11 ; RUN: -aarch64-neon-syntax=apple -asm-verbose=false -disable-post-ra \
12 ; RUN: -frame-pointer=non-leaf -global-isel -global-isel-abort=2 \
13 ; RUN: -pass-remarks-missed=gisel-* 2>&1 | FileCheck %s \
14 ; RUN: --check-prefixes=FALLBACK-FP16,GISEL-FP16,GISEL
16 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
18 ; CHECK-CVT-LABEL: test_fadd:
19 ; CHECK-CVT-NEXT: fcvt s1, h1
20 ; CHECK-CVT-NEXT: fcvt s0, h0
21 ; CHECK-CVT-NEXT: fadd s0, s0, s1
22 ; CHECK-CVT-NEXT: fcvt h0, s0
25 ; CHECK-FP16-LABEL: test_fadd:
26 ; CHECK-FP16-NEXT: fadd h0, h0, h1
27 ; CHECK-FP16-NEXT: ret
29 define half @test_fadd(half %a, half %b) #0 {
34 ; CHECK-CVT-LABEL: test_fsub:
35 ; CHECK-CVT-NEXT: fcvt s1, h1
36 ; CHECK-CVT-NEXT: fcvt s0, h0
37 ; CHECK-CVT-NEXT: fsub s0, s0, s1
38 ; CHECK-CVT-NEXT: fcvt h0, s0
41 ; CHECK-FP16-LABEL: test_fsub:
42 ; CHECK-FP16-NEXT: fsub h0, h0, h1
43 ; CHECK-FP16-NEXT: ret
45 define half @test_fsub(half %a, half %b) #0 {
50 ; CHECK-CVT-LABEL: test_fmul:
51 ; CHECK-CVT-NEXT: fcvt s1, h1
52 ; CHECK-CVT-NEXT: fcvt s0, h0
53 ; CHECK-CVT-NEXT: fmul s0, s0, s1
54 ; CHECK-CVT-NEXT: fcvt h0, s0
57 ; CHECK-FP16-LABEL: test_fmul:
58 ; CHECK-FP16-NEXT: fmul h0, h0, h1
59 ; CHECK-FP16-NEXT: ret
61 define half @test_fmul(half %a, half %b) #0 {
66 ; CHECK-CVT-LABEL: test_fmadd:
67 ; CHECK-CVT-NEXT: fcvt s1, h1
68 ; CHECK-CVT-NEXT: fcvt s0, h0
69 ; CHECK-CVT-NEXT: fmul s0, s0, s1
70 ; CHECK-CVT-NEXT: fcvt h0, s0
71 ; CHECK-CVT-NEXT: fcvt s0, h0
72 ; CHECK-CVT-NEXT: fcvt s1, h2
73 ; CHECK-CVT-NEXT: fadd s0, s0, s1
74 ; CHECK-CVT-NEXT: fcvt h0, s0
77 ; CHECK-FP16-LABEL: test_fmadd:
78 ; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
79 ; CHECK-FP16-NEXT: ret
81 define half @test_fmadd(half %a, half %b, half %c) #0 {
82 %mul = fmul fast half %a, %b
83 %r = fadd fast half %mul, %c
86 ; CHECK-CVT-LABEL: test_fdiv:
87 ; CHECK-CVT-NEXT: fcvt s1, h1
88 ; CHECK-CVT-NEXT: fcvt s0, h0
89 ; CHECK-CVT-NEXT: fdiv s0, s0, s1
90 ; CHECK-CVT-NEXT: fcvt h0, s0
93 ; CHECK-FP16-LABEL: test_fdiv:
94 ; CHECK-FP16-NEXT: fdiv h0, h0, h1
95 ; CHECK-FP16-NEXT: ret
97 define half @test_fdiv(half %a, half %b) #0 {
102 ; CHECK-COMMON-LABEL: test_frem:
103 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
104 ; CHECK-COMMON-NEXT: mov x29, sp
105 ; CHECK-COMMON-NEXT: fcvt s0, h0
106 ; CHECK-COMMON-NEXT: fcvt s1, h1
107 ; CHECK-COMMON-NEXT: bl {{_?}}fmodf
108 ; CHECK-COMMON-NEXT: fcvt h0, s0
109 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
110 ; CHECK-COMMON-NEXT: ret
111 define half @test_frem(half %a, half %b) #0 {
112 %r = frem half %a, %b
116 ; CHECK-COMMON-LABEL: test_store:
117 ; CHECK-COMMON-NEXT: str h0, [x0]
118 ; CHECK-COMMON-NEXT: ret
119 define void @test_store(half %a, ptr %b) #0 {
120 store half %a, ptr %b
124 ; CHECK-COMMON-LABEL: test_load:
125 ; CHECK-COMMON-NEXT: ldr h0, [x0]
126 ; CHECK-COMMON-NEXT: ret
127 define half @test_load(ptr %a) #0 {
128 %r = load half, ptr %a
132 declare half @test_callee(half %a, half %b) #0
134 ; CHECK-COMMON-LABEL: test_call:
135 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
136 ; CHECK-COMMON-NEXT: mov x29, sp
137 ; CHECK-COMMON-NEXT: bl {{_?}}test_callee
138 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
139 ; CHECK-COMMON-NEXT: ret
140 define half @test_call(half %a, half %b) #0 {
141 %r = call half @test_callee(half %a, half %b)
145 ; CHECK-COMMON-LABEL: test_call_flipped:
146 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
147 ; CHECK-COMMON-NEXT: mov x29, sp
148 ; CHECK-COMMON-NEXT: fmov s2, s0
149 ; CHECK-COMMON-NEXT: fmov s0, s1
150 ; CHECK-COMMON-NEXT: fmov s1, s2
151 ; CHECK-COMMON-NEXT: bl {{_?}}test_callee
152 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
153 ; CHECK-COMMON-NEXT: ret
154 define half @test_call_flipped(half %a, half %b) #0 {
155 %r = call half @test_callee(half %b, half %a)
159 ; CHECK-COMMON-LABEL: test_tailcall_flipped:
160 ; CHECK-COMMON-NEXT: fmov s2, s0
161 ; CHECK-COMMON-NEXT: fmov s0, s1
162 ; CHECK-COMMON-NEXT: fmov s1, s2
163 ; CHECK-COMMON-NEXT: b {{_?}}test_callee
164 define half @test_tailcall_flipped(half %a, half %b) #0 {
165 %r = tail call half @test_callee(half %b, half %a)
169 ; CHECK-CVT-LABEL: test_select:
170 ; CHECK-CVT-NEXT: cmp w0, #0
171 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
172 ; CHECK-CVT-NEXT: ret
174 ; CHECK-FP16-LABEL: test_select:
175 ; CHECK-FP16-NEXT: cmp w0, #0
176 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, ne
177 ; CHECK-FP16-NEXT: ret
179 define half @test_select(half %a, half %b, i1 zeroext %c) #0 {
180 %r = select i1 %c, half %a, half %b
184 ; CHECK-CVT-LABEL: test_select_cc:
185 ; CHECK-CVT-DAG: fcvt s3, h3
186 ; CHECK-CVT-DAG: fcvt s2, h2
187 ; CHECK-CVT-DAG: fcmp s2, s3
188 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
189 ; CHECK-CVT-NEXT: ret
191 ; CHECK-FP16-LABEL: test_select_cc:
192 ; CHECK-FP16-NEXT: fcmp h2, h3
193 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, ne
194 ; CHECK-FP16-NEXT: ret
196 define half @test_select_cc(half %a, half %b, half %c, half %d) #0 {
197 %cc = fcmp une half %c, %d
198 %r = select i1 %cc, half %a, half %b
202 ; CHECK-CVT-LABEL: test_select_cc_f32_f16:
203 ; CHECK-CVT-DAG: fcvt s2, h2
204 ; CHECK-CVT-DAG: fcvt s3, h3
205 ; CHECK-CVT-NEXT: fcmp s2, s3
206 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
207 ; CHECK-CVT-NEXT: ret
209 ; CHECK-FP16-LABEL: test_select_cc_f32_f16:
210 ; CHECK-FP16-NEXT: fcmp h2, h3
211 ; CHECK-FP16-NEXT: fcsel s0, s0, s1, ne
212 ; CHECK-FP16-NEXT: ret
214 define float @test_select_cc_f32_f16(float %a, float %b, half %c, half %d) #0 {
215 %cc = fcmp une half %c, %d
216 %r = select i1 %cc, float %a, float %b
220 ; CHECK-CVT-LABEL: test_select_cc_f16_f32:
221 ; CHECK-CVT-DAG: fcmp s2, s3
222 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
223 ; CHECK-CVT-NEXT: ret
225 ; CHECK-FP16-LABEL: test_select_cc_f16_f32:
226 ; CHECK-FP16-NEXT: fcmp s2, s3
227 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, ne
228 ; CHECK-FP16-NEXT: ret
230 define half @test_select_cc_f16_f32(half %a, half %b, float %c, float %d) #0 {
231 %cc = fcmp une float %c, %d
232 %r = select i1 %cc, half %a, half %b
236 ; CHECK-CVT-LABEL: test_fcmp_une:
237 ; CHECK-CVT-NEXT: fcvt s1, h1
238 ; CHECK-CVT-NEXT: fcvt s0, h0
239 ; CHECK-CVT-NEXT: fcmp s0, s1
240 ; CHECK-CVT-NEXT: cset w0, ne
241 ; CHECK-CVT-NEXT: ret
243 ; CHECK-FP16-LABEL: test_fcmp_une:
244 ; CHECK-FP16-NEXT: fcmp h0, h1
245 ; CHECK-FP16-NEXT: cset w0, ne
246 ; CHECK-FP16-NEXT: ret
248 define i1 @test_fcmp_une(half %a, half %b) #0 {
249 %r = fcmp une half %a, %b
253 ; CHECK-CVT-LABEL: test_fcmp_ueq:
254 ; CHECK-CVT-NEXT: fcvt s1, h1
255 ; CHECK-CVT-NEXT: fcvt s0, h0
256 ; CHECK-CVT-NEXT: fcmp s0, s1
257 ; CHECK-CVT-NEXT: cset [[TRUE:w[0-9]+]], eq
258 ; CHECK-CVT-NEXT: csinc w0, [[TRUE]], wzr, vc
259 ; CHECK-CVT-NEXT: ret
261 ; CHECK-FP16-LABEL: test_fcmp_ueq:
262 ; CHECK-FP16-NEXT: fcmp h0, h1
263 ; CHECK-FP16-NEXT: cset [[TRUE:w[0-9]+]], eq
264 ; CHECK-FP16-NEXT: csinc w0, [[TRUE]], wzr, vc
265 ; CHECK-FP16-NEXT: ret
267 define i1 @test_fcmp_ueq(half %a, half %b) #0 {
268 %r = fcmp ueq half %a, %b
272 ; CHECK-CVT-LABEL: test_fcmp_ugt:
273 ; CHECK-CVT-NEXT: fcvt s1, h1
274 ; CHECK-CVT-NEXT: fcvt s0, h0
275 ; CHECK-CVT-NEXT: fcmp s0, s1
276 ; CHECK-CVT-NEXT: cset w0, hi
277 ; CHECK-CVT-NEXT: ret
279 ; CHECK-FP16-LABEL: test_fcmp_ugt:
280 ; CHECK-FP16-NEXT: fcmp h0, h1
281 ; CHECK-FP16-NEXT: cset w0, hi
282 ; CHECK-FP16-NEXT: ret
284 define i1 @test_fcmp_ugt(half %a, half %b) #0 {
285 %r = fcmp ugt half %a, %b
289 ; CHECK-CVT-LABEL: test_fcmp_uge:
290 ; CHECK-CVT-NEXT: fcvt s1, h1
291 ; CHECK-CVT-NEXT: fcvt s0, h0
292 ; CHECK-CVT-NEXT: fcmp s0, s1
293 ; CHECK-CVT-NEXT: cset w0, pl
294 ; CHECK-CVT-NEXT: ret
296 ; CHECK-FP16-LABEL: test_fcmp_uge:
297 ; CHECK-FP16-NEXT: fcmp h0, h1
298 ; CHECK-FP16-NEXT: cset w0, pl
299 ; CHECK-FP16-NEXT: ret
301 define i1 @test_fcmp_uge(half %a, half %b) #0 {
302 %r = fcmp uge half %a, %b
306 ; CHECK-CVT-LABEL: test_fcmp_ult:
307 ; CHECK-CVT-NEXT: fcvt s1, h1
308 ; CHECK-CVT-NEXT: fcvt s0, h0
309 ; CHECK-CVT-NEXT: fcmp s0, s1
310 ; CHECK-CVT-NEXT: cset w0, lt
311 ; CHECK-CVT-NEXT: ret
313 ; CHECK-FP16-LABEL: test_fcmp_ult:
314 ; CHECK-FP16-NEXT: fcmp h0, h1
315 ; CHECK-FP16-NEXT: cset w0, lt
316 ; CHECK-FP16-NEXT: ret
318 define i1 @test_fcmp_ult(half %a, half %b) #0 {
319 %r = fcmp ult half %a, %b
323 ; CHECK-CVT-LABEL: test_fcmp_ule:
324 ; CHECK-CVT-NEXT: fcvt s1, h1
325 ; CHECK-CVT-NEXT: fcvt s0, h0
326 ; CHECK-CVT-NEXT: fcmp s0, s1
327 ; CHECK-CVT-NEXT: cset w0, le
328 ; CHECK-CVT-NEXT: ret
330 ; CHECK-FP16-LABEL: test_fcmp_ule:
331 ; CHECK-FP16-NEXT: fcmp h0, h1
332 ; CHECK-FP16-NEXT: cset w0, le
333 ; CHECK-FP16-NEXT: ret
335 define i1 @test_fcmp_ule(half %a, half %b) #0 {
336 %r = fcmp ule half %a, %b
340 ; CHECK-CVT-LABEL: test_fcmp_uno:
341 ; CHECK-CVT-NEXT: fcvt s1, h1
342 ; CHECK-CVT-NEXT: fcvt s0, h0
343 ; CHECK-CVT-NEXT: fcmp s0, s1
344 ; CHECK-CVT-NEXT: cset w0, vs
345 ; CHECK-CVT-NEXT: ret
347 ; CHECK-FP16-LABEL: test_fcmp_uno:
348 ; CHECK-FP16-NEXT: fcmp h0, h1
349 ; CHECK-FP16-NEXT: cset w0, vs
350 ; CHECK-FP16-NEXT: ret
352 define i1 @test_fcmp_uno(half %a, half %b) #0 {
353 %r = fcmp uno half %a, %b
357 ; CHECK-CVT-LABEL: test_fcmp_one:
358 ; CHECK-CVT-NEXT: fcvt s1, h1
359 ; CHECK-CVT-NEXT: fcvt s0, h0
360 ; CHECK-CVT-NEXT: fcmp s0, s1
361 ; CHECK-CVT-NEXT: cset [[TRUE:w[0-9]+]], mi
362 ; CHECK-CVT-NEXT: csinc w0, [[TRUE]], wzr, le
363 ; CHECK-CVT-NEXT: ret
365 ; CHECK-FP16-LABEL: test_fcmp_one:
366 ; CHECK-FP16-NEXT: fcmp h0, h1
367 ; CHECK-FP16-NEXT: cset [[TRUE:w[0-9]+]], mi
368 ; CHECK-FP16-NEXT: csinc w0, [[TRUE]], wzr, le
369 ; CHECK-FP16-NEXT: ret
371 define i1 @test_fcmp_one(half %a, half %b) #0 {
372 %r = fcmp one half %a, %b
376 ; CHECK-CVT-LABEL: test_fcmp_oeq:
377 ; CHECK-CVT-NEXT: fcvt s1, h1
378 ; CHECK-CVT-NEXT: fcvt s0, h0
379 ; CHECK-CVT-NEXT: fcmp s0, s1
380 ; CHECK-CVT-NEXT: cset w0, eq
381 ; CHECK-CVT-NEXT: ret
383 ; CHECK-FP16-LABEL: test_fcmp_oeq:
384 ; CHECK-FP16-NEXT: fcmp h0, h1
385 ; CHECK-FP16-NEXT: cset w0, eq
386 ; CHECK-FP16-NEXT: ret
388 define i1 @test_fcmp_oeq(half %a, half %b) #0 {
389 %r = fcmp oeq half %a, %b
393 ; CHECK-CVT-LABEL: test_fcmp_ogt:
394 ; CHECK-CVT-NEXT: fcvt s1, h1
395 ; CHECK-CVT-NEXT: fcvt s0, h0
396 ; CHECK-CVT-NEXT: fcmp s0, s1
397 ; CHECK-CVT-NEXT: cset w0, gt
398 ; CHECK-CVT-NEXT: ret
400 ; CHECK-FP16-LABEL: test_fcmp_ogt:
401 ; CHECK-FP16-NEXT: fcmp h0, h1
402 ; CHECK-FP16-NEXT: cset w0, gt
403 ; CHECK-FP16-NEXT: ret
405 define i1 @test_fcmp_ogt(half %a, half %b) #0 {
406 %r = fcmp ogt half %a, %b
410 ; CHECK-CVT-LABEL: test_fcmp_oge:
411 ; CHECK-CVT-NEXT: fcvt s1, h1
412 ; CHECK-CVT-NEXT: fcvt s0, h0
413 ; CHECK-CVT-NEXT: fcmp s0, s1
414 ; CHECK-CVT-NEXT: cset w0, ge
415 ; CHECK-CVT-NEXT: ret
417 ; CHECK-FP16-LABEL: test_fcmp_oge:
418 ; CHECK-FP16-NEXT: fcmp h0, h1
419 ; CHECK-FP16-NEXT: cset w0, ge
420 ; CHECK-FP16-NEXT: ret
422 define i1 @test_fcmp_oge(half %a, half %b) #0 {
423 %r = fcmp oge half %a, %b
427 ; CHECK-CVT-LABEL: test_fcmp_olt:
428 ; CHECK-CVT-NEXT: fcvt s1, h1
429 ; CHECK-CVT-NEXT: fcvt s0, h0
430 ; CHECK-CVT-NEXT: fcmp s0, s1
431 ; CHECK-CVT-NEXT: cset w0, mi
432 ; CHECK-CVT-NEXT: ret
434 ; CHECK-FP16-LABEL: test_fcmp_olt:
435 ; CHECK-FP16-NEXT: fcmp h0, h1
436 ; CHECK-FP16-NEXT: cset w0, mi
437 ; CHECK-FP16-NEXT: ret
439 define i1 @test_fcmp_olt(half %a, half %b) #0 {
440 %r = fcmp olt half %a, %b
444 ; CHECK-CVT-LABEL: test_fcmp_ole:
445 ; CHECK-CVT-NEXT: fcvt s1, h1
446 ; CHECK-CVT-NEXT: fcvt s0, h0
447 ; CHECK-CVT-NEXT: fcmp s0, s1
448 ; CHECK-CVT-NEXT: cset w0, ls
449 ; CHECK-CVT-NEXT: ret
451 ; CHECK-FP16-LABEL: test_fcmp_ole:
452 ; CHECK-FP16-NEXT: fcmp h0, h1
453 ; CHECK-FP16-NEXT: cset w0, ls
454 ; CHECK-FP16-NEXT: ret
456 define i1 @test_fcmp_ole(half %a, half %b) #0 {
457 %r = fcmp ole half %a, %b
461 ; CHECK-CVT-LABEL: test_fcmp_ord:
462 ; CHECK-CVT-NEXT: fcvt s1, h1
463 ; CHECK-CVT-NEXT: fcvt s0, h0
464 ; CHECK-CVT-NEXT: fcmp s0, s1
465 ; CHECK-CVT-NEXT: cset w0, vc
466 ; CHECK-CVT-NEXT: ret
468 ; CHECK-FP16-LABEL: test_fcmp_ord:
469 ; CHECK-FP16-NEXT: fcmp h0, h1
470 ; CHECK-FP16-NEXT: cset w0, vc
471 ; CHECK-FP16-NEXT: ret
473 define i1 @test_fcmp_ord(half %a, half %b) #0 {
474 %r = fcmp ord half %a, %b
478 ; CHECK-COMMON-LABEL: test_fccmp:
479 ; CHECK-CVT: fcvt s1, h0
480 ; CHECK-CVT-NEXT: fmov s2, #5.00000000
481 ; CHECK-CVT-NEXT: fcmp s1, s2
482 ; CHECK-CVT-NEXT: fmov s2, #8.00000000
483 ; CHECK-CVT-NEXT: fccmp s1, s2, #4, mi
484 ; CHECK-CVT-NEXT: adrp x8
485 ; CHECK-CVT-NEXT: ldr h1, [x8,
486 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, gt
487 ; CHECK-CVT-NEXT: str h0, [x0]
488 ; CHECK-CVT-NEXT: ret
489 ; CHECK-FP16: fmov h1, #5.00000000
490 ; CHECK-FP16-NEXT: fcmp h0, h1
491 ; CHECK-FP16-NEXT: fmov h2, #8.00000000
492 ; CHECK-FP16-NEXT: fccmp h0, h2, #4, mi
493 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, gt
494 ; CHECK-FP16-NEXT: str h0, [x0]
495 ; CHECK-FP16-NEXT: ret
497 define void @test_fccmp(half %in, ptr %out) {
498 %cmp1 = fcmp ogt half %in, 0xH4800
499 %cmp2 = fcmp olt half %in, 0xH4500
500 %cond = and i1 %cmp1, %cmp2
501 %result = select i1 %cond, half %in, half 0xH4500
502 store half %result, ptr %out
506 ; CHECK-CVT-LABEL: test_br_cc:
507 ; CHECK-CVT-NEXT: fcvt s1, h1
508 ; CHECK-CVT-NEXT: fcvt s0, h0
509 ; CHECK-CVT-NEXT: fcmp s0, s1
510 ; CHECK-CVT-NEXT: csel x8, x0, x1, pl
511 ; CHECK-CVT-NEXT: str wzr, [x8]
512 ; CHECK-CVT-NEXT: ret
514 ; CHECK-FP16-LABEL: test_br_cc:
515 ; CHECK-FP16-NEXT: fcmp h0, h1
516 ; CHECK-FP16-NEXT: csel x8, x0, x1, pl
517 ; CHECK-FP16-NEXT: str wzr, [x8]
518 ; CHECK-FP16-NEXT: ret
520 define void @test_br_cc(half %a, half %b, ptr %p1, ptr %p2) #0 {
521 %c = fcmp uge half %a, %b
522 br i1 %c, label %then, label %else
531 ; CHECK-COMMON-LABEL: test_phi:
532 ; CHECK-COMMON: mov x[[PTR:[0-9]+]], x0
533 ; CHECK-COMMON: ldr h[[AB:[0-9]+]], [x0]
534 ; CHECK-COMMON: [[LOOP:LBB[0-9_]+]]:
535 ; CHECK-COMMON: fmov s[[R:[0-9]+]], s[[AB]]
536 ; CHECK-COMMON: ldr h[[AB]], [x[[PTR]]]
537 ; CHECK-COMMON: mov x0, x[[PTR]]
538 ; CHECK-COMMON: bl {{_?}}test_dummy
539 ; CHECK-COMMON: fmov s0, s[[R]]
541 define half @test_phi(ptr %p1) #0 {
543 %a = load half, ptr %p1
546 %r = phi half [%a, %entry], [%b, %loop]
547 %b = load half, ptr %p1
548 %c = call i1 @test_dummy(ptr %p1)
549 br i1 %c, label %loop, label %return
554 declare i1 @test_dummy(ptr %p1) #0
556 ; CHECK-CVT-LABEL: test_fptosi_i32:
557 ; CHECK-CVT-NEXT: fcvt s0, h0
558 ; CHECK-CVT-NEXT: fcvtzs w0, s0
559 ; CHECK-CVT-NEXT: ret
561 ; CHECK-FP16-LABEL: test_fptosi_i32:
562 ; CHECK-FP16-NEXT: fcvtzs w0, h0
563 ; CHECK-FP16-NEXT: ret
565 define i32 @test_fptosi_i32(half %a) #0 {
566 %r = fptosi half %a to i32
570 ; CHECK-CVT-LABEL: test_fptosi_i64:
571 ; CHECK-CVT-NEXT: fcvt s0, h0
572 ; CHECK-CVT-NEXT: fcvtzs x0, s0
573 ; CHECK-CVT-NEXT: ret
575 ; CHECK-FP16-LABEL: test_fptosi_i64:
576 ; CHECK-FP16-NEXT: fcvtzs x0, h0
577 ; CHECK-FP16-NEXT: ret
579 define i64 @test_fptosi_i64(half %a) #0 {
580 %r = fptosi half %a to i64
584 ; CHECK-CVT-LABEL: test_fptoui_i32:
585 ; CHECK-CVT-NEXT: fcvt s0, h0
586 ; CHECK-CVT-NEXT: fcvtzu w0, s0
587 ; CHECK-CVT-NEXT: ret
589 ; CHECK-FP16-LABEL: test_fptoui_i32:
590 ; CHECK-FP16-NEXT: fcvtzu w0, h0
591 ; CHECK-FP16-NEXT: ret
593 define i32 @test_fptoui_i32(half %a) #0 {
594 %r = fptoui half %a to i32
598 ; CHECK-CVT-LABEL: test_fptoui_i64:
599 ; CHECK-CVT-NEXT: fcvt s0, h0
600 ; CHECK-CVT-NEXT: fcvtzu x0, s0
601 ; CHECK-CVT-NEXT: ret
603 ; CHECK-FP16-LABEL: test_fptoui_i64:
604 ; CHECK-FP16-NEXT: fcvtzu x0, h0
605 ; CHECK-FP16-NEXT: ret
607 define i64 @test_fptoui_i64(half %a) #0 {
608 %r = fptoui half %a to i64
612 ; CHECK-CVT-LABEL: test_uitofp_i32:
613 ; CHECK-CVT-NEXT: ucvtf s0, w0
614 ; CHECK-CVT-NEXT: fcvt h0, s0
615 ; CHECK-CVT-NEXT: ret
617 ; CHECK-FP16-LABEL: test_uitofp_i32:
618 ; CHECK-FP16-NEXT: ucvtf h0, w0
619 ; CHECK-FP16-NEXT: ret
621 define half @test_uitofp_i32(i32 %a) #0 {
622 %r = uitofp i32 %a to half
626 ; CHECK-CVT-LABEL: test_uitofp_i64:
627 ; CHECK-CVT-NEXT: ucvtf s0, x0
628 ; CHECK-CVT-NEXT: fcvt h0, s0
629 ; CHECK-CVT-NEXT: ret
631 ; CHECK-FP16-LABEL: test_uitofp_i64:
632 ; CHECK-FP16-NEXT: ucvtf h0, x0
633 ; CHECK-FP16-NEXT: ret
635 define half @test_uitofp_i64(i64 %a) #0 {
636 %r = uitofp i64 %a to half
640 ; CHECK-CVT-LABEL: test_sitofp_i32:
641 ; CHECK-CVT-NEXT: scvtf s0, w0
642 ; CHECK-CVT-NEXT: fcvt h0, s0
643 ; CHECK-CVT-NEXT: ret
645 ; CHECK-FP16-LABEL: test_sitofp_i32:
646 ; CHECK-FP16-NEXT: scvtf h0, w0
647 ; CHECK-FP16-NEXT: ret
649 define half @test_sitofp_i32(i32 %a) #0 {
650 %r = sitofp i32 %a to half
654 ; CHECK-CVT-LABEL: test_sitofp_i64:
655 ; CHECK-CVT-NEXT: scvtf s0, x0
656 ; CHECK-CVT-NEXT: fcvt h0, s0
657 ; CHECK-CVT-NEXT: ret
659 ; CHECK-FP16-LABEL: test_sitofp_i64:
660 ; CHECK-FP16-NEXT: scvtf h0, x0
661 ; CHECK-FP16-NEXT: ret
662 define half @test_sitofp_i64(i64 %a) #0 {
663 %r = sitofp i64 %a to half
667 ; CHECK-CVT-LABEL: test_uitofp_i32_fadd:
668 ; CHECK-CVT-NEXT: ucvtf s1, w0
669 ; CHECK-CVT-NEXT: fcvt h1, s1
670 ; CHECK-CVT-NEXT: fcvt s0, h0
671 ; CHECK-CVT-NEXT: fcvt s1, h1
672 ; CHECK-CVT-NEXT: fadd s0, s0, s1
673 ; CHECK-CVT-NEXT: fcvt h0, s0
674 ; CHECK-CVT-NEXT: ret
676 ; CHECK-FP16-LABEL: test_uitofp_i32_fadd:
677 ; CHECK-FP16-NEXT: ucvtf h1, w0
678 ; CHECK-FP16-NEXT: fadd h0, h0, h1
679 ; CHECK-FP16-NEXT: ret
681 define half @test_uitofp_i32_fadd(i32 %a, half %b) #0 {
682 %c = uitofp i32 %a to half
683 %r = fadd half %b, %c
687 ; CHECK-CVT-LABEL: test_sitofp_i32_fadd:
688 ; CHECK-CVT-NEXT: scvtf s1, w0
689 ; CHECK-CVT-NEXT: fcvt h1, s1
690 ; CHECK-CVT-NEXT: fcvt s0, h0
691 ; CHECK-CVT-NEXT: fcvt s1, h1
692 ; CHECK-CVT-NEXT: fadd s0, s0, s1
693 ; CHECK-CVT-NEXT: fcvt h0, s0
694 ; CHECK-CVT-NEXT: ret
696 ; CHECK-FP16-LABEL: test_sitofp_i32_fadd:
697 ; CHECK-FP16-NEXT: scvtf h1, w0
698 ; CHECK-FP16-NEXT: fadd h0, h0, h1
699 ; CHECK-FP16-NEXT: ret
701 define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 {
702 %c = sitofp i32 %a to half
703 %r = fadd half %b, %c
707 ; CHECK-COMMON-LABEL: test_fptrunc_float:
708 ; CHECK-COMMON-NEXT: fcvt h0, s0
709 ; CHECK-COMMON-NEXT: ret
711 define half @test_fptrunc_float(float %a) #0 {
712 %r = fptrunc float %a to half
716 ; CHECK-COMMON-LABEL: test_fptrunc_double:
717 ; CHECK-COMMON-NEXT: fcvt h0, d0
718 ; CHECK-COMMON-NEXT: ret
719 define half @test_fptrunc_double(double %a) #0 {
720 %r = fptrunc double %a to half
724 ; CHECK-COMMON-LABEL: test_fpext_float:
725 ; CHECK-COMMON-NEXT: fcvt s0, h0
726 ; CHECK-COMMON-NEXT: ret
727 define float @test_fpext_float(half %a) #0 {
728 %r = fpext half %a to float
732 ; CHECK-COMMON-LABEL: test_fpext_double:
733 ; CHECK-COMMON-NEXT: fcvt d0, h0
734 ; CHECK-COMMON-NEXT: ret
735 define double @test_fpext_double(half %a) #0 {
736 %r = fpext half %a to double
741 ; CHECK-COMMON-LABEL: test_bitcast_halftoi16:
742 ; CHECK-COMMON-NEXT: fmov w0, s0
743 ; CHECK-COMMON-NEXT: ret
744 define i16 @test_bitcast_halftoi16(half %a) #0 {
745 %r = bitcast half %a to i16
749 ; CHECK-COMMON-LABEL: test_bitcast_i16tohalf:
750 ; CHECK-COMMON-NEXT: fmov s0, w0
751 ; CHECK-COMMON-NEXT: ret
752 define half @test_bitcast_i16tohalf(i16 %a) #0 {
753 %r = bitcast i16 %a to half
758 declare half @llvm.sqrt.f16(half %a) #0
759 declare half @llvm.powi.f16.i32(half %a, i32 %b) #0
760 declare half @llvm.sin.f16(half %a) #0
761 declare half @llvm.cos.f16(half %a) #0
762 declare half @llvm.pow.f16(half %a, half %b) #0
763 declare half @llvm.exp.f16(half %a) #0
764 declare half @llvm.exp2.f16(half %a) #0
765 declare half @llvm.log.f16(half %a) #0
766 declare half @llvm.log10.f16(half %a) #0
767 declare half @llvm.log2.f16(half %a) #0
768 declare half @llvm.fma.f16(half %a, half %b, half %c) #0
769 declare half @llvm.fabs.f16(half %a) #0
770 declare half @llvm.minnum.f16(half %a, half %b) #0
771 declare half @llvm.maxnum.f16(half %a, half %b) #0
772 declare half @llvm.copysign.f16(half %a, half %b) #0
773 declare half @llvm.floor.f16(half %a) #0
774 declare half @llvm.ceil.f16(half %a) #0
775 declare half @llvm.trunc.f16(half %a) #0
776 declare half @llvm.rint.f16(half %a) #0
777 declare half @llvm.nearbyint.f16(half %a) #0
778 declare half @llvm.round.f16(half %a) #0
779 declare half @llvm.roundeven.f16(half %a) #0
780 declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0
782 ; FALLBACK-NOT: remark:{{.*}}test_sqrt
783 ; FALLBACK-FP16-NOT: remark:{{.*}}test_sqrt
785 ; CHECK-CVT-LABEL: test_sqrt:
786 ; CHECK-CVT-NEXT: fcvt s0, h0
787 ; CHECK-CVT-NEXT: fsqrt s0, s0
788 ; CHECK-CVT-NEXT: fcvt h0, s0
789 ; CHECK-CVT-NEXT: ret
791 ; CHECK-FP16-LABEL: test_sqrt:
792 ; CHECK-FP16-NEXT: fsqrt h0, h0
793 ; CHECK-FP16-NEXT: ret
795 ; GISEL-CVT-LABEL: test_sqrt:
796 ; GISEL-CVT-NEXT: fcvt s0, h0
797 ; GISEL-CVT-NEXT: fsqrt s0, s0
798 ; GISEL-CVT-NEXT: fcvt h0, s0
799 ; GISEL-CVT-NEXT: ret
801 ; GISEL-FP16-LABEL: test_sqrt:
802 ; GISEL-FP16-NEXT: fsqrt h0, h0
803 ; GISEL-FP16-NEXT: ret
805 define half @test_sqrt(half %a) #0 {
806 %r = call half @llvm.sqrt.f16(half %a)
810 ; CHECK-COMMON-LABEL: test_powi:
811 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
812 ; CHECK-COMMON-NEXT: mov x29, sp
813 ; CHECK-COMMON-NEXT: fcvt s0, h0
814 ; CHECK-COMMON-NEXT: bl {{_?}}__powisf2
815 ; CHECK-COMMON-NEXT: fcvt h0, s0
816 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
817 ; CHECK-COMMON-NEXT: ret
818 define half @test_powi(half %a, i32 %b) #0 {
819 %r = call half @llvm.powi.f16.i32(half %a, i32 %b)
823 ; FALLBACK-NOT: remark:{{.*}}test_sin
824 ; FALLBACK-FP16-NOT: remark:{{.*}}test_sin
826 ; CHECK-COMMON-LABEL: test_sin:
827 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
828 ; CHECK-COMMON-NEXT: mov x29, sp
829 ; CHECK-COMMON-NEXT: fcvt s0, h0
830 ; CHECK-COMMON-NEXT: bl {{_?}}sinf
831 ; CHECK-COMMON-NEXT: fcvt h0, s0
832 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
833 ; CHECK-COMMON-NEXT: ret
835 ; GISEL-LABEL: test_sin:
836 ; GISEL-NEXT: stp x29, x30, [sp, #-16]!
837 ; GISEL-NEXT: mov x29, sp
838 ; GISEL-NEXT: fcvt s0, h0
839 ; GISEL-NEXT: bl {{_?}}sinf
840 ; GISEL-NEXT: fcvt h0, s0
841 ; GISEL-NEXT: ldp x29, x30, [sp], #16
843 define half @test_sin(half %a) #0 {
844 %r = call half @llvm.sin.f16(half %a)
848 ; FALLBACK-NOT: remark:{{.*}}test_cos
849 ; FALLBACK-FP16-NOT: remark:{{.*}}test_cos
851 ; CHECK-COMMON-LABEL: test_cos:
852 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
853 ; CHECK-COMMON-NEXT: mov x29, sp
854 ; CHECK-COMMON-NEXT: fcvt s0, h0
855 ; CHECK-COMMON-NEXT: bl {{_?}}cosf
856 ; CHECK-COMMON-NEXT: fcvt h0, s0
857 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
858 ; CHECK-COMMON-NEXT: ret
860 ; GISEL-LABEL: test_cos:
861 ; GISEL-NEXT: stp x29, x30, [sp, #-16]!
862 ; GISEL-NEXT: mov x29, sp
863 ; GISEL-NEXT: fcvt s0, h0
864 ; GISEL-NEXT: bl {{_?}}cosf
865 ; GISEL-NEXT: fcvt h0, s0
866 ; GISEL-NEXT: ldp x29, x30, [sp], #16
868 define half @test_cos(half %a) #0 {
869 %r = call half @llvm.cos.f16(half %a)
873 ; CHECK-COMMON-LABEL: test_pow:
874 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
875 ; CHECK-COMMON-NEXT: mov x29, sp
876 ; CHECK-COMMON-NEXT: fcvt s0, h0
877 ; CHECK-COMMON-NEXT: fcvt s1, h1
878 ; CHECK-COMMON-NEXT: bl {{_?}}powf
879 ; CHECK-COMMON-NEXT: fcvt h0, s0
880 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
881 ; CHECK-COMMON-NEXT: ret
882 define half @test_pow(half %a, half %b) #0 {
883 %r = call half @llvm.pow.f16(half %a, half %b)
887 ; FALLBACK-NOT: remark:{{.*}}test_exp
888 ; FALLBACK-FP16-NOT: remark:{{.*}}test_exp
890 ; CHECK-COMMON-LABEL: test_exp:
891 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
892 ; CHECK-COMMON-NEXT: mov x29, sp
893 ; CHECK-COMMON-NEXT: fcvt s0, h0
894 ; CHECK-COMMON-NEXT: bl {{_?}}expf
895 ; CHECK-COMMON-NEXT: fcvt h0, s0
896 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
897 ; CHECK-COMMON-NEXT: ret
899 ; GISEL-LABEL: test_exp:
900 ; GISEL-NEXT: stp x29, x30, [sp, #-16]!
901 ; GISEL-NEXT: mov x29, sp
902 ; GISEL-NEXT: fcvt s0, h0
903 ; GISEL-NEXT: bl {{_?}}expf
904 ; GISEL-NEXT: fcvt h0, s0
905 ; GISEL-NEXT: ldp x29, x30, [sp], #16
907 define half @test_exp(half %a) #0 {
908 %r = call half @llvm.exp.f16(half %a)
912 ; CHECK-COMMON-LABEL: test_exp2:
913 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
914 ; CHECK-COMMON-NEXT: mov x29, sp
915 ; CHECK-COMMON-NEXT: fcvt s0, h0
916 ; CHECK-COMMON-NEXT: bl {{_?}}exp2f
917 ; CHECK-COMMON-NEXT: fcvt h0, s0
918 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
919 ; CHECK-COMMON-NEXT: ret
921 ; GISEL-LABEL: test_exp2:
922 ; GISEL-NEXT: stp x29, x30, [sp, #-16]!
923 ; GISEL-NEXT: mov x29, sp
924 ; GISEL-NEXT: fcvt s0, h0
925 ; GISEL-NEXT: bl {{_?}}exp2f
926 ; GISEL-NEXT: fcvt h0, s0
927 ; GISEL-NEXT: ldp x29, x30, [sp], #16
929 define half @test_exp2(half %a) #0 {
930 %r = call half @llvm.exp2.f16(half %a)
934 ; FALLBACK-NOT: remark:{{.*}}test_log
935 ; FALLBACK-FP16-NOT: remark:{{.*}}test_log
937 ; CHECK-COMMON-LABEL: test_log:
938 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
939 ; CHECK-COMMON-NEXT: mov x29, sp
940 ; CHECK-COMMON-NEXT: fcvt s0, h0
941 ; CHECK-COMMON-NEXT: bl {{_?}}logf
942 ; CHECK-COMMON-NEXT: fcvt h0, s0
943 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
944 ; CHECK-COMMON-NEXT: ret
946 ; GISEL-LABEL: test_log:
947 ; GISEL: stp x29, x30, [sp, #-16]!
948 ; GISEL-NEXT: mov x29, sp
949 ; GISEL-NEXT: fcvt s0, h0
950 ; GISEL-NEXT: bl {{_?}}logf
951 ; GISEL-NEXT: fcvt h0, s0
952 ; GISEL-NEXT: ldp x29, x30, [sp], #16
955 define half @test_log(half %a) #0 {
956 %r = call half @llvm.log.f16(half %a)
960 ; FALLBACK-NOT: remark:{{.*}}test_log10
961 ; FALLBACK-FP16-NOT: remark:{{.*}}test_log10
963 ; CHECK-COMMON-LABEL: test_log10:
964 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
965 ; CHECK-COMMON-NEXT: mov x29, sp
966 ; CHECK-COMMON-NEXT: fcvt s0, h0
967 ; CHECK-COMMON-NEXT: bl {{_?}}log10f
968 ; CHECK-COMMON-NEXT: fcvt h0, s0
969 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
970 ; CHECK-COMMON-NEXT: ret
972 ; GISEL-LABEL: test_log10:
973 ; GISEL-NEXT: stp x29, x30, [sp, #-16]!
974 ; GISEL-NEXT: mov x29, sp
975 ; GISEL-NEXT: fcvt s0, h0
976 ; GISEL-NEXT: bl {{_?}}log10f
977 ; GISEL-NEXT: fcvt h0, s0
978 ; GISEL-NEXT: ldp x29, x30, [sp], #16
981 define half @test_log10(half %a) #0 {
982 %r = call half @llvm.log10.f16(half %a)
986 ; FALLBACK-NOT: remark:{{.*}}test_log2
987 ; FALLBACK-FP16-NOT: remark:{{.*}}test_log2
989 ; CHECK-COMMON-LABEL: test_log2:
990 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
991 ; CHECK-COMMON-NEXT: mov x29, sp
992 ; CHECK-COMMON-NEXT: fcvt s0, h0
993 ; CHECK-COMMON-NEXT: bl {{_?}}log2f
994 ; CHECK-COMMON-NEXT: fcvt h0, s0
995 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
996 ; CHECK-COMMON-NEXT: ret
998 ; GISEL-LABEL: test_log2:
999 ; GISEL-NEXT: stp x29, x30, [sp, #-16]!
1000 ; GISEL-NEXT: mov x29, sp
1001 ; GISEL-NEXT: fcvt s0, h0
1002 ; GISEL-NEXT: bl {{_?}}log2f
1003 ; GISEL-NEXT: fcvt h0, s0
1004 ; GISEL-NEXT: ldp x29, x30, [sp], #16
1007 define half @test_log2(half %a) #0 {
1008 %r = call half @llvm.log2.f16(half %a)
1012 ; CHECK-CVT-LABEL: test_fma:
1013 ; CHECK-CVT-NEXT: fcvt s2, h2
1014 ; CHECK-CVT-NEXT: fcvt s1, h1
1015 ; CHECK-CVT-NEXT: fcvt s0, h0
1016 ; CHECK-CVT-NEXT: fmadd s0, s0, s1, s2
1017 ; CHECK-CVT-NEXT: fcvt h0, s0
1018 ; CHECK-CVT-NEXT: ret
1020 ; CHECK-FP16-LABEL: test_fma:
1021 ; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
1022 ; CHECK-FP16-NEXT: ret
1024 define half @test_fma(half %a, half %b, half %c) #0 {
1025 %r = call half @llvm.fma.f16(half %a, half %b, half %c)
1029 ; CHECK-CVT-LABEL: test_fabs:
1030 ; CHECK-CVT-NEXT: fcvt s0, h0
1031 ; CHECK-CVT-NEXT: fabs s0, s0
1032 ; CHECK-CVT-NEXT: fcvt h0, s0
1033 ; CHECK-CVT-NEXT: ret
1035 ; CHECK-FP16-LABEL: test_fabs:
1036 ; CHECK-FP16-NEXT: fabs h0, h0
1037 ; CHECK-FP16-NEXT: ret
1039 ; FALLBACK-NOT: remark:{{.*}}test_fabs
1040 ; FALLBACK-FP16-NOT: remark:{{.*}}test_fabs
1042 ; GISEL-CVT-LABEL: test_fabs:
1043 ; GISEL-CVT-NEXT: fcvt s0, h0
1044 ; GISEL-CVT-NEXT: fabs s0, s0
1045 ; GISEL-CVT-NEXT: fcvt h0, s0
1046 ; GISEL-CVT-NEXT: ret
1048 ; GISEL-FP16-LABEL: test_fabs:
1049 ; GISEL-FP16-NEXT: fabs h0, h0
1050 ; GISEL-FP16-NEXT: ret
1052 define half @test_fabs(half %a) #0 {
1053 %r = call half @llvm.fabs.f16(half %a)
1057 ; CHECK-CVT-LABEL: test_minnum:
1058 ; CHECK-CVT-NEXT: fcvt s1, h1
1059 ; CHECK-CVT-NEXT: fcvt s0, h0
1060 ; CHECK-CVT-NEXT: fminnm s0, s0, s1
1061 ; CHECK-CVT-NEXT: fcvt h0, s0
1062 ; CHECK-CVT-NEXT: ret
1064 ; CHECK-FP16-LABEL: test_minnum:
1065 ; CHECK-FP16-NEXT: fminnm h0, h0, h1
1066 ; CHECK-FP16-NEXT: ret
1068 define half @test_minnum(half %a, half %b) #0 {
1069 %r = call half @llvm.minnum.f16(half %a, half %b)
1073 ; CHECK-CVT-LABEL: test_maxnum:
1074 ; CHECK-CVT-NEXT: fcvt s1, h1
1075 ; CHECK-CVT-NEXT: fcvt s0, h0
1076 ; CHECK-CVT-NEXT: fmaxnm s0, s0, s1
1077 ; CHECK-CVT-NEXT: fcvt h0, s0
1078 ; CHECK-CVT-NEXT: ret
1080 ; CHECK-FP16-LABEL: test_maxnum:
1081 ; CHECK-FP16-NEXT: fmaxnm h0, h0, h1
1082 ; CHECK-FP16-NEXT: ret
1084 define half @test_maxnum(half %a, half %b) #0 {
1085 %r = call half @llvm.maxnum.f16(half %a, half %b)
1089 ; CHECK-CVT-LABEL: test_copysign:
1090 ; CHECK-CVT-NEXT: fcvt s1, h1
1091 ; CHECK-CVT-NEXT: fcvt s0, h0
1092 ; CHECK-CVT-NEXT: mvni.4s v2, #128, lsl #24
1093 ; CHECK-CVT-NEXT: bif.16b v0, v1, v2
1094 ; CHECK-CVT-NEXT: fcvt h0, s0
1095 ; CHECK-CVT-NEXT: ret
1097 ; CHECK-FP16-LABEL: test_copysign:
1098 ; CHECK-FP16-NEXT: mvni.8h v2, #128, lsl #8
1099 ; CHECK-FP16-NEXT: bif.16b v0, v1, v2
1100 ; CHECK-FP16-NEXT: ret
1102 define half @test_copysign(half %a, half %b) #0 {
1103 %r = call half @llvm.copysign.f16(half %a, half %b)
1107 ; CHECK-CVT-LABEL: test_copysign_f32:
1108 ; CHECK-CVT-NEXT: fcvt s0, h0
1109 ; CHECK-CVT-NEXT: mvni.4s v2, #128, lsl #24
1110 ; CHECK-CVT-NEXT: bif.16b v0, v1, v2
1111 ; CHECK-CVT-NEXT: fcvt h0, s0
1112 ; CHECK-CVT-NEXT: ret
1114 ; CHECK-FP16-LABEL: test_copysign_f32:
1115 ; CHECK-FP16-NEXT: fcvt h1, s1
1116 ; CHECK-FP16-NEXT: mvni.8h v2, #128, lsl #8
1117 ; CHECK-FP16-NEXT: bif.16b v0, v1, v2
1118 ; CHECK-FP16-NEXT: ret
1120 define half @test_copysign_f32(half %a, float %b) #0 {
1121 %tb = fptrunc float %b to half
1122 %r = call half @llvm.copysign.f16(half %a, half %tb)
1126 ; CHECK-CVT-LABEL: test_copysign_f64:
1127 ; CHECK-CVT-NEXT: fcvt s1, d1
1128 ; CHECK-CVT-NEXT: fcvt s0, h0
1129 ; CHECK-CVT-NEXT: mvni.4s v2, #128, lsl #24
1130 ; CHECK-CVT-NEXT: bif.16b v0, v1, v2
1131 ; CHECK-CVT-NEXT: fcvt h0, s0
1132 ; CHECK-CVT-NEXT: ret
1134 ; CHECK-FP16-LABEL: test_copysign_f64:
1135 ; CHECK-FP16-NEXT: fcvt h1, d1
1136 ; CHECK-FP16-NEXT: mvni.8h v2, #128, lsl #8
1137 ; CHECK-FP16-NEXT: bif.16b v0, v1, v2
1138 ; CHECK-FP16-NEXT: ret
1140 define half @test_copysign_f64(half %a, double %b) #0 {
1141 %tb = fptrunc double %b to half
1142 %r = call half @llvm.copysign.f16(half %a, half %tb)
1146 ; Check that the FP promotion will use a truncating FP_ROUND, so we can fold
1147 ; away the (fpext (fp_round <result>)) here.
1149 ; CHECK-CVT-LABEL: test_copysign_extended:
1150 ; CHECK-CVT-NEXT: fcvt s1, h1
1151 ; CHECK-CVT-NEXT: fcvt s0, h0
1152 ; CHECK-CVT-NEXT: mvni.4s v2, #128, lsl #24
1153 ; CHECK-CVT-NEXT: bif.16b v0, v1, v2
1154 ; CHECK-CVT-NEXT: ret
1156 ; CHECK-FP16-LABEL: test_copysign_extended:
1157 ; CHECK-FP16-NEXT: mvni.8h v2, #128, lsl #8
1158 ; CHECK-FP16-NEXT: bif.16b v0, v1, v2
1159 ; CHECK-FP16-NEXT: fcvt s0, h0
1160 ; CHECK-FP16-NEXT: ret
1162 define float @test_copysign_extended(half %a, half %b) #0 {
1163 %r = call half @llvm.copysign.f16(half %a, half %b)
1164 %xr = fpext half %r to float
1168 ; CHECK-CVT-LABEL: test_floor:
1169 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1170 ; CHECK-CVT-NEXT: frintm [[INT32:s[0-9]+]], [[FLOAT32]]
1171 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
1172 ; CHECK-CVT-NEXT: ret
1174 ; CHECK-FP16-LABEL: test_floor:
1175 ; CHECK-FP16-NEXT: frintm h0, h0
1176 ; CHECK-FP16-NEXT: ret
1178 ; FALLBACK-NOT: remark:{{.*}}test_floor
1179 ; FALLBACK-FP16-NOT: remark:{{.*}}test_floor
1181 ; GISEL-CVT-LABEL: test_floor:
1182 ; GISEL-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1183 ; GISEL-CVT-NEXT: frintm [[INT32:s[0-9]+]], [[FLOAT32]]
1184 ; GISEL-CVT-NEXT: fcvt h0, [[INT32]]
1185 ; GISEL-CVT-NEXT: ret
1187 ; GISEL-FP16-LABEL: test_floor:
1188 ; GISEL-FP16-NEXT: frintm h0, h0
1189 ; GISEL-FP16-NEXT: ret
1191 define half @test_floor(half %a) #0 {
1192 %r = call half @llvm.floor.f16(half %a)
1196 ; CHECK-CVT-LABEL: test_ceil:
1197 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1198 ; CHECK-CVT-NEXT: frintp [[INT32:s[0-9]+]], [[FLOAT32]]
1199 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
1200 ; CHECK-CVT-NEXT: ret
1202 ; CHECK-FP16-LABEL: test_ceil:
1203 ; CHECK-FP16-NEXT: frintp h0, h0
1204 ; CHECK-FP16-NEXT: ret
1206 ; FALLBACK-NOT: remark:{{.*}}test_ceil
1207 ; FALLBACK-FP16-NOT: remark:{{.*}}test_ceil
1209 ; GISEL-CVT-LABEL: test_ceil:
1210 ; GISEL-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1211 ; GISEL-CVT-NEXT: frintp [[INT32:s[0-9]+]], [[FLOAT32]]
1212 ; GISEL-CVT-NEXT: fcvt h0, [[INT32]]
1213 ; GISEL-CVT-NEXT: ret
1215 ; GISEL-FP16-LABEL: test_ceil:
1216 ; GISEL-FP16-NEXT: frintp h0, h0
1217 ; GISEL-FP16-NEXT: ret
1218 define half @test_ceil(half %a) #0 {
1219 %r = call half @llvm.ceil.f16(half %a)
1223 ; CHECK-CVT-LABEL: test_trunc:
1224 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1225 ; CHECK-CVT-NEXT: frintz [[INT32:s[0-9]+]], [[FLOAT32]]
1226 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
1227 ; CHECK-CVT-NEXT: ret
1229 ; CHECK-FP16-LABEL: test_trunc:
1230 ; CHECK-FP16-NEXT: frintz h0, h0
1231 ; CHECK-FP16-NEXT: ret
1233 define half @test_trunc(half %a) #0 {
1234 %r = call half @llvm.trunc.f16(half %a)
1238 ; CHECK-CVT-LABEL: test_rint:
1239 ; CHECK-CVT-NEXT: fcvt s0, h0
1240 ; CHECK-CVT-NEXT: frintx s0, s0
1241 ; CHECK-CVT-NEXT: fcvt h0, s0
1242 ; CHECK-CVT-NEXT: ret
1244 ; CHECK-FP16-LABEL: test_rint:
1245 ; CHECK-FP16-NEXT: frintx h0, h0
1246 ; CHECK-FP16-NEXT: ret
1248 define half @test_rint(half %a) #0 {
1249 %r = call half @llvm.rint.f16(half %a)
1253 ; CHECK-CVT-LABEL: test_nearbyint:
1254 ; CHECK-CVT-NEXT: fcvt s0, h0
1255 ; CHECK-CVT-NEXT: frinti s0, s0
1256 ; CHECK-CVT-NEXT: fcvt h0, s0
1257 ; CHECK-CVT-NEXT: ret
1259 ; CHECK-FP16-LABEL: test_nearbyint:
1260 ; CHECK-FP16-NEXT: frinti h0, h0
1261 ; CHECK-FP16-NEXT: ret
1263 define half @test_nearbyint(half %a) #0 {
1264 %r = call half @llvm.nearbyint.f16(half %a)
1268 ; CHECK-CVT-LABEL: test_round:
1269 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1270 ; CHECK-CVT-NEXT: frinta [[INT32:s[0-9]+]], [[FLOAT32]]
1271 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
1272 ; CHECK-CVT-NEXT: ret
1274 ; GISEL-CVT-LABEL: test_round:
1275 ; GISEL-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1276 ; GISEL-CVT-NEXT: frinta [[INT32:s[0-9]+]], [[FLOAT32]]
1277 ; GISEL-CVT-NEXT: fcvt h0, [[INT32]]
1278 ; GISEL-CVT-NEXT: ret
1281 ; CHECK-FP16-LABEL: test_round:
1282 ; CHECK-FP16-NEXT: frinta h0, h0
1283 ; CHECK-FP16-NEXT: ret
1285 ; GISEL-FP16-LABEL: test_round:
1286 ; GISEL-FP16-NEXT: frinta h0, h0
1287 ; GISEL-FP16-NEXT: ret
1289 define half @test_round(half %a) #0 {
1290 %r = call half @llvm.round.f16(half %a)
1294 ; CHECK-CVT-LABEL: test_roundeven:
1295 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1296 ; CHECK-CVT-NEXT: frintn [[INT32:s[0-9]+]], [[FLOAT32]]
1297 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
1298 ; CHECK-CVT-NEXT: ret
1300 ; GISEL-CVT-LABEL: test_roundeven:
1301 ; GISEL-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
1302 ; GISEL-CVT-NEXT: frintn [[INT32:s[0-9]+]], [[FLOAT32]]
1303 ; GISEL-CVT-NEXT: fcvt h0, [[INT32]]
1304 ; GISEL-CVT-NEXT: ret
1307 ; CHECK-FP16-LABEL: test_roundeven:
1308 ; CHECK-FP16-NEXT: frintn h0, h0
1309 ; CHECK-FP16-NEXT: ret
1311 ; GISEL-FP16-LABEL: test_roundeven:
1312 ; GISEL-FP16-NEXT: frintn h0, h0
1313 ; GISEL-FP16-NEXT: ret
1315 define half @test_roundeven(half %a) #0 {
1316 %r = call half @llvm.roundeven.f16(half %a)
1320 ; CHECK-CVT-LABEL: test_fmuladd:
1321 ; CHECK-CVT-NEXT: fcvt s1, h1
1322 ; CHECK-CVT-NEXT: fcvt s0, h0
1323 ; CHECK-CVT-NEXT: fmul s0, s0, s1
1324 ; CHECK-CVT-NEXT: fcvt h0, s0
1325 ; CHECK-CVT-NEXT: fcvt s0, h0
1326 ; CHECK-CVT-NEXT: fcvt s1, h2
1327 ; CHECK-CVT-NEXT: fadd s0, s0, s1
1328 ; CHECK-CVT-NEXT: fcvt h0, s0
1329 ; CHECK-CVT-NEXT: ret
1331 ; CHECK-FP16-LABEL: test_fmuladd:
1332 ; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
1333 ; CHECK-FP16-NEXT: ret
1335 define half @test_fmuladd(half %a, half %b, half %c) #0 {
1336 %r = call half @llvm.fmuladd.f16(half %a, half %b, half %c)
1340 attributes #0 = { nounwind }