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