1; RUN: llc < %s -mtriple aarch64-unknown-unknown -aarch64-neon-syntax=apple -asm-verbose=false -disable-post-ra | FileCheck %s 2 3target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 4 5; CHECK-LABEL: test_fadd: 6; CHECK-NEXT: fcvt s1, h1 7; CHECK-NEXT: fcvt s0, h0 8; CHECK-NEXT: fadd s0, s0, s1 9; CHECK-NEXT: fcvt h0, s0 10; CHECK-NEXT: ret 11define half @test_fadd(half %a, half %b) #0 { 12 %r = fadd half %a, %b 13 ret half %r 14} 15 16; CHECK-LABEL: test_fsub: 17; CHECK-NEXT: fcvt s1, h1 18; CHECK-NEXT: fcvt s0, h0 19; CHECK-NEXT: fsub s0, s0, s1 20; CHECK-NEXT: fcvt h0, s0 21; CHECK-NEXT: ret 22define half @test_fsub(half %a, half %b) #0 { 23 %r = fsub half %a, %b 24 ret half %r 25} 26 27; CHECK-LABEL: test_fmul: 28; CHECK-NEXT: fcvt s1, h1 29; CHECK-NEXT: fcvt s0, h0 30; CHECK-NEXT: fmul s0, s0, s1 31; CHECK-NEXT: fcvt h0, s0 32; CHECK-NEXT: ret 33define half @test_fmul(half %a, half %b) #0 { 34 %r = fmul half %a, %b 35 ret half %r 36} 37 38; CHECK-LABEL: test_fdiv: 39; CHECK-NEXT: fcvt s1, h1 40; CHECK-NEXT: fcvt s0, h0 41; CHECK-NEXT: fdiv s0, s0, s1 42; CHECK-NEXT: fcvt h0, s0 43; CHECK-NEXT: ret 44define half @test_fdiv(half %a, half %b) #0 { 45 %r = fdiv half %a, %b 46 ret half %r 47} 48 49; CHECK-LABEL: test_frem: 50; CHECK-NEXT: stp x29, x30, [sp, #-16]! 51; CHECK-NEXT: mov x29, sp 52; CHECK-NEXT: fcvt s0, h0 53; CHECK-NEXT: fcvt s1, h1 54; CHECK-NEXT: bl {{_?}}fmodf 55; CHECK-NEXT: fcvt h0, s0 56; CHECK-NEXT: ldp x29, x30, [sp], #16 57; CHECK-NEXT: ret 58define half @test_frem(half %a, half %b) #0 { 59 %r = frem half %a, %b 60 ret half %r 61} 62 63; CHECK-LABEL: test_store: 64; CHECK-NEXT: str h0, [x0] 65; CHECK-NEXT: ret 66define void @test_store(half %a, half* %b) #0 { 67 store half %a, half* %b 68 ret void 69} 70 71; CHECK-LABEL: test_load: 72; CHECK-NEXT: ldr h0, [x0] 73; CHECK-NEXT: ret 74define half @test_load(half* %a) #0 { 75 %r = load half, half* %a 76 ret half %r 77} 78 79 80declare half @test_callee(half %a, half %b) #0 81 82; CHECK-LABEL: test_call: 83; CHECK-NEXT: stp x29, x30, [sp, #-16]! 84; CHECK-NEXT: mov x29, sp 85; CHECK-NEXT: bl {{_?}}test_callee 86; CHECK-NEXT: ldp x29, x30, [sp], #16 87; CHECK-NEXT: ret 88define half @test_call(half %a, half %b) #0 { 89 %r = call half @test_callee(half %a, half %b) 90 ret half %r 91} 92 93; CHECK-LABEL: test_call_flipped: 94; CHECK-NEXT: stp x29, x30, [sp, #-16]! 95; CHECK-NEXT: mov x29, sp 96; CHECK-NEXT: mov.16b v2, v0 97; CHECK-NEXT: mov.16b v0, v1 98; CHECK-NEXT: mov.16b v1, v2 99; CHECK-NEXT: bl {{_?}}test_callee 100; CHECK-NEXT: ldp x29, x30, [sp], #16 101; CHECK-NEXT: ret 102define half @test_call_flipped(half %a, half %b) #0 { 103 %r = call half @test_callee(half %b, half %a) 104 ret half %r 105} 106 107; CHECK-LABEL: test_tailcall_flipped: 108; CHECK-NEXT: mov.16b v2, v0 109; CHECK-NEXT: mov.16b v0, v1 110; CHECK-NEXT: mov.16b v1, v2 111; CHECK-NEXT: b {{_?}}test_callee 112define half @test_tailcall_flipped(half %a, half %b) #0 { 113 %r = tail call half @test_callee(half %b, half %a) 114 ret half %r 115} 116 117; CHECK-LABEL: test_select: 118; CHECK-NEXT: fcvt s1, h1 119; CHECK-NEXT: fcvt s0, h0 120; CHECK-NEXT: cmp w0, #0 121; CHECK-NEXT: fcsel s0, s0, s1, ne 122; CHECK-NEXT: fcvt h0, s0 123; CHECK-NEXT: ret 124define half @test_select(half %a, half %b, i1 zeroext %c) #0 { 125 %r = select i1 %c, half %a, half %b 126 ret half %r 127} 128 129; CHECK-LABEL: test_select_cc: 130; CHECK-DAG: fcvt s3, h3 131; CHECK-DAG: fcvt s2, h2 132; CHECK-DAG: fcvt s1, h1 133; CHECK-DAG: fcvt s0, h0 134; CHECK-DAG: fcmp s2, s3 135; CHECK-DAG: cset [[CC:w[0-9]+]], ne 136; CHECK-DAG: cmp [[CC]], #0 137; CHECK-NEXT: fcsel s0, s0, s1, ne 138; CHECK-NEXT: fcvt h0, s0 139; CHECK-NEXT: ret 140define half @test_select_cc(half %a, half %b, half %c, half %d) #0 { 141 %cc = fcmp une half %c, %d 142 %r = select i1 %cc, half %a, half %b 143 ret half %r 144} 145 146; CHECK-LABEL: test_select_cc_f32_f16: 147; CHECK-DAG: fcvt s2, h2 148; CHECK-DAG: fcvt s3, h3 149; CHECK-NEXT: fcmp s2, s3 150; CHECK-NEXT: fcsel s0, s0, s1, ne 151; CHECK-NEXT: ret 152define float @test_select_cc_f32_f16(float %a, float %b, half %c, half %d) #0 { 153 %cc = fcmp une half %c, %d 154 %r = select i1 %cc, float %a, float %b 155 ret float %r 156} 157 158; CHECK-LABEL: test_select_cc_f16_f32: 159; CHECK-DAG: fcvt s0, h0 160; CHECK-DAG: fcvt s1, h1 161; CHECK-DAG: fcmp s2, s3 162; CHECK-DAG: cset w8, ne 163; CHECK-NEXT: cmp w8, #0 164; CHECK-NEXT: fcsel s0, s0, s1, ne 165; CHECK-NEXT: fcvt h0, s0 166; CHECK-NEXT: ret 167define half @test_select_cc_f16_f32(half %a, half %b, float %c, float %d) #0 { 168 %cc = fcmp une float %c, %d 169 %r = select i1 %cc, half %a, half %b 170 ret half %r 171} 172 173; CHECK-LABEL: test_fcmp_une: 174; CHECK-NEXT: fcvt s1, h1 175; CHECK-NEXT: fcvt s0, h0 176; CHECK-NEXT: fcmp s0, s1 177; CHECK-NEXT: cset w0, ne 178; CHECK-NEXT: ret 179define i1 @test_fcmp_une(half %a, half %b) #0 { 180 %r = fcmp une half %a, %b 181 ret i1 %r 182} 183 184; CHECK-LABEL: test_fcmp_ueq: 185; CHECK-NEXT: fcvt s1, h1 186; CHECK-NEXT: fcvt s0, h0 187; CHECK-NEXT: fcmp s0, s1 188; CHECK-NEXT: orr [[TRUE:w[0-9]+]], wzr, #0x1 189; CHECK-NEXT: csel [[CC:w[0-9]+]], [[TRUE]], wzr, eq 190; CHECK-NEXT: csel w0, [[TRUE]], [[CC]], vs 191; CHECK-NEXT: ret 192define i1 @test_fcmp_ueq(half %a, half %b) #0 { 193 %r = fcmp ueq half %a, %b 194 ret i1 %r 195} 196 197; CHECK-LABEL: test_fcmp_ugt: 198; CHECK-NEXT: fcvt s1, h1 199; CHECK-NEXT: fcvt s0, h0 200; CHECK-NEXT: fcmp s0, s1 201; CHECK-NEXT: cset w0, hi 202; CHECK-NEXT: ret 203define i1 @test_fcmp_ugt(half %a, half %b) #0 { 204 %r = fcmp ugt half %a, %b 205 ret i1 %r 206} 207 208; CHECK-LABEL: test_fcmp_uge: 209; CHECK-NEXT: fcvt s1, h1 210; CHECK-NEXT: fcvt s0, h0 211; CHECK-NEXT: fcmp s0, s1 212; CHECK-NEXT: cset w0, pl 213; CHECK-NEXT: ret 214define i1 @test_fcmp_uge(half %a, half %b) #0 { 215 %r = fcmp uge half %a, %b 216 ret i1 %r 217} 218 219; CHECK-LABEL: test_fcmp_ult: 220; CHECK-NEXT: fcvt s1, h1 221; CHECK-NEXT: fcvt s0, h0 222; CHECK-NEXT: fcmp s0, s1 223; CHECK-NEXT: cset w0, lt 224; CHECK-NEXT: ret 225define i1 @test_fcmp_ult(half %a, half %b) #0 { 226 %r = fcmp ult half %a, %b 227 ret i1 %r 228} 229 230; CHECK-LABEL: test_fcmp_ule: 231; CHECK-NEXT: fcvt s1, h1 232; CHECK-NEXT: fcvt s0, h0 233; CHECK-NEXT: fcmp s0, s1 234; CHECK-NEXT: cset w0, le 235; CHECK-NEXT: ret 236define i1 @test_fcmp_ule(half %a, half %b) #0 { 237 %r = fcmp ule half %a, %b 238 ret i1 %r 239} 240 241 242; CHECK-LABEL: test_fcmp_uno: 243; CHECK-NEXT: fcvt s1, h1 244; CHECK-NEXT: fcvt s0, h0 245; CHECK-NEXT: fcmp s0, s1 246; CHECK-NEXT: cset w0, vs 247; CHECK-NEXT: ret 248define i1 @test_fcmp_uno(half %a, half %b) #0 { 249 %r = fcmp uno half %a, %b 250 ret i1 %r 251} 252 253; CHECK-LABEL: test_fcmp_one: 254; CHECK-NEXT: fcvt s1, h1 255; CHECK-NEXT: fcvt s0, h0 256; CHECK-NEXT: fcmp s0, s1 257; CHECK-NEXT: orr [[TRUE:w[0-9]+]], wzr, #0x1 258; CHECK-NEXT: csel [[CC:w[0-9]+]], [[TRUE]], wzr, mi 259; CHECK-NEXT: csel w0, [[TRUE]], [[CC]], gt 260; CHECK-NEXT: ret 261define i1 @test_fcmp_one(half %a, half %b) #0 { 262 %r = fcmp one half %a, %b 263 ret i1 %r 264} 265 266; CHECK-LABEL: test_fcmp_oeq: 267; CHECK-NEXT: fcvt s1, h1 268; CHECK-NEXT: fcvt s0, h0 269; CHECK-NEXT: fcmp s0, s1 270; CHECK-NEXT: cset w0, eq 271; CHECK-NEXT: ret 272define i1 @test_fcmp_oeq(half %a, half %b) #0 { 273 %r = fcmp oeq half %a, %b 274 ret i1 %r 275} 276 277; CHECK-LABEL: test_fcmp_ogt: 278; CHECK-NEXT: fcvt s1, h1 279; CHECK-NEXT: fcvt s0, h0 280; CHECK-NEXT: fcmp s0, s1 281; CHECK-NEXT: cset w0, gt 282; CHECK-NEXT: ret 283define i1 @test_fcmp_ogt(half %a, half %b) #0 { 284 %r = fcmp ogt half %a, %b 285 ret i1 %r 286} 287 288; CHECK-LABEL: test_fcmp_oge: 289; CHECK-NEXT: fcvt s1, h1 290; CHECK-NEXT: fcvt s0, h0 291; CHECK-NEXT: fcmp s0, s1 292; CHECK-NEXT: cset w0, ge 293; CHECK-NEXT: ret 294define i1 @test_fcmp_oge(half %a, half %b) #0 { 295 %r = fcmp oge half %a, %b 296 ret i1 %r 297} 298 299; CHECK-LABEL: test_fcmp_olt: 300; CHECK-NEXT: fcvt s1, h1 301; CHECK-NEXT: fcvt s0, h0 302; CHECK-NEXT: fcmp s0, s1 303; CHECK-NEXT: cset w0, mi 304; CHECK-NEXT: ret 305define i1 @test_fcmp_olt(half %a, half %b) #0 { 306 %r = fcmp olt half %a, %b 307 ret i1 %r 308} 309 310; CHECK-LABEL: test_fcmp_ole: 311; CHECK-NEXT: fcvt s1, h1 312; CHECK-NEXT: fcvt s0, h0 313; CHECK-NEXT: fcmp s0, s1 314; CHECK-NEXT: cset w0, ls 315; CHECK-NEXT: ret 316define i1 @test_fcmp_ole(half %a, half %b) #0 { 317 %r = fcmp ole half %a, %b 318 ret i1 %r 319} 320 321; CHECK-LABEL: test_fcmp_ord: 322; CHECK-NEXT: fcvt s1, h1 323; CHECK-NEXT: fcvt s0, h0 324; CHECK-NEXT: fcmp s0, s1 325; CHECK-NEXT: cset w0, vc 326; CHECK-NEXT: ret 327define i1 @test_fcmp_ord(half %a, half %b) #0 { 328 %r = fcmp ord half %a, %b 329 ret i1 %r 330} 331 332; CHECK-LABEL: test_br_cc: 333; CHECK-NEXT: fcvt s1, h1 334; CHECK-NEXT: fcvt s0, h0 335; CHECK-NEXT: fcmp s0, s1 336; CHECK-NEXT: b.mi [[BRCC_ELSE:.?LBB[0-9_]+]] 337; CHECK-NEXT: str wzr, [x0] 338; CHECK-NEXT: ret 339; CHECK-NEXT: [[BRCC_ELSE]]: 340; CHECK-NEXT: str wzr, [x1] 341; CHECK-NEXT: ret 342define void @test_br_cc(half %a, half %b, i32* %p1, i32* %p2) #0 { 343 %c = fcmp uge half %a, %b 344 br i1 %c, label %then, label %else 345then: 346 store i32 0, i32* %p1 347 ret void 348else: 349 store i32 0, i32* %p2 350 ret void 351} 352 353; CHECK-LABEL: test_phi: 354; CHECK: mov x[[PTR:[0-9]+]], x0 355; CHECK: ldr h[[AB:[0-9]+]], [x[[PTR]]] 356; CHECK: [[LOOP:LBB[0-9_]+]]: 357; CHECK: mov.16b v[[R:[0-9]+]], v[[AB]] 358; CHECK: ldr h[[AB]], [x[[PTR]]] 359; CHECK: mov x0, x[[PTR]] 360; CHECK: bl {{_?}}test_dummy 361; CHECK: mov.16b v0, v[[R]] 362; CHECK: ret 363define half @test_phi(half* %p1) #0 { 364entry: 365 %a = load half, half* %p1 366 br label %loop 367loop: 368 %r = phi half [%a, %entry], [%b, %loop] 369 %b = load half, half* %p1 370 %c = call i1 @test_dummy(half* %p1) 371 br i1 %c, label %loop, label %return 372return: 373 ret half %r 374} 375declare i1 @test_dummy(half* %p1) #0 376 377; CHECK-LABEL: test_fptosi_i32: 378; CHECK-NEXT: fcvt s0, h0 379; CHECK-NEXT: fcvtzs w0, s0 380; CHECK-NEXT: ret 381define i32 @test_fptosi_i32(half %a) #0 { 382 %r = fptosi half %a to i32 383 ret i32 %r 384} 385 386; CHECK-LABEL: test_fptosi_i64: 387; CHECK-NEXT: fcvt s0, h0 388; CHECK-NEXT: fcvtzs x0, s0 389; CHECK-NEXT: ret 390define i64 @test_fptosi_i64(half %a) #0 { 391 %r = fptosi half %a to i64 392 ret i64 %r 393} 394 395; CHECK-LABEL: test_fptoui_i32: 396; CHECK-NEXT: fcvt s0, h0 397; CHECK-NEXT: fcvtzu w0, s0 398; CHECK-NEXT: ret 399define i32 @test_fptoui_i32(half %a) #0 { 400 %r = fptoui half %a to i32 401 ret i32 %r 402} 403 404; CHECK-LABEL: test_fptoui_i64: 405; CHECK-NEXT: fcvt s0, h0 406; CHECK-NEXT: fcvtzu x0, s0 407; CHECK-NEXT: ret 408define i64 @test_fptoui_i64(half %a) #0 { 409 %r = fptoui half %a to i64 410 ret i64 %r 411} 412 413; CHECK-LABEL: test_uitofp_i32: 414; CHECK-NEXT: ucvtf s0, w0 415; CHECK-NEXT: fcvt h0, s0 416; CHECK-NEXT: ret 417define half @test_uitofp_i32(i32 %a) #0 { 418 %r = uitofp i32 %a to half 419 ret half %r 420} 421 422; CHECK-LABEL: test_uitofp_i64: 423; CHECK-NEXT: ucvtf s0, x0 424; CHECK-NEXT: fcvt h0, s0 425; CHECK-NEXT: ret 426define half @test_uitofp_i64(i64 %a) #0 { 427 %r = uitofp i64 %a to half 428 ret half %r 429} 430 431; CHECK-LABEL: test_sitofp_i32: 432; CHECK-NEXT: scvtf s0, w0 433; CHECK-NEXT: fcvt h0, s0 434; CHECK-NEXT: ret 435define half @test_sitofp_i32(i32 %a) #0 { 436 %r = sitofp i32 %a to half 437 ret half %r 438} 439 440; CHECK-LABEL: test_sitofp_i64: 441; CHECK-NEXT: scvtf s0, x0 442; CHECK-NEXT: fcvt h0, s0 443; CHECK-NEXT: ret 444define half @test_sitofp_i64(i64 %a) #0 { 445 %r = sitofp i64 %a to half 446 ret half %r 447} 448 449; CHECK-LABEL: test_fptrunc_float: 450; CHECK-NEXT: fcvt h0, s0 451; CHECK-NEXT: ret 452 453define half @test_fptrunc_float(float %a) #0 { 454 %r = fptrunc float %a to half 455 ret half %r 456} 457 458; CHECK-LABEL: test_fptrunc_double: 459; CHECK-NEXT: fcvt h0, d0 460; CHECK-NEXT: ret 461define half @test_fptrunc_double(double %a) #0 { 462 %r = fptrunc double %a to half 463 ret half %r 464} 465 466; CHECK-LABEL: test_fpext_float: 467; CHECK-NEXT: fcvt s0, h0 468; CHECK-NEXT: ret 469define float @test_fpext_float(half %a) #0 { 470 %r = fpext half %a to float 471 ret float %r 472} 473 474; CHECK-LABEL: test_fpext_double: 475; CHECK-NEXT: fcvt d0, h0 476; CHECK-NEXT: ret 477define double @test_fpext_double(half %a) #0 { 478 %r = fpext half %a to double 479 ret double %r 480} 481 482 483; CHECK-LABEL: test_bitcast_halftoi16: 484; CHECK-NEXT: fmov w0, s0 485; CHECK-NEXT: ret 486define i16 @test_bitcast_halftoi16(half %a) #0 { 487 %r = bitcast half %a to i16 488 ret i16 %r 489} 490 491; CHECK-LABEL: test_bitcast_i16tohalf: 492; CHECK-NEXT: fmov s0, w0 493; CHECK-NEXT: ret 494define half @test_bitcast_i16tohalf(i16 %a) #0 { 495 %r = bitcast i16 %a to half 496 ret half %r 497} 498 499 500declare half @llvm.sqrt.f16(half %a) #0 501declare half @llvm.powi.f16(half %a, i32 %b) #0 502declare half @llvm.sin.f16(half %a) #0 503declare half @llvm.cos.f16(half %a) #0 504declare half @llvm.pow.f16(half %a, half %b) #0 505declare half @llvm.exp.f16(half %a) #0 506declare half @llvm.exp2.f16(half %a) #0 507declare half @llvm.log.f16(half %a) #0 508declare half @llvm.log10.f16(half %a) #0 509declare half @llvm.log2.f16(half %a) #0 510declare half @llvm.fma.f16(half %a, half %b, half %c) #0 511declare half @llvm.fabs.f16(half %a) #0 512declare half @llvm.minnum.f16(half %a, half %b) #0 513declare half @llvm.maxnum.f16(half %a, half %b) #0 514declare half @llvm.copysign.f16(half %a, half %b) #0 515declare half @llvm.floor.f16(half %a) #0 516declare half @llvm.ceil.f16(half %a) #0 517declare half @llvm.trunc.f16(half %a) #0 518declare half @llvm.rint.f16(half %a) #0 519declare half @llvm.nearbyint.f16(half %a) #0 520declare half @llvm.round.f16(half %a) #0 521declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0 522 523; CHECK-LABEL: test_sqrt: 524; CHECK-NEXT: fcvt s0, h0 525; CHECK-NEXT: fsqrt s0, s0 526; CHECK-NEXT: fcvt h0, s0 527; CHECK-NEXT: ret 528define half @test_sqrt(half %a) #0 { 529 %r = call half @llvm.sqrt.f16(half %a) 530 ret half %r 531} 532 533; CHECK-LABEL: test_powi: 534; CHECK-NEXT: stp x29, x30, [sp, #-16]! 535; CHECK-NEXT: mov x29, sp 536; CHECK-NEXT: fcvt s0, h0 537; CHECK-NEXT: bl {{_?}}__powisf2 538; CHECK-NEXT: fcvt h0, s0 539; CHECK-NEXT: ldp x29, x30, [sp], #16 540; CHECK-NEXT: ret 541define half @test_powi(half %a, i32 %b) #0 { 542 %r = call half @llvm.powi.f16(half %a, i32 %b) 543 ret half %r 544} 545 546; CHECK-LABEL: test_sin: 547; CHECK-NEXT: stp x29, x30, [sp, #-16]! 548; CHECK-NEXT: mov x29, sp 549; CHECK-NEXT: fcvt s0, h0 550; CHECK-NEXT: bl {{_?}}sinf 551; CHECK-NEXT: fcvt h0, s0 552; CHECK-NEXT: ldp x29, x30, [sp], #16 553; CHECK-NEXT: ret 554define half @test_sin(half %a) #0 { 555 %r = call half @llvm.sin.f16(half %a) 556 ret half %r 557} 558 559; CHECK-LABEL: test_cos: 560; CHECK-NEXT: stp x29, x30, [sp, #-16]! 561; CHECK-NEXT: mov x29, sp 562; CHECK-NEXT: fcvt s0, h0 563; CHECK-NEXT: bl {{_?}}cosf 564; CHECK-NEXT: fcvt h0, s0 565; CHECK-NEXT: ldp x29, x30, [sp], #16 566; CHECK-NEXT: ret 567define half @test_cos(half %a) #0 { 568 %r = call half @llvm.cos.f16(half %a) 569 ret half %r 570} 571 572; CHECK-LABEL: test_pow: 573; CHECK-NEXT: stp x29, x30, [sp, #-16]! 574; CHECK-NEXT: mov x29, sp 575; CHECK-NEXT: fcvt s0, h0 576; CHECK-NEXT: fcvt s1, h1 577; CHECK-NEXT: bl {{_?}}powf 578; CHECK-NEXT: fcvt h0, s0 579; CHECK-NEXT: ldp x29, x30, [sp], #16 580; CHECK-NEXT: ret 581define half @test_pow(half %a, half %b) #0 { 582 %r = call half @llvm.pow.f16(half %a, half %b) 583 ret half %r 584} 585 586; CHECK-LABEL: test_exp: 587; CHECK-NEXT: stp x29, x30, [sp, #-16]! 588; CHECK-NEXT: mov x29, sp 589; CHECK-NEXT: fcvt s0, h0 590; CHECK-NEXT: bl {{_?}}expf 591; CHECK-NEXT: fcvt h0, s0 592; CHECK-NEXT: ldp x29, x30, [sp], #16 593; CHECK-NEXT: ret 594define half @test_exp(half %a) #0 { 595 %r = call half @llvm.exp.f16(half %a) 596 ret half %r 597} 598 599; CHECK-LABEL: test_exp2: 600; CHECK-NEXT: stp x29, x30, [sp, #-16]! 601; CHECK-NEXT: mov x29, sp 602; CHECK-NEXT: fcvt s0, h0 603; CHECK-NEXT: bl {{_?}}exp2f 604; CHECK-NEXT: fcvt h0, s0 605; CHECK-NEXT: ldp x29, x30, [sp], #16 606; CHECK-NEXT: ret 607define half @test_exp2(half %a) #0 { 608 %r = call half @llvm.exp2.f16(half %a) 609 ret half %r 610} 611 612; CHECK-LABEL: test_log: 613; CHECK-NEXT: stp x29, x30, [sp, #-16]! 614; CHECK-NEXT: mov x29, sp 615; CHECK-NEXT: fcvt s0, h0 616; CHECK-NEXT: bl {{_?}}logf 617; CHECK-NEXT: fcvt h0, s0 618; CHECK-NEXT: ldp x29, x30, [sp], #16 619; CHECK-NEXT: ret 620define half @test_log(half %a) #0 { 621 %r = call half @llvm.log.f16(half %a) 622 ret half %r 623} 624 625; CHECK-LABEL: test_log10: 626; CHECK-NEXT: stp x29, x30, [sp, #-16]! 627; CHECK-NEXT: mov x29, sp 628; CHECK-NEXT: fcvt s0, h0 629; CHECK-NEXT: bl {{_?}}log10f 630; CHECK-NEXT: fcvt h0, s0 631; CHECK-NEXT: ldp x29, x30, [sp], #16 632; CHECK-NEXT: ret 633define half @test_log10(half %a) #0 { 634 %r = call half @llvm.log10.f16(half %a) 635 ret half %r 636} 637 638; CHECK-LABEL: test_log2: 639; CHECK-NEXT: stp x29, x30, [sp, #-16]! 640; CHECK-NEXT: mov x29, sp 641; CHECK-NEXT: fcvt s0, h0 642; CHECK-NEXT: bl {{_?}}log2f 643; CHECK-NEXT: fcvt h0, s0 644; CHECK-NEXT: ldp x29, x30, [sp], #16 645; CHECK-NEXT: ret 646define half @test_log2(half %a) #0 { 647 %r = call half @llvm.log2.f16(half %a) 648 ret half %r 649} 650 651; CHECK-LABEL: test_fma: 652; CHECK-NEXT: fcvt s2, h2 653; CHECK-NEXT: fcvt s1, h1 654; CHECK-NEXT: fcvt s0, h0 655; CHECK-NEXT: fmadd s0, s0, s1, s2 656; CHECK-NEXT: fcvt h0, s0 657; CHECK-NEXT: ret 658define half @test_fma(half %a, half %b, half %c) #0 { 659 %r = call half @llvm.fma.f16(half %a, half %b, half %c) 660 ret half %r 661} 662 663; CHECK-LABEL: test_fabs: 664; CHECK-NEXT: fcvt s0, h0 665; CHECK-NEXT: fabs s0, s0 666; CHECK-NEXT: fcvt h0, s0 667; CHECK-NEXT: ret 668define half @test_fabs(half %a) #0 { 669 %r = call half @llvm.fabs.f16(half %a) 670 ret half %r 671} 672 673; CHECK-LABEL: test_minnum: 674; CHECK-NEXT: fcvt s1, h1 675; CHECK-NEXT: fcvt s0, h0 676; CHECK-NEXT: fminnm s0, s0, s1 677; CHECK-NEXT: fcvt h0, s0 678; CHECK-NEXT: ret 679define half @test_minnum(half %a, half %b) #0 { 680 %r = call half @llvm.minnum.f16(half %a, half %b) 681 ret half %r 682} 683 684; CHECK-LABEL: test_maxnum: 685; CHECK-NEXT: fcvt s1, h1 686; CHECK-NEXT: fcvt s0, h0 687; CHECK-NEXT: fmaxnm s0, s0, s1 688; CHECK-NEXT: fcvt h0, s0 689; CHECK-NEXT: ret 690define half @test_maxnum(half %a, half %b) #0 { 691 %r = call half @llvm.maxnum.f16(half %a, half %b) 692 ret half %r 693} 694 695; CHECK-LABEL: test_copysign: 696; CHECK-NEXT: fcvt s1, h1 697; CHECK-NEXT: fcvt s0, h0 698; CHECK-NEXT: movi.4s v2, #0x80, lsl #24 699; CHECK-NEXT: bit.16b v0, v1, v2 700; CHECK-NEXT: fcvt h0, s0 701; CHECK-NEXT: ret 702define half @test_copysign(half %a, half %b) #0 { 703 %r = call half @llvm.copysign.f16(half %a, half %b) 704 ret half %r 705} 706 707; CHECK-LABEL: test_copysign_f32: 708; CHECK-NEXT: fcvt s0, h0 709; CHECK-NEXT: movi.4s v2, #0x80, lsl #24 710; CHECK-NEXT: bit.16b v0, v1, v2 711; CHECK-NEXT: fcvt h0, s0 712; CHECK-NEXT: ret 713define half @test_copysign_f32(half %a, float %b) #0 { 714 %tb = fptrunc float %b to half 715 %r = call half @llvm.copysign.f16(half %a, half %tb) 716 ret half %r 717} 718 719; CHECK-LABEL: test_copysign_f64: 720; CHECK-NEXT: fcvt s1, d1 721; CHECK-NEXT: fcvt s0, h0 722; CHECK-NEXT: movi.4s v2, #0x80, lsl #24 723; CHECK-NEXT: bit.16b v0, v1, v2 724; CHECK-NEXT: fcvt h0, s0 725; CHECK-NEXT: ret 726define half @test_copysign_f64(half %a, double %b) #0 { 727 %tb = fptrunc double %b to half 728 %r = call half @llvm.copysign.f16(half %a, half %tb) 729 ret half %r 730} 731 732; Check that the FP promotion will use a truncating FP_ROUND, so we can fold 733; away the (fpext (fp_round <result>)) here. 734 735; CHECK-LABEL: test_copysign_extended: 736; CHECK-NEXT: fcvt s1, h1 737; CHECK-NEXT: fcvt s0, h0 738; CHECK-NEXT: movi.4s v2, #0x80, lsl #24 739; CHECK-NEXT: bit.16b v0, v1, v2 740; CHECK-NEXT: ret 741define float @test_copysign_extended(half %a, half %b) #0 { 742 %r = call half @llvm.copysign.f16(half %a, half %b) 743 %xr = fpext half %r to float 744 ret float %xr 745} 746 747; CHECK-LABEL: test_floor: 748; CHECK-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0 749; CHECK-NEXT: frintm [[INT32:s[0-9]+]], [[FLOAT32]] 750; CHECK-NEXT: fcvt h0, [[INT32]] 751; CHECK-NEXT: ret 752define half @test_floor(half %a) #0 { 753 %r = call half @llvm.floor.f16(half %a) 754 ret half %r 755} 756 757; CHECK-LABEL: test_ceil: 758; CHECK-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0 759; CHECK-NEXT: frintp [[INT32:s[0-9]+]], [[FLOAT32]] 760; CHECK-NEXT: fcvt h0, [[INT32]] 761; CHECK-NEXT: ret 762define half @test_ceil(half %a) #0 { 763 %r = call half @llvm.ceil.f16(half %a) 764 ret half %r 765} 766 767; CHECK-LABEL: test_trunc: 768; CHECK-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0 769; CHECK-NEXT: frintz [[INT32:s[0-9]+]], [[FLOAT32]] 770; CHECK-NEXT: fcvt h0, [[INT32]] 771; CHECK-NEXT: ret 772define half @test_trunc(half %a) #0 { 773 %r = call half @llvm.trunc.f16(half %a) 774 ret half %r 775} 776 777; CHECK-LABEL: test_rint: 778; CHECK-NEXT: fcvt s0, h0 779; CHECK-NEXT: frintx s0, s0 780; CHECK-NEXT: fcvt h0, s0 781; CHECK-NEXT: ret 782define half @test_rint(half %a) #0 { 783 %r = call half @llvm.rint.f16(half %a) 784 ret half %r 785} 786 787; CHECK-LABEL: test_nearbyint: 788; CHECK-NEXT: fcvt s0, h0 789; CHECK-NEXT: frinti s0, s0 790; CHECK-NEXT: fcvt h0, s0 791; CHECK-NEXT: ret 792define half @test_nearbyint(half %a) #0 { 793 %r = call half @llvm.nearbyint.f16(half %a) 794 ret half %r 795} 796 797; CHECK-LABEL: test_round: 798; CHECK-NEXT: fcvt [[FLOAT32:s[0-9]+]], h0 799; CHECK-NEXT: frinta [[INT32:s[0-9]+]], [[FLOAT32]] 800; CHECK-NEXT: fcvt h0, [[INT32]] 801; CHECK-NEXT: ret 802define half @test_round(half %a) #0 { 803 %r = call half @llvm.round.f16(half %a) 804 ret half %r 805} 806 807; CHECK-LABEL: test_fmuladd: 808; CHECK-NEXT: fcvt s1, h1 809; CHECK-NEXT: fcvt s0, h0 810; CHECK-NEXT: fmul s0, s0, s1 811; CHECK-NEXT: fcvt h0, s0 812; CHECK-NEXT: fcvt s0, h0 813; CHECK-NEXT: fcvt s1, h2 814; CHECK-NEXT: fadd s0, s0, s1 815; CHECK-NEXT: fcvt h0, s0 816; CHECK-NEXT: ret 817define half @test_fmuladd(half %a, half %b, half %c) #0 { 818 %r = call half @llvm.fmuladd.f16(half %a, half %b, half %c) 819 ret half %r 820} 821 822attributes #0 = { nounwind } 823