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