Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc < %s -mtriple aarch64-unknown-unknown -aarch64-neon-syntax=apple -asm-verbose=false -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK-CVT --check-prefix=CHECK-COMMON
      2 ; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 -aarch64-neon-syntax=apple -asm-verbose=false -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-FP16
      3 
      4 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
      5 
      6 ; CHECK-CVT-LABEL: test_fadd:
      7 ; CHECK-CVT-NEXT: fcvt s1, h1
      8 ; CHECK-CVT-NEXT: fcvt s0, h0
      9 ; CHECK-CVT-NEXT: fadd s0, s0, s1
     10 ; CHECK-CVT-NEXT: fcvt h0, s0
     11 ; CHECK-CVT-NEXT: ret
     12 
     13 ; CHECK-FP16-LABEL: test_fadd:
     14 ; CHECK-FP16-NEXT:  fadd h0, h0, h1
     15 ; CHECK-FP16-NEXT:  ret
     16 
     17 define half @test_fadd(half %a, half %b) #0 {
     18   %r = fadd half %a, %b
     19   ret half %r
     20 }
     21 
     22 ; CHECK-CVT-LABEL: test_fsub:
     23 ; CHECK-CVT-NEXT: fcvt s1, h1
     24 ; CHECK-CVT-NEXT: fcvt s0, h0
     25 ; CHECK-CVT-NEXT: fsub s0, s0, s1
     26 ; CHECK-CVT-NEXT: fcvt h0, s0
     27 ; CHECK-CVT-NEXT: ret
     28 
     29 ; CHECK-FP16-LABEL: test_fsub:
     30 ; CHECK-FP16-NEXT: fsub h0, h0, h1
     31 ; CHECK-FP16-NEXT: ret
     32 
     33 define half @test_fsub(half %a, half %b) #0 {
     34   %r = fsub half %a, %b
     35   ret half %r
     36 }
     37 
     38 ; CHECK-CVT-LABEL: test_fmul:
     39 ; CHECK-CVT-NEXT: fcvt s1, h1
     40 ; CHECK-CVT-NEXT: fcvt s0, h0
     41 ; CHECK-CVT-NEXT: fmul s0, s0, s1
     42 ; CHECK-CVT-NEXT: fcvt h0, s0
     43 ; CHECK-CVT-NEXT: ret
     44 
     45 ; CHECK-FP16-LABEL: test_fmul:
     46 ; CHECK-FP16-NEXT: fmul h0, h0, h1
     47 ; CHECK-FP16-NEXT: ret
     48 
     49 define half @test_fmul(half %a, half %b) #0 {
     50   %r = fmul half %a, %b
     51   ret half %r
     52 }
     53 
     54 ; CHECK-CVT-LABEL: test_fdiv:
     55 ; CHECK-CVT-NEXT: fcvt s1, h1
     56 ; CHECK-CVT-NEXT: fcvt s0, h0
     57 ; CHECK-CVT-NEXT: fdiv s0, s0, s1
     58 ; CHECK-CVT-NEXT: fcvt h0, s0
     59 ; CHECK-CVT-NEXT: ret
     60 
     61 ; CHECK-FP16-LABEL: test_fdiv:
     62 ; CHECK-FP16-NEXT: fdiv	h0, h0, h1
     63 ; CHECK-FP16-NEXT: ret
     64 
     65 define half @test_fdiv(half %a, half %b) #0 {
     66   %r = fdiv half %a, %b
     67   ret half %r
     68 }
     69 
     70 ; CHECK-COMMON-LABEL: test_frem:
     71 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
     72 ; CHECK-COMMON-NEXT: mov  x29, sp
     73 ; CHECK-COMMON-NEXT: fcvt s0, h0
     74 ; CHECK-COMMON-NEXT: fcvt s1, h1
     75 ; CHECK-COMMON-NEXT: bl {{_?}}fmodf
     76 ; CHECK-COMMON-NEXT: fcvt h0, s0
     77 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
     78 ; CHECK-COMMON-NEXT: ret
     79 define half @test_frem(half %a, half %b) #0 {
     80   %r = frem half %a, %b
     81   ret half %r
     82 }
     83 
     84 ; CHECK-COMMON-LABEL: test_store:
     85 ; CHECK-COMMON-NEXT: str  h0, [x0]
     86 ; CHECK-COMMON-NEXT: ret
     87 define void @test_store(half %a, half* %b) #0 {
     88   store half %a, half* %b
     89   ret void
     90 }
     91 
     92 ; CHECK-COMMON-LABEL: test_load:
     93 ; CHECK-COMMON-NEXT: ldr  h0, [x0]
     94 ; CHECK-COMMON-NEXT: ret
     95 define half @test_load(half* %a) #0 {
     96   %r = load half, half* %a
     97   ret half %r
     98 }
     99 
    100 declare half @test_callee(half %a, half %b) #0
    101 
    102 ; CHECK-COMMON-LABEL: test_call:
    103 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    104 ; CHECK-COMMON-NEXT: mov  x29, sp
    105 ; CHECK-COMMON-NEXT: bl {{_?}}test_callee
    106 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    107 ; CHECK-COMMON-NEXT: ret
    108 define half @test_call(half %a, half %b) #0 {
    109   %r = call half @test_callee(half %a, half %b)
    110   ret half %r
    111 }
    112 
    113 ; CHECK-COMMON-LABEL: test_call_flipped:
    114 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    115 ; CHECK-COMMON-NEXT: mov  x29, sp
    116 ; CHECK-COMMON-NEXT: mov.16b  v2, v0
    117 ; CHECK-COMMON-NEXT: mov.16b  v0, v1
    118 ; CHECK-COMMON-NEXT: mov.16b  v1, v2
    119 ; CHECK-COMMON-NEXT: bl {{_?}}test_callee
    120 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    121 ; CHECK-COMMON-NEXT: ret
    122 define half @test_call_flipped(half %a, half %b) #0 {
    123   %r = call half @test_callee(half %b, half %a)
    124   ret half %r
    125 }
    126 
    127 ; CHECK-COMMON-LABEL: test_tailcall_flipped:
    128 ; CHECK-COMMON-NEXT: mov.16b  v2, v0
    129 ; CHECK-COMMON-NEXT: mov.16b  v0, v1
    130 ; CHECK-COMMON-NEXT: mov.16b  v1, v2
    131 ; CHECK-COMMON-NEXT: b {{_?}}test_callee
    132 define half @test_tailcall_flipped(half %a, half %b) #0 {
    133   %r = tail call half @test_callee(half %b, half %a)
    134   ret half %r
    135 }
    136 
    137 ; CHECK-CVT-LABEL: test_select:
    138 ; CHECK-CVT-NEXT: fcvt s1, h1
    139 ; CHECK-CVT-NEXT: fcvt s0, h0
    140 ; CHECK-CVT-NEXT: cmp  w0, #0
    141 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
    142 ; CHECK-CVT-NEXT: fcvt h0, s0
    143 ; CHECK-CVT-NEXT: ret
    144 
    145 ; CHECK-FP16-LABEL: test_select:
    146 ; CHECK-FP16-NEXT: cmp w0, #0
    147 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, ne
    148 ; CHECK-FP16-NEXT: ret
    149 
    150 define half @test_select(half %a, half %b, i1 zeroext %c) #0 {
    151   %r = select i1 %c, half %a, half %b
    152   ret half %r
    153 }
    154 
    155 ; CHECK-CVT-LABEL: test_select_cc:
    156 ; CHECK-CVT-DAG: fcvt s3, h3
    157 ; CHECK-CVT-DAG: fcvt s2, h2
    158 ; CHECK-CVT-DAG: fcvt s1, h1
    159 ; CHECK-CVT-DAG: fcvt s0, h0
    160 ; CHECK-CVT-DAG: fcmp s2, s3
    161 ; CHECK-CVT-DAG: cset [[CC:w[0-9]+]], ne
    162 ; CHECK-CVT-DAG: cmp [[CC]], #0
    163 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
    164 ; CHECK-CVT-NEXT: fcvt h0, s0
    165 ; CHECK-CVT-NEXT: ret
    166 
    167 ; CHECK-FP16-LABEL: test_select_cc:
    168 ; CHECK-FP16-NEXT: fcmp h2, h3
    169 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, ne
    170 ; CHECK-FP16-NEXT: ret
    171 
    172 define half @test_select_cc(half %a, half %b, half %c, half %d) #0 {
    173   %cc = fcmp une half %c, %d
    174   %r = select i1 %cc, half %a, half %b
    175   ret half %r
    176 }
    177 
    178 ; CHECK-CVT-LABEL: test_select_cc_f32_f16:
    179 ; CHECK-CVT-DAG:   fcvt s2, h2
    180 ; CHECK-CVT-DAG:   fcvt s3, h3
    181 ; CHECK-CVT-NEXT:  fcmp s2, s3
    182 ; CHECK-CVT-NEXT:  fcsel s0, s0, s1, ne
    183 ; CHECK-CVT-NEXT:  ret
    184 
    185 ; CHECK-FP16-LABEL: test_select_cc_f32_f16:
    186 ; CHECK-FP16-NEXT: fcmp	h2, h3
    187 ; CHECK-FP16-NEXT: fcsel	s0, s0, s1, ne
    188 ; CHECK-FP16-NEXT: ret
    189 
    190 define float @test_select_cc_f32_f16(float %a, float %b, half %c, half %d) #0 {
    191   %cc = fcmp une half %c, %d
    192   %r = select i1 %cc, float %a, float %b
    193   ret float %r
    194 }
    195 
    196 ; CHECK-CVT-LABEL: test_select_cc_f16_f32:
    197 ; CHECK-CVT-DAG:  fcvt s0, h0
    198 ; CHECK-CVT-DAG:  fcvt s1, h1
    199 ; CHECK-CVT-DAG:  fcmp s2, s3
    200 ; CHECK-CVT-DAG:  cset w8, ne
    201 ; CHECK-CVT-NEXT: cmp w8, #0
    202 ; CHECK-CVT-NEXT: fcsel s0, s0, s1, ne
    203 ; CHECK-CVT-NEXT: fcvt h0, s0
    204 ; CHECK-CVT-NEXT: ret
    205 
    206 ; CHECK-FP16-LABEL: test_select_cc_f16_f32:
    207 ; CHECK-FP16-NEXT: fcmp	s2, s3
    208 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, ne
    209 ; CHECK-FP16-NEXT: ret
    210 
    211 define half @test_select_cc_f16_f32(half %a, half %b, float %c, float %d) #0 {
    212   %cc = fcmp une float %c, %d
    213   %r = select i1 %cc, half %a, half %b
    214   ret half %r
    215 }
    216 
    217 ; CHECK-CVT-LABEL: test_fcmp_une:
    218 ; CHECK-CVT-NEXT: fcvt s1, h1
    219 ; CHECK-CVT-NEXT: fcvt s0, h0
    220 ; CHECK-CVT-NEXT: fcmp s0, s1
    221 ; CHECK-CVT-NEXT: cset  w0, ne
    222 ; CHECK-CVT-NEXT: ret
    223 
    224 ; CHECK-FP16-LABEL: test_fcmp_une:
    225 ; CHECK-FP16-NEXT: fcmp	h0, h1
    226 ; CHECK-FP16-NEXT: cset w0, ne
    227 ; CHECK-FP16-NEXT: ret
    228 
    229 define i1 @test_fcmp_une(half %a, half %b) #0 {
    230   %r = fcmp une half %a, %b
    231   ret i1 %r
    232 }
    233 
    234 ; CHECK-CVT-LABEL: test_fcmp_ueq:
    235 ; CHECK-CVT-NEXT: fcvt s1, h1
    236 ; CHECK-CVT-NEXT: fcvt s0, h0
    237 ; CHECK-CVT-NEXT: fcmp s0, s1
    238 ; CHECK-CVT-NEXT: cset [[TRUE:w[0-9]+]], eq
    239 ; CHECK-CVT-NEXT: csinc w0, [[TRUE]], wzr, vc
    240 ; CHECK-CVT-NEXT: ret
    241 
    242 ; CHECK-FP16-LABEL: test_fcmp_ueq:
    243 ; CHECK-FP16-NEXT: fcmp	h0, h1
    244 ; CHECK-FP16-NEXT: cset [[TRUE:w[0-9]+]], eq
    245 ; CHECK-FP16-NEXT: csinc w0, [[TRUE]], wzr, vc
    246 ; CHECK-FP16-NEXT: ret
    247 
    248 define i1 @test_fcmp_ueq(half %a, half %b) #0 {
    249   %r = fcmp ueq half %a, %b
    250   ret i1 %r
    251 }
    252 
    253 ; CHECK-CVT-LABEL: test_fcmp_ugt:
    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  w0, hi
    258 ; CHECK-CVT-NEXT: ret
    259 
    260 ; CHECK-FP16-LABEL: test_fcmp_ugt:
    261 ; CHECK-FP16-NEXT: fcmp h0, h1
    262 ; CHECK-FP16-NEXT: cset  w0, hi
    263 ; CHECK-FP16-NEXT: ret
    264 
    265 define i1 @test_fcmp_ugt(half %a, half %b) #0 {
    266   %r = fcmp ugt half %a, %b
    267   ret i1 %r
    268 }
    269 
    270 ; CHECK-CVT-LABEL: test_fcmp_uge:
    271 ; CHECK-CVT-NEXT: fcvt s1, h1
    272 ; CHECK-CVT-NEXT: fcvt s0, h0
    273 ; CHECK-CVT-NEXT: fcmp s0, s1
    274 ; CHECK-CVT-NEXT: cset  w0, pl
    275 ; CHECK-CVT-NEXT: ret
    276 
    277 ; CHECK-FP16-LABEL: test_fcmp_uge:
    278 ; CHECK-FP16-NEXT: fcmp h0, h1
    279 ; CHECK-FP16-NEXT: cset  w0, pl
    280 ; CHECK-FP16-NEXT: ret
    281 
    282 define i1 @test_fcmp_uge(half %a, half %b) #0 {
    283   %r = fcmp uge half %a, %b
    284   ret i1 %r
    285 }
    286 
    287 ; CHECK-CVT-LABEL: test_fcmp_ult:
    288 ; CHECK-CVT-NEXT: fcvt s1, h1
    289 ; CHECK-CVT-NEXT: fcvt s0, h0
    290 ; CHECK-CVT-NEXT: fcmp s0, s1
    291 ; CHECK-CVT-NEXT: cset  w0, lt
    292 ; CHECK-CVT-NEXT: ret
    293 
    294 ; CHECK-FP16-LABEL: test_fcmp_ult:
    295 ; CHECK-FP16-NEXT: fcmp h0, h1
    296 ; CHECK-FP16-NEXT: cset  w0, lt
    297 ; CHECK-FP16-NEXT: ret
    298 
    299 define i1 @test_fcmp_ult(half %a, half %b) #0 {
    300   %r = fcmp ult half %a, %b
    301   ret i1 %r
    302 }
    303 
    304 ; CHECK-CVT-LABEL: test_fcmp_ule:
    305 ; CHECK-CVT-NEXT: fcvt s1, h1
    306 ; CHECK-CVT-NEXT: fcvt s0, h0
    307 ; CHECK-CVT-NEXT: fcmp s0, s1
    308 ; CHECK-CVT-NEXT: cset  w0, le
    309 ; CHECK-CVT-NEXT: ret
    310 
    311 ; CHECK-FP16-LABEL: test_fcmp_ule:
    312 ; CHECK-FP16-NEXT: fcmp h0, h1
    313 ; CHECK-FP16-NEXT: cset  w0, le
    314 ; CHECK-FP16-NEXT: ret
    315 
    316 define i1 @test_fcmp_ule(half %a, half %b) #0 {
    317   %r = fcmp ule half %a, %b
    318   ret i1 %r
    319 }
    320 
    321 ; CHECK-CVT-LABEL: test_fcmp_uno:
    322 ; CHECK-CVT-NEXT: fcvt s1, h1
    323 ; CHECK-CVT-NEXT: fcvt s0, h0
    324 ; CHECK-CVT-NEXT: fcmp s0, s1
    325 ; CHECK-CVT-NEXT: cset  w0, vs
    326 ; CHECK-CVT-NEXT: ret
    327 
    328 ; CHECK-FP16-LABEL: test_fcmp_uno:
    329 ; CHECK-FP16-NEXT: fcmp h0, h1
    330 ; CHECK-FP16-NEXT: cset  w0, vs
    331 ; CHECK-FP16-NEXT: ret
    332 
    333 define i1 @test_fcmp_uno(half %a, half %b) #0 {
    334   %r = fcmp uno half %a, %b
    335   ret i1 %r
    336 }
    337 
    338 ; CHECK-CVT-LABEL: test_fcmp_one:
    339 ; CHECK-CVT-NEXT: fcvt s1, h1
    340 ; CHECK-CVT-NEXT: fcvt s0, h0
    341 ; CHECK-CVT-NEXT: fcmp s0, s1
    342 ; CHECK-CVT-NEXT: cset [[TRUE:w[0-9]+]], mi
    343 ; CHECK-CVT-NEXT: csinc w0, [[TRUE]], wzr, le
    344 ; CHECK-CVT-NEXT: ret
    345 
    346 ; CHECK-FP16-LABEL: test_fcmp_one:
    347 ; CHECK-FP16-NEXT: fcmp h0, h1
    348 ; CHECK-FP16-NEXT: cset [[TRUE:w[0-9]+]], mi
    349 ; CHECK-FP16-NEXT: csinc w0, [[TRUE]], wzr, le
    350 ; CHECK-FP16-NEXT: ret
    351 
    352 define i1 @test_fcmp_one(half %a, half %b) #0 {
    353   %r = fcmp one half %a, %b
    354   ret i1 %r
    355 }
    356 
    357 ; CHECK-CVT-LABEL: test_fcmp_oeq:
    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  w0, eq
    362 ; CHECK-CVT-NEXT: ret
    363 
    364 ; CHECK-FP16-LABEL: test_fcmp_oeq:
    365 ; CHECK-FP16-NEXT: fcmp h0, h1
    366 ; CHECK-FP16-NEXT: cset  w0, eq
    367 ; CHECK-FP16-NEXT: ret
    368 
    369 define i1 @test_fcmp_oeq(half %a, half %b) #0 {
    370   %r = fcmp oeq half %a, %b
    371   ret i1 %r
    372 }
    373 
    374 ; CHECK-CVT-LABEL: test_fcmp_ogt:
    375 ; CHECK-CVT-NEXT: fcvt s1, h1
    376 ; CHECK-CVT-NEXT: fcvt s0, h0
    377 ; CHECK-CVT-NEXT: fcmp s0, s1
    378 ; CHECK-CVT-NEXT: cset  w0, gt
    379 ; CHECK-CVT-NEXT: ret
    380 
    381 ; CHECK-FP16-LABEL: test_fcmp_ogt:
    382 ; CHECK-FP16-NEXT: fcmp h0, h1
    383 ; CHECK-FP16-NEXT: cset  w0, gt
    384 ; CHECK-FP16-NEXT: ret
    385 
    386 define i1 @test_fcmp_ogt(half %a, half %b) #0 {
    387   %r = fcmp ogt half %a, %b
    388   ret i1 %r
    389 }
    390 
    391 ; CHECK-CVT-LABEL: test_fcmp_oge:
    392 ; CHECK-CVT-NEXT: fcvt s1, h1
    393 ; CHECK-CVT-NEXT: fcvt s0, h0
    394 ; CHECK-CVT-NEXT: fcmp s0, s1
    395 ; CHECK-CVT-NEXT: cset  w0, ge
    396 ; CHECK-CVT-NEXT: ret
    397 
    398 ; CHECK-FP16-LABEL: test_fcmp_oge:
    399 ; CHECK-FP16-NEXT: fcmp h0, h1
    400 ; CHECK-FP16-NEXT: cset  w0, ge
    401 ; CHECK-FP16-NEXT: ret
    402 
    403 define i1 @test_fcmp_oge(half %a, half %b) #0 {
    404   %r = fcmp oge half %a, %b
    405   ret i1 %r
    406 }
    407 
    408 ; CHECK-CVT-LABEL: test_fcmp_olt:
    409 ; CHECK-CVT-NEXT: fcvt s1, h1
    410 ; CHECK-CVT-NEXT: fcvt s0, h0
    411 ; CHECK-CVT-NEXT: fcmp s0, s1
    412 ; CHECK-CVT-NEXT: cset  w0, mi
    413 ; CHECK-CVT-NEXT: ret
    414 
    415 ; CHECK-FP16-LABEL: test_fcmp_olt:
    416 ; CHECK-FP16-NEXT: fcmp h0, h1
    417 ; CHECK-FP16-NEXT: cset  w0, mi
    418 ; CHECK-FP16-NEXT: ret
    419 
    420 define i1 @test_fcmp_olt(half %a, half %b) #0 {
    421   %r = fcmp olt half %a, %b
    422   ret i1 %r
    423 }
    424 
    425 ; CHECK-CVT-LABEL: test_fcmp_ole:
    426 ; CHECK-CVT-NEXT: fcvt s1, h1
    427 ; CHECK-CVT-NEXT: fcvt s0, h0
    428 ; CHECK-CVT-NEXT: fcmp s0, s1
    429 ; CHECK-CVT-NEXT: cset  w0, ls
    430 ; CHECK-CVT-NEXT: ret
    431 
    432 ; CHECK-FP16-LABEL: test_fcmp_ole:
    433 ; CHECK-FP16-NEXT: fcmp h0, h1
    434 ; CHECK-FP16-NEXT: cset  w0, ls
    435 ; CHECK-FP16-NEXT: ret
    436 
    437 define i1 @test_fcmp_ole(half %a, half %b) #0 {
    438   %r = fcmp ole half %a, %b
    439   ret i1 %r
    440 }
    441 
    442 ; CHECK-CVT-LABEL: test_fcmp_ord:
    443 ; CHECK-CVT-NEXT: fcvt s1, h1
    444 ; CHECK-CVT-NEXT: fcvt s0, h0
    445 ; CHECK-CVT-NEXT: fcmp s0, s1
    446 ; CHECK-CVT-NEXT: cset  w0, vc
    447 ; CHECK-CVT-NEXT: ret
    448 
    449 ; CHECK-FP16-LABEL: test_fcmp_ord:
    450 ; CHECK-FP16-NEXT: fcmp h0, h1
    451 ; CHECK-FP16-NEXT: cset  w0, vc
    452 ; CHECK-FP16-NEXT: ret
    453 
    454 define i1 @test_fcmp_ord(half %a, half %b) #0 {
    455   %r = fcmp ord half %a, %b
    456   ret i1 %r
    457 }
    458 
    459 ; CHECK-COMMON-LABEL: test_fccmp:
    460 ; CHECK-CVT:      fcvt  s0, h0
    461 ; CHECK-CVT-NEXT: fmov  s1, #8.00000000
    462 ; CHECK-CVT-NEXT: fmov  s2, #5.00000000
    463 ; CHECK-CVT-NEXT: fcmp  s0, s1
    464 ; CHECK-CVT-NEXT: cset  w8, gt
    465 ; CHECK-CVT-NEXT: fcmp  s0, s2
    466 ; CHECK-CVT-NEXT: cset  w9, mi
    467 ; CHECK-CVT-NEXT: tst   w8, w9
    468 ; CHECK-CVT-NEXT: fcsel s0, s0, s2, ne
    469 ; CHECK-CVT-NEXT: fcvt  h0, s0
    470 ; CHECK-CVT-NEXT: str   h0, [x0]
    471 ; CHECK-CVT-NEXT: ret
    472 ; CHECK-FP16:      fmov  h1, #5.00000000
    473 ; CHECK-FP16-NEXT: fcmp  h0, h1
    474 ; CHECK-FP16-NEXT: fmov  h2, #8.00000000
    475 ; CHECK-FP16-NEXT: fccmp h0, h2, #4, mi
    476 ; CHECK-FP16-NEXT: fcsel h0, h0, h1, gt
    477 ; CHECK-FP16-NEXT: str   h0, [x0]
    478 ; CHECK-FP16-NEXT: ret
    479 
    480 define void @test_fccmp(half %in, half* %out) {
    481   %cmp1 = fcmp ogt half %in, 0xH4800
    482   %cmp2 = fcmp olt half %in, 0xH4500
    483   %cond = and i1 %cmp1, %cmp2
    484   %result = select i1 %cond, half %in, half 0xH4500
    485   store half %result, half* %out
    486   ret void
    487 }
    488 
    489 ; CHECK-CVT-LABEL: test_br_cc:
    490 ; CHECK-CVT-NEXT: fcvt s1, h1
    491 ; CHECK-CVT-NEXT: fcvt s0, h0
    492 ; CHECK-CVT-NEXT: fcmp s0, s1
    493 ; CHECK-CVT-NEXT: b.mi [[BRCC_ELSE:.?LBB[0-9_]+]]
    494 ; CHECK-CVT-NEXT: str  wzr, [x0]
    495 ; CHECK-CVT-NEXT: ret
    496 ; CHECK-CVT-NEXT: [[BRCC_ELSE]]:
    497 ; CHECK-CVT-NEXT: str  wzr, [x1]
    498 ; CHECK-CVT-NEXT: ret
    499 
    500 ; CHECK-FP16-LABEL: test_br_cc:
    501 ; CHECK-FP16-NEXT: fcmp h0, h1
    502 ; CHECK-FP16-NEXT: b.mi [[BRCC_ELSE:.?LBB[0-9_]+]]
    503 ; CHECK-FP16-NEXT: str  wzr, [x0]
    504 ; CHECK-FP16-NEXT: ret
    505 ; CHECK-FP16-NEXT: [[BRCC_ELSE]]:
    506 ; CHECK-FP16-NEXT: str  wzr, [x1]
    507 ; CHECK-FP16-NEXT: ret
    508 
    509 define void @test_br_cc(half %a, half %b, i32* %p1, i32* %p2) #0 {
    510   %c = fcmp uge half %a, %b
    511   br i1 %c, label %then, label %else
    512 then:
    513   store i32 0, i32* %p1
    514   ret void
    515 else:
    516   store i32 0, i32* %p2
    517   ret void
    518 }
    519 
    520 ; CHECK-COMMON-LABEL: test_phi:
    521 ; CHECK-COMMON: mov  x[[PTR:[0-9]+]], x0
    522 ; CHECK-COMMON: ldr  h[[AB:[0-9]+]], [x0]
    523 ; CHECK-COMMON: [[LOOP:LBB[0-9_]+]]:
    524 ; CHECK-COMMON: mov.16b  v[[R:[0-9]+]], v[[AB]]
    525 ; CHECK-COMMON: ldr  h[[AB]], [x[[PTR]]]
    526 ; CHECK-COMMON: mov  x0, x[[PTR]]
    527 ; CHECK-COMMON: bl {{_?}}test_dummy
    528 ; CHECK-COMMON: mov.16b  v0, v[[R]]
    529 ; CHECK-COMMON: ret
    530 define half @test_phi(half* %p1) #0 {
    531 entry:
    532   %a = load half, half* %p1
    533   br label %loop
    534 loop:
    535   %r = phi half [%a, %entry], [%b, %loop]
    536   %b = load half, half* %p1
    537   %c = call i1 @test_dummy(half* %p1)
    538   br i1 %c, label %loop, label %return
    539 return:
    540   ret half %r
    541 }
    542 
    543 declare i1 @test_dummy(half* %p1) #0
    544 
    545 ; CHECK-CVT-LABEL: test_fptosi_i32:
    546 ; CHECK-CVT-NEXT: fcvt s0, h0
    547 ; CHECK-CVT-NEXT: fcvtzs w0, s0
    548 ; CHECK-CVT-NEXT: ret
    549 
    550 ; CHECK-FP16-LABEL: test_fptosi_i32:
    551 ; CHECK-FP16-NEXT: fcvtzs w0, h0
    552 ; CHECK-FP16-NEXT: ret
    553 
    554 define i32 @test_fptosi_i32(half %a) #0 {
    555   %r = fptosi half %a to i32
    556   ret i32 %r
    557 }
    558 
    559 ; CHECK-CVT-LABEL: test_fptosi_i64:
    560 ; CHECK-CVT-NEXT: fcvt s0, h0
    561 ; CHECK-CVT-NEXT: fcvtzs x0, s0
    562 ; CHECK-CVT-NEXT: ret
    563 
    564 ; CHECK-FP16-LABEL: test_fptosi_i64:
    565 ; CHECK-FP16-NEXT: fcvtzs x0, h0
    566 ; CHECK-FP16-NEXT: ret
    567 
    568 define i64 @test_fptosi_i64(half %a) #0 {
    569   %r = fptosi half %a to i64
    570   ret i64 %r
    571 }
    572 
    573 ; CHECK-CVT-LABEL: test_fptoui_i32:
    574 ; CHECK-CVT-NEXT: fcvt s0, h0
    575 ; CHECK-CVT-NEXT: fcvtzu w0, s0
    576 ; CHECK-CVT-NEXT: ret
    577 
    578 ; CHECK-FP16-LABEL: test_fptoui_i32:
    579 ; CHECK-FP16-NEXT: fcvtzu w0, h0
    580 ; CHECK-FP16-NEXT: ret
    581 
    582 define i32 @test_fptoui_i32(half %a) #0 {
    583   %r = fptoui half %a to i32
    584   ret i32 %r
    585 }
    586 
    587 ; CHECK-CVT-LABEL: test_fptoui_i64:
    588 ; CHECK-CVT-NEXT: fcvt s0, h0
    589 ; CHECK-CVT-NEXT: fcvtzu x0, s0
    590 ; CHECK-CVT-NEXT: ret
    591 
    592 ; CHECK-FP16-LABEL: test_fptoui_i64:
    593 ; CHECK-FP16-NEXT: fcvtzu x0, h0
    594 ; CHECK-FP16-NEXT: ret
    595 
    596 define i64 @test_fptoui_i64(half %a) #0 {
    597   %r = fptoui half %a to i64
    598   ret i64 %r
    599 }
    600 
    601 ; CHECK-CVT-LABEL: test_uitofp_i32:
    602 ; CHECK-CVT-NEXT: ucvtf s0, w0
    603 ; CHECK-CVT-NEXT: fcvt h0, s0
    604 ; CHECK-CVT-NEXT: ret
    605 
    606 ; CHECK-FP16-LABEL: test_uitofp_i32:
    607 ; CHECK-FP16-NEXT: ucvtf h0, w0
    608 ; CHECK-FP16-NEXT: ret
    609 
    610 define half @test_uitofp_i32(i32 %a) #0 {
    611   %r = uitofp i32 %a to half
    612   ret half %r
    613 }
    614 
    615 ; CHECK-CVT-LABEL: test_uitofp_i64:
    616 ; CHECK-CVT-NEXT: ucvtf s0, x0
    617 ; CHECK-CVT-NEXT: fcvt h0, s0
    618 ; CHECK-CVT-NEXT: ret
    619 
    620 ; CHECK-FP16-LABEL: test_uitofp_i64:
    621 ; CHECK-FP16-NEXT: ucvtf h0, x0
    622 ; CHECK-FP16-NEXT: ret
    623 
    624 define half @test_uitofp_i64(i64 %a) #0 {
    625   %r = uitofp i64 %a to half
    626   ret half %r
    627 }
    628 
    629 ; CHECK-CVT-LABEL: test_sitofp_i32:
    630 ; CHECK-CVT-NEXT: scvtf s0, w0
    631 ; CHECK-CVT-NEXT: fcvt h0, s0
    632 ; CHECK-CVT-NEXT: ret
    633 
    634 ; CHECK-FP16-LABEL: test_sitofp_i32:
    635 ; CHECK-FP16-NEXT: scvtf h0, w0
    636 ; CHECK-FP16-NEXT: ret
    637 
    638 define half @test_sitofp_i32(i32 %a) #0 {
    639   %r = sitofp i32 %a to half
    640   ret half %r
    641 }
    642 
    643 ; CHECK-CVT-LABEL: test_sitofp_i64:
    644 ; CHECK-CVT-NEXT: scvtf s0, x0
    645 ; CHECK-CVT-NEXT: fcvt h0, s0
    646 ; CHECK-CVT-NEXT: ret
    647 
    648 ; CHECK-FP16-LABEL: test_sitofp_i64:
    649 ; CHECK-FP16-NEXT: scvtf h0, x0
    650 ; CHECK-FP16-NEXT: ret
    651 define half @test_sitofp_i64(i64 %a) #0 {
    652   %r = sitofp i64 %a to half
    653   ret half %r
    654 }
    655 
    656 ; CHECK-CVT-LABEL: test_uitofp_i32_fadd:
    657 ; CHECK-CVT-NEXT: ucvtf s1, w0
    658 ; CHECK-CVT-NEXT: fcvt h1, s1
    659 ; CHECK-CVT-NEXT: fcvt s0, h0
    660 ; CHECK-CVT-NEXT: fcvt s1, h1
    661 ; CHECK-CVT-NEXT: fadd s0, s0, s1
    662 ; CHECK-CVT-NEXT: fcvt h0, s0
    663 ; CHECK-CVT-NEXT: ret
    664 
    665 ; CHECK-FP16-LABEL: test_uitofp_i32_fadd:
    666 ; CHECK-FP16-NEXT: ucvtf h1, w0
    667 ; CHECK-FP16-NEXT: fadd h0, h0, h1
    668 ; CHECK-FP16-NEXT: ret
    669 
    670 define half @test_uitofp_i32_fadd(i32 %a, half %b) #0 {
    671   %c = uitofp i32 %a to half
    672   %r = fadd half %b, %c
    673   ret half %r
    674 }
    675 
    676 ; CHECK-CVT-LABEL: test_sitofp_i32_fadd:
    677 ; CHECK-CVT-NEXT: scvtf s1, w0
    678 ; CHECK-CVT-NEXT: fcvt h1, s1
    679 ; CHECK-CVT-NEXT: fcvt s0, h0
    680 ; CHECK-CVT-NEXT: fcvt s1, h1
    681 ; CHECK-CVT-NEXT: fadd s0, s0, s1
    682 ; CHECK-CVT-NEXT: fcvt h0, s0
    683 ; CHECK-CVT-NEXT: ret
    684 
    685 ; CHECK-FP16-LABEL: test_sitofp_i32_fadd:
    686 ; CHECK-FP16-NEXT: scvtf h1, w0
    687 ; CHECK-FP16-NEXT: fadd h0, h0, h1
    688 ; CHECK-FP16-NEXT: ret
    689 
    690 define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 {
    691   %c = sitofp i32 %a to half
    692   %r = fadd half %b, %c
    693   ret half %r
    694 }
    695 
    696 ; CHECK-COMMON-LABEL: test_fptrunc_float:
    697 ; CHECK-COMMON-NEXT: fcvt h0, s0
    698 ; CHECK-COMMON-NEXT: ret
    699 
    700 define half @test_fptrunc_float(float %a) #0 {
    701   %r = fptrunc float %a to half
    702   ret half %r
    703 }
    704 
    705 ; CHECK-COMMON-LABEL: test_fptrunc_double:
    706 ; CHECK-COMMON-NEXT: fcvt h0, d0
    707 ; CHECK-COMMON-NEXT: ret
    708 define half @test_fptrunc_double(double %a) #0 {
    709   %r = fptrunc double %a to half
    710   ret half %r
    711 }
    712 
    713 ; CHECK-COMMON-LABEL: test_fpext_float:
    714 ; CHECK-COMMON-NEXT: fcvt s0, h0
    715 ; CHECK-COMMON-NEXT: ret
    716 define float @test_fpext_float(half %a) #0 {
    717   %r = fpext half %a to float
    718   ret float %r
    719 }
    720 
    721 ; CHECK-COMMON-LABEL: test_fpext_double:
    722 ; CHECK-COMMON-NEXT: fcvt d0, h0
    723 ; CHECK-COMMON-NEXT: ret
    724 define double @test_fpext_double(half %a) #0 {
    725   %r = fpext half %a to double
    726   ret double %r
    727 }
    728 
    729 
    730 ; CHECK-COMMON-LABEL: test_bitcast_halftoi16:
    731 ; CHECK-COMMON-NEXT: fmov w0, s0
    732 ; CHECK-COMMON-NEXT: ret
    733 define i16 @test_bitcast_halftoi16(half %a) #0 {
    734   %r = bitcast half %a to i16
    735   ret i16 %r
    736 }
    737 
    738 ; CHECK-COMMON-LABEL: test_bitcast_i16tohalf:
    739 ; CHECK-COMMON-NEXT: fmov s0, w0
    740 ; CHECK-COMMON-NEXT: ret
    741 define half @test_bitcast_i16tohalf(i16 %a) #0 {
    742   %r = bitcast i16 %a to half
    743   ret half %r
    744 }
    745 
    746 
    747 declare half @llvm.sqrt.f16(half %a) #0
    748 declare half @llvm.powi.f16(half %a, i32 %b) #0
    749 declare half @llvm.sin.f16(half %a) #0
    750 declare half @llvm.cos.f16(half %a) #0
    751 declare half @llvm.pow.f16(half %a, half %b) #0
    752 declare half @llvm.exp.f16(half %a) #0
    753 declare half @llvm.exp2.f16(half %a) #0
    754 declare half @llvm.log.f16(half %a) #0
    755 declare half @llvm.log10.f16(half %a) #0
    756 declare half @llvm.log2.f16(half %a) #0
    757 declare half @llvm.fma.f16(half %a, half %b, half %c) #0
    758 declare half @llvm.fabs.f16(half %a) #0
    759 declare half @llvm.minnum.f16(half %a, half %b) #0
    760 declare half @llvm.maxnum.f16(half %a, half %b) #0
    761 declare half @llvm.copysign.f16(half %a, half %b) #0
    762 declare half @llvm.floor.f16(half %a) #0
    763 declare half @llvm.ceil.f16(half %a) #0
    764 declare half @llvm.trunc.f16(half %a) #0
    765 declare half @llvm.rint.f16(half %a) #0
    766 declare half @llvm.nearbyint.f16(half %a) #0
    767 declare half @llvm.round.f16(half %a) #0
    768 declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0
    769 declare half @llvm.aarch64.neon.frecpe.f16(half %a) #0
    770 declare half @llvm.aarch64.neon.frecpx.f16(half %a) #0
    771 declare half @llvm.aarch64.neon.frsqrte.f16(half %a) #0
    772 
    773 ; CHECK-CVT-LABEL: test_sqrt:
    774 ; CHECK-CVT-NEXT: fcvt s0, h0
    775 ; CHECK-CVT-NEXT: fsqrt s0, s0
    776 ; CHECK-CVT-NEXT: fcvt h0, s0
    777 ; CHECK-CVT-NEXT: ret
    778 
    779 ; CHECK-FP16-LABEL: test_sqrt:
    780 ; CHECK-FP16-NEXT: fsqrt h0, h0
    781 ; CHECK-FP16-NEXT: ret
    782 
    783 define half @test_sqrt(half %a) #0 {
    784   %r = call half @llvm.sqrt.f16(half %a)
    785   ret half %r
    786 }
    787 
    788 ; CHECK-COMMON-LABEL: test_powi:
    789 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    790 ; CHECK-COMMON-NEXT: mov  x29, sp
    791 ; CHECK-COMMON-NEXT: fcvt s0, h0
    792 ; CHECK-COMMON-NEXT: bl {{_?}}__powisf2
    793 ; CHECK-COMMON-NEXT: fcvt h0, s0
    794 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    795 ; CHECK-COMMON-NEXT: ret
    796 define half @test_powi(half %a, i32 %b) #0 {
    797   %r = call half @llvm.powi.f16(half %a, i32 %b)
    798   ret half %r
    799 }
    800 
    801 ; CHECK-COMMON-LABEL: test_sin:
    802 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    803 ; CHECK-COMMON-NEXT: mov  x29, sp
    804 ; CHECK-COMMON-NEXT: fcvt s0, h0
    805 ; CHECK-COMMON-NEXT: bl {{_?}}sinf
    806 ; CHECK-COMMON-NEXT: fcvt h0, s0
    807 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    808 ; CHECK-COMMON-NEXT: ret
    809 define half @test_sin(half %a) #0 {
    810   %r = call half @llvm.sin.f16(half %a)
    811   ret half %r
    812 }
    813 
    814 ; CHECK-COMMON-LABEL: test_cos:
    815 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    816 ; CHECK-COMMON-NEXT: mov  x29, sp
    817 ; CHECK-COMMON-NEXT: fcvt s0, h0
    818 ; CHECK-COMMON-NEXT: bl {{_?}}cosf
    819 ; CHECK-COMMON-NEXT: fcvt h0, s0
    820 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    821 ; CHECK-COMMON-NEXT: ret
    822 define half @test_cos(half %a) #0 {
    823   %r = call half @llvm.cos.f16(half %a)
    824   ret half %r
    825 }
    826 
    827 ; CHECK-COMMON-LABEL: test_pow:
    828 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    829 ; CHECK-COMMON-NEXT: mov  x29, sp
    830 ; CHECK-COMMON-NEXT: fcvt s0, h0
    831 ; CHECK-COMMON-NEXT: fcvt s1, h1
    832 ; CHECK-COMMON-NEXT: bl {{_?}}powf
    833 ; CHECK-COMMON-NEXT: fcvt h0, s0
    834 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    835 ; CHECK-COMMON-NEXT: ret
    836 define half @test_pow(half %a, half %b) #0 {
    837   %r = call half @llvm.pow.f16(half %a, half %b)
    838   ret half %r
    839 }
    840 
    841 ; CHECK-COMMON-LABEL: test_exp:
    842 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    843 ; CHECK-COMMON-NEXT: mov  x29, sp
    844 ; CHECK-COMMON-NEXT: fcvt s0, h0
    845 ; CHECK-COMMON-NEXT: bl {{_?}}expf
    846 ; CHECK-COMMON-NEXT: fcvt h0, s0
    847 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    848 ; CHECK-COMMON-NEXT: ret
    849 define half @test_exp(half %a) #0 {
    850   %r = call half @llvm.exp.f16(half %a)
    851   ret half %r
    852 }
    853 
    854 ; CHECK-COMMON-LABEL: test_exp2:
    855 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    856 ; CHECK-COMMON-NEXT: mov  x29, sp
    857 ; CHECK-COMMON-NEXT: fcvt s0, h0
    858 ; CHECK-COMMON-NEXT: bl {{_?}}exp2f
    859 ; CHECK-COMMON-NEXT: fcvt h0, s0
    860 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    861 ; CHECK-COMMON-NEXT: ret
    862 define half @test_exp2(half %a) #0 {
    863   %r = call half @llvm.exp2.f16(half %a)
    864   ret half %r
    865 }
    866 
    867 ; CHECK-COMMON-LABEL: test_log:
    868 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    869 ; CHECK-COMMON-NEXT: mov  x29, sp
    870 ; CHECK-COMMON-NEXT: fcvt s0, h0
    871 ; CHECK-COMMON-NEXT: bl {{_?}}logf
    872 ; CHECK-COMMON-NEXT: fcvt h0, s0
    873 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    874 ; CHECK-COMMON-NEXT: ret
    875 define half @test_log(half %a) #0 {
    876   %r = call half @llvm.log.f16(half %a)
    877   ret half %r
    878 }
    879 
    880 ; CHECK-COMMON-LABEL: test_log10:
    881 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    882 ; CHECK-COMMON-NEXT: mov  x29, sp
    883 ; CHECK-COMMON-NEXT: fcvt s0, h0
    884 ; CHECK-COMMON-NEXT: bl {{_?}}log10f
    885 ; CHECK-COMMON-NEXT: fcvt h0, s0
    886 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    887 ; CHECK-COMMON-NEXT: ret
    888 define half @test_log10(half %a) #0 {
    889   %r = call half @llvm.log10.f16(half %a)
    890   ret half %r
    891 }
    892 
    893 ; CHECK-COMMON-LABEL: test_log2:
    894 ; CHECK-COMMON-NEXT: stp x29, x30, [sp, #-16]!
    895 ; CHECK-COMMON-NEXT: mov  x29, sp
    896 ; CHECK-COMMON-NEXT: fcvt s0, h0
    897 ; CHECK-COMMON-NEXT: bl {{_?}}log2f
    898 ; CHECK-COMMON-NEXT: fcvt h0, s0
    899 ; CHECK-COMMON-NEXT: ldp x29, x30, [sp], #16
    900 ; CHECK-COMMON-NEXT: ret
    901 define half @test_log2(half %a) #0 {
    902   %r = call half @llvm.log2.f16(half %a)
    903   ret half %r
    904 }
    905 
    906 ; CHECK-CVT-LABEL: test_fma:
    907 ; CHECK-CVT-NEXT: fcvt s2, h2
    908 ; CHECK-CVT-NEXT: fcvt s1, h1
    909 ; CHECK-CVT-NEXT: fcvt s0, h0
    910 ; CHECK-CVT-NEXT: fmadd s0, s0, s1, s2
    911 ; CHECK-CVT-NEXT: fcvt h0, s0
    912 ; CHECK-CVT-NEXT: ret
    913 
    914 ; CHECK-FP16-LABEL: test_fma:
    915 ; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
    916 ; CHECK-FP16-NEXT: ret
    917 
    918 define half @test_fma(half %a, half %b, half %c) #0 {
    919   %r = call half @llvm.fma.f16(half %a, half %b, half %c)
    920   ret half %r
    921 }
    922 
    923 ; CHECK-CVT-LABEL: test_fabs:
    924 ; CHECK-CVT-NEXT: fcvt s0, h0
    925 ; CHECK-CVT-NEXT: fabs s0, s0
    926 ; CHECK-CVT-NEXT: fcvt h0, s0
    927 ; CHECK-CVT-NEXT: ret
    928 
    929 ; CHECK-FP16-LABEL: test_fabs:
    930 ; CHECK-FP16-NEXT: fabs h0, h0
    931 ; CHECK-FP16-NEXT: ret
    932 
    933 define half @test_fabs(half %a) #0 {
    934   %r = call half @llvm.fabs.f16(half %a)
    935   ret half %r
    936 }
    937 
    938 ; CHECK-CVT-LABEL: test_minnum:
    939 ; CHECK-CVT-NEXT: fcvt s1, h1
    940 ; CHECK-CVT-NEXT: fcvt s0, h0
    941 ; CHECK-CVT-NEXT: fminnm s0, s0, s1
    942 ; CHECK-CVT-NEXT: fcvt h0, s0
    943 ; CHECK-CVT-NEXT: ret
    944 
    945 ; CHECK-FP16-LABEL: test_minnum:
    946 ; CHECK-FP16-NEXT: fminnm h0, h0, h1
    947 ; CHECK-FP16-NEXT: ret
    948 
    949 define half @test_minnum(half %a, half %b) #0 {
    950   %r = call half @llvm.minnum.f16(half %a, half %b)
    951   ret half %r
    952 }
    953 
    954 ; CHECK-CVT-LABEL: test_maxnum:
    955 ; CHECK-CVT-NEXT: fcvt s1, h1
    956 ; CHECK-CVT-NEXT: fcvt s0, h0
    957 ; CHECK-CVT-NEXT: fmaxnm s0, s0, s1
    958 ; CHECK-CVT-NEXT: fcvt h0, s0
    959 ; CHECK-CVT-NEXT: ret
    960 
    961 ; CHECK-FP16-LABEL: test_maxnum:
    962 ; CHECK-FP16-NEXT: fmaxnm h0, h0, h1
    963 ; CHECK-FP16-NEXT: ret
    964 
    965 define half @test_maxnum(half %a, half %b) #0 {
    966   %r = call half @llvm.maxnum.f16(half %a, half %b)
    967   ret half %r
    968 }
    969 
    970 ; CHECK-CVT-LABEL: test_copysign:
    971 ; CHECK-CVT-NEXT: fcvt s1, h1
    972 ; CHECK-CVT-NEXT: fcvt s0, h0
    973 ; CHECK-CVT-NEXT: movi.4s v2, #128, lsl #24
    974 ; CHECK-CVT-NEXT: bit.16b v0, v1, v2
    975 ; CHECK-CVT-NEXT: fcvt h0, s0
    976 ; CHECK-CVT-NEXT: ret
    977 
    978 ; CHECK-FP16-LABEL: test_copysign:
    979 ; CHECK-FP16-NEXT: movi.8h v2, #128, lsl #8
    980 ; CHECK-FP16-NEXT: bit.16b  v0, v1, v2
    981 ; CHECK-FP16-NEXT: ret
    982 
    983 define half @test_copysign(half %a, half %b) #0 {
    984   %r = call half @llvm.copysign.f16(half %a, half %b)
    985   ret half %r
    986 }
    987 
    988 ; CHECK-CVT-LABEL: test_copysign_f32:
    989 ; CHECK-CVT-NEXT: fcvt s0, h0
    990 ; CHECK-CVT-NEXT: movi.4s v2, #128, lsl #24
    991 ; CHECK-CVT-NEXT: bit.16b v0, v1, v2
    992 ; CHECK-CVT-NEXT: fcvt h0, s0
    993 ; CHECK-CVT-NEXT: ret
    994 
    995 ; CHECK-FP16-LABEL: test_copysign_f32:
    996 ; CHECK-FP16-NEXT: fcvt h1, s1
    997 ; CHECK-FP16-NEXT: movi.8h	v2, #128, lsl #8
    998 ; CHECK-FP16-NEXT: bit.16b v0, v1, v2
    999 ; CHECK-FP16-NEXT: ret
   1000 
   1001 define half @test_copysign_f32(half %a, float %b) #0 {
   1002   %tb = fptrunc float %b to half
   1003   %r = call half @llvm.copysign.f16(half %a, half %tb)
   1004   ret half %r
   1005 }
   1006 
   1007 ; CHECK-CVT-LABEL: test_copysign_f64:
   1008 ; CHECK-CVT-NEXT: fcvt s1, d1
   1009 ; CHECK-CVT-NEXT: fcvt s0, h0
   1010 ; CHECK-CVT-NEXT: movi.4s v2, #128, lsl #24
   1011 ; CHECK-CVT-NEXT: bit.16b v0, v1, v2
   1012 ; CHECK-CVT-NEXT: fcvt h0, s0
   1013 ; CHECK-CVT-NEXT: ret
   1014 
   1015 ; CHECK-FP16-LABEL: test_copysign_f64:
   1016 ; CHECK-FP16-NEXT: fcvt h1, d1
   1017 ; CHECK-FP16-NEXT: movi.8h v2, #128, lsl #8
   1018 ; CHECK-FP16-NEXT: bit.16b v0, v1, v2
   1019 ; CHECK-FP16-NEXT: ret
   1020 
   1021 define half @test_copysign_f64(half %a, double %b) #0 {
   1022   %tb = fptrunc double %b to half
   1023   %r = call half @llvm.copysign.f16(half %a, half %tb)
   1024   ret half %r
   1025 }
   1026 
   1027 ; Check that the FP promotion will use a truncating FP_ROUND, so we can fold
   1028 ; away the (fpext (fp_round <result>)) here.
   1029 
   1030 ; CHECK-CVT-LABEL: test_copysign_extended:
   1031 ; CHECK-CVT-NEXT: fcvt s1, h1
   1032 ; CHECK-CVT-NEXT: fcvt s0, h0
   1033 ; CHECK-CVT-NEXT: movi.4s v2, #128, lsl #24
   1034 ; CHECK-CVT-NEXT: bit.16b v0, v1, v2
   1035 ; CHECK-CVT-NEXT: ret
   1036 
   1037 ; CHECK-FP16-LABEL: test_copysign_extended:
   1038 ; CHECK-FP16-NEXT: movi.8h v2, #128, lsl #8
   1039 ; CHECK-FP16-NEXT: bit.16b v0, v1, v2
   1040 ; CHECK-FP16-NEXT: fcvt s0, h0
   1041 ; CHECK-FP16-NEXT: ret
   1042 
   1043 define float @test_copysign_extended(half %a, half %b) #0 {
   1044   %r = call half @llvm.copysign.f16(half %a, half %b)
   1045   %xr = fpext half %r to float
   1046   ret float %xr
   1047 }
   1048 
   1049 ; CHECK-CVT-LABEL: test_floor:
   1050 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
   1051 ; CHECK-CVT-NEXT: frintm [[INT32:s[0-9]+]], [[FLOAT32]]
   1052 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
   1053 ; CHECK-CVT-NEXT: ret
   1054 
   1055 ; CHECK-FP16-LABEL: test_floor:
   1056 ; CHECK-FP16-NEXT: frintm h0, h0
   1057 ; CHECK-FP16-NEXT: ret
   1058 
   1059 define half @test_floor(half %a) #0 {
   1060   %r = call half @llvm.floor.f16(half %a)
   1061   ret half %r
   1062 }
   1063 
   1064 ; CHECK-CVT-LABEL: test_ceil:
   1065 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
   1066 ; CHECK-CVT-NEXT: frintp [[INT32:s[0-9]+]], [[FLOAT32]]
   1067 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
   1068 ; CHECK-CVT-NEXT: ret
   1069 
   1070 ; CHECK-FP16-LABEL: test_ceil:
   1071 ; CHECK-FP16-NEXT: frintp h0, h0
   1072 ; CHECK-FP16-NEXT: ret
   1073 
   1074 define half @test_ceil(half %a) #0 {
   1075   %r = call half @llvm.ceil.f16(half %a)
   1076   ret half %r
   1077 }
   1078 
   1079 ; CHECK-CVT-LABEL: test_trunc:
   1080 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
   1081 ; CHECK-CVT-NEXT: frintz [[INT32:s[0-9]+]], [[FLOAT32]]
   1082 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
   1083 ; CHECK-CVT-NEXT: ret
   1084 
   1085 ; CHECK-FP16-LABEL: test_trunc:
   1086 ; CHECK-FP16-NEXT: frintz h0, h0
   1087 ; CHECK-FP16-NEXT: ret
   1088 
   1089 define half @test_trunc(half %a) #0 {
   1090   %r = call half @llvm.trunc.f16(half %a)
   1091   ret half %r
   1092 }
   1093 
   1094 ; CHECK-CVT-LABEL: test_rint:
   1095 ; CHECK-CVT-NEXT: fcvt s0, h0
   1096 ; CHECK-CVT-NEXT: frintx s0, s0
   1097 ; CHECK-CVT-NEXT: fcvt h0, s0
   1098 ; CHECK-CVT-NEXT: ret
   1099 
   1100 ; CHECK-FP16-LABEL: test_rint:
   1101 ; CHECK-FP16-NEXT: frintx h0, h0
   1102 ; CHECK-FP16-NEXT: ret
   1103 
   1104 define half @test_rint(half %a) #0 {
   1105   %r = call half @llvm.rint.f16(half %a)
   1106   ret half %r
   1107 }
   1108 
   1109 ; CHECK-CVT-LABEL: test_nearbyint:
   1110 ; CHECK-CVT-NEXT: fcvt s0, h0
   1111 ; CHECK-CVT-NEXT: frinti s0, s0
   1112 ; CHECK-CVT-NEXT: fcvt h0, s0
   1113 ; CHECK-CVT-NEXT: ret
   1114 
   1115 ; CHECK-FP16-LABEL: test_nearbyint:
   1116 ; CHECK-FP16-NEXT: frinti h0, h0
   1117 ; CHECK-FP16-NEXT: ret
   1118 
   1119 define half @test_nearbyint(half %a) #0 {
   1120   %r = call half @llvm.nearbyint.f16(half %a)
   1121   ret half %r
   1122 }
   1123 
   1124 ; CHECK-CVT-LABEL: test_round:
   1125 ; CHECK-CVT-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0
   1126 ; CHECK-CVT-NEXT: frinta [[INT32:s[0-9]+]], [[FLOAT32]]
   1127 ; CHECK-CVT-NEXT: fcvt h0, [[INT32]]
   1128 ; CHECK-CVT-NEXT: ret
   1129 
   1130 ; CHECK-FP16-LABEL: test_round:
   1131 ; CHECK-FP16-NEXT: frinta h0, h0
   1132 ; CHECK-FP16-NEXT: ret
   1133 
   1134 define half @test_round(half %a) #0 {
   1135   %r = call half @llvm.round.f16(half %a)
   1136   ret half %r
   1137 }
   1138 
   1139 ; CHECK-CVT-LABEL: test_fmuladd:
   1140 ; CHECK-CVT-NEXT: fcvt s1, h1
   1141 ; CHECK-CVT-NEXT: fcvt s0, h0
   1142 ; CHECK-CVT-NEXT: fmul s0, s0, s1
   1143 ; CHECK-CVT-NEXT: fcvt h0, s0
   1144 ; CHECK-CVT-NEXT: fcvt s0, h0
   1145 ; CHECK-CVT-NEXT: fcvt s1, h2
   1146 ; CHECK-CVT-NEXT: fadd s0, s0, s1
   1147 ; CHECK-CVT-NEXT: fcvt h0, s0
   1148 ; CHECK-CVT-NEXT: ret
   1149 
   1150 ; CHECK-FP16-LABEL: test_fmuladd:
   1151 ; CHECK-FP16-NEXT: fmul h0, h0, h1
   1152 ; CHECK-FP16-NEXT: fadd h0, h0, h2
   1153 ; CHECK-FP16-NEXT: ret
   1154 
   1155 define half @test_fmuladd(half %a, half %b, half %c) #0 {
   1156   %r = call half @llvm.fmuladd.f16(half %a, half %b, half %c)
   1157   ret half %r
   1158 }
   1159 
   1160 ; CHECK-FP16-LABEL: test_vrecpeh_f16:
   1161 ; CHECK-FP16-NEXT: frecpe h0, h0
   1162 ; CHECK-FP16-NEXT: ret
   1163 
   1164 define half @test_vrecpeh_f16(half %a) #0 {
   1165   %r = call half @llvm.aarch64.neon.frecpe.f16(half %a)
   1166   ret half %r
   1167 }
   1168 
   1169 ; CHECK-FP16-LABEL: test_vrecpxh_f16:
   1170 ; CHECK-FP16-NEXT: frecpx h0, h0
   1171 ; CHECK-FP16-NEXT: ret
   1172 
   1173 define half @test_vrecpxh_f16(half %a) #0 {
   1174   %r = call half @llvm.aarch64.neon.frecpx.f16(half %a)
   1175   ret half %r
   1176 }
   1177 
   1178 ; CHECK-FP16-LABEL: test_vrsqrteh_f16:
   1179 ; CHECK-FP16-NEXT: frsqrte h0, h0
   1180 ; CHECK-FP16-NEXT: ret
   1181 
   1182 define half @test_vrsqrteh_f16(half %a) #0 {
   1183   %r = call half @llvm.aarch64.neon.frsqrte.f16(half %a)
   1184   ret half %r
   1185 }
   1186 
   1187 attributes #0 = { nounwind }
   1188