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