1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 2; RUN: llc < %s -mtriple aarch64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,CHECK-CVT,CHECK-CVT-SD 3; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FP16,CHECK-FP16-SD 4; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-CVT,CHECK-CVT-GI 5; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-FP16,CHECK-FP16-GI 6 7define half @test_fadd(half %a, half %b) #0 { 8; CHECK-CVT-SD-LABEL: test_fadd: 9; CHECK-CVT-SD: // %bb.0: 10; CHECK-CVT-SD-NEXT: fcvt s1, h1 11; CHECK-CVT-SD-NEXT: fcvt s0, h0 12; CHECK-CVT-SD-NEXT: fadd s0, s0, s1 13; CHECK-CVT-SD-NEXT: fcvt h0, s0 14; CHECK-CVT-SD-NEXT: ret 15; 16; CHECK-FP16-LABEL: test_fadd: 17; CHECK-FP16: // %bb.0: 18; CHECK-FP16-NEXT: fadd h0, h0, h1 19; CHECK-FP16-NEXT: ret 20; 21; CHECK-CVT-GI-LABEL: test_fadd: 22; CHECK-CVT-GI: // %bb.0: 23; CHECK-CVT-GI-NEXT: fcvt s0, h0 24; CHECK-CVT-GI-NEXT: fcvt s1, h1 25; CHECK-CVT-GI-NEXT: fadd s0, s0, s1 26; CHECK-CVT-GI-NEXT: fcvt h0, s0 27; CHECK-CVT-GI-NEXT: ret 28 %r = fadd half %a, %b 29 ret half %r 30} 31 32define half @test_fsub(half %a, half %b) #0 { 33; CHECK-CVT-SD-LABEL: test_fsub: 34; CHECK-CVT-SD: // %bb.0: 35; CHECK-CVT-SD-NEXT: fcvt s1, h1 36; CHECK-CVT-SD-NEXT: fcvt s0, h0 37; CHECK-CVT-SD-NEXT: fsub s0, s0, s1 38; CHECK-CVT-SD-NEXT: fcvt h0, s0 39; CHECK-CVT-SD-NEXT: ret 40; 41; CHECK-FP16-LABEL: test_fsub: 42; CHECK-FP16: // %bb.0: 43; CHECK-FP16-NEXT: fsub h0, h0, h1 44; CHECK-FP16-NEXT: ret 45; 46; CHECK-CVT-GI-LABEL: test_fsub: 47; CHECK-CVT-GI: // %bb.0: 48; CHECK-CVT-GI-NEXT: fcvt s0, h0 49; CHECK-CVT-GI-NEXT: fcvt s1, h1 50; CHECK-CVT-GI-NEXT: fsub s0, s0, s1 51; CHECK-CVT-GI-NEXT: fcvt h0, s0 52; CHECK-CVT-GI-NEXT: ret 53 %r = fsub half %a, %b 54 ret half %r 55} 56 57define half @test_fmul(half %a, half %b) #0 { 58; CHECK-CVT-SD-LABEL: test_fmul: 59; CHECK-CVT-SD: // %bb.0: 60; CHECK-CVT-SD-NEXT: fcvt s1, h1 61; CHECK-CVT-SD-NEXT: fcvt s0, h0 62; CHECK-CVT-SD-NEXT: fmul s0, s0, s1 63; CHECK-CVT-SD-NEXT: fcvt h0, s0 64; CHECK-CVT-SD-NEXT: ret 65; 66; CHECK-FP16-LABEL: test_fmul: 67; CHECK-FP16: // %bb.0: 68; CHECK-FP16-NEXT: fmul h0, h0, h1 69; CHECK-FP16-NEXT: ret 70; 71; CHECK-CVT-GI-LABEL: test_fmul: 72; CHECK-CVT-GI: // %bb.0: 73; CHECK-CVT-GI-NEXT: fcvt s0, h0 74; CHECK-CVT-GI-NEXT: fcvt s1, h1 75; CHECK-CVT-GI-NEXT: fmul s0, s0, s1 76; CHECK-CVT-GI-NEXT: fcvt h0, s0 77; CHECK-CVT-GI-NEXT: ret 78 %r = fmul half %a, %b 79 ret half %r 80} 81 82define half @test_fmadd(half %a, half %b, half %c) #0 { 83; CHECK-CVT-SD-LABEL: test_fmadd: 84; CHECK-CVT-SD: // %bb.0: 85; CHECK-CVT-SD-NEXT: fcvt s1, h1 86; CHECK-CVT-SD-NEXT: fcvt s0, h0 87; CHECK-CVT-SD-NEXT: fmul s0, s0, s1 88; CHECK-CVT-SD-NEXT: fcvt s1, h2 89; CHECK-CVT-SD-NEXT: fcvt h0, s0 90; CHECK-CVT-SD-NEXT: fcvt s0, h0 91; CHECK-CVT-SD-NEXT: fadd s0, s0, s1 92; CHECK-CVT-SD-NEXT: fcvt h0, s0 93; CHECK-CVT-SD-NEXT: ret 94; 95; CHECK-FP16-LABEL: test_fmadd: 96; CHECK-FP16: // %bb.0: 97; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2 98; CHECK-FP16-NEXT: ret 99; 100; CHECK-CVT-GI-LABEL: test_fmadd: 101; CHECK-CVT-GI: // %bb.0: 102; CHECK-CVT-GI-NEXT: fcvt s0, h0 103; CHECK-CVT-GI-NEXT: fcvt s1, h1 104; CHECK-CVT-GI-NEXT: fmul s0, s0, s1 105; CHECK-CVT-GI-NEXT: fcvt s1, h2 106; CHECK-CVT-GI-NEXT: fcvt h0, s0 107; CHECK-CVT-GI-NEXT: fcvt s0, h0 108; CHECK-CVT-GI-NEXT: fadd s0, s0, s1 109; CHECK-CVT-GI-NEXT: fcvt h0, s0 110; CHECK-CVT-GI-NEXT: ret 111 %mul = fmul fast half %a, %b 112 %r = fadd fast half %mul, %c 113 ret half %r 114} 115 116define half @test_fdiv(half %a, half %b) #0 { 117; CHECK-CVT-SD-LABEL: test_fdiv: 118; CHECK-CVT-SD: // %bb.0: 119; CHECK-CVT-SD-NEXT: fcvt s1, h1 120; CHECK-CVT-SD-NEXT: fcvt s0, h0 121; CHECK-CVT-SD-NEXT: fdiv s0, s0, s1 122; CHECK-CVT-SD-NEXT: fcvt h0, s0 123; CHECK-CVT-SD-NEXT: ret 124; 125; CHECK-FP16-LABEL: test_fdiv: 126; CHECK-FP16: // %bb.0: 127; CHECK-FP16-NEXT: fdiv h0, h0, h1 128; CHECK-FP16-NEXT: ret 129; 130; CHECK-CVT-GI-LABEL: test_fdiv: 131; CHECK-CVT-GI: // %bb.0: 132; CHECK-CVT-GI-NEXT: fcvt s0, h0 133; CHECK-CVT-GI-NEXT: fcvt s1, h1 134; CHECK-CVT-GI-NEXT: fdiv s0, s0, s1 135; CHECK-CVT-GI-NEXT: fcvt h0, s0 136; CHECK-CVT-GI-NEXT: ret 137 %r = fdiv half %a, %b 138 ret half %r 139} 140 141define half @test_frem(half %a, half %b) #0 { 142; CHECK-LABEL: test_frem: 143; CHECK: // %bb.0: 144; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 145; CHECK-NEXT: fcvt s0, h0 146; CHECK-NEXT: fcvt s1, h1 147; CHECK-NEXT: bl fmodf 148; CHECK-NEXT: fcvt h0, s0 149; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 150; CHECK-NEXT: ret 151 %r = frem half %a, %b 152 ret half %r 153} 154 155define void @test_store(half %a, ptr %b) #0 { 156; CHECK-LABEL: test_store: 157; CHECK: // %bb.0: 158; CHECK-NEXT: str h0, [x0] 159; CHECK-NEXT: ret 160 store half %a, ptr %b 161 ret void 162} 163 164define half @test_load(ptr %a) #0 { 165; CHECK-LABEL: test_load: 166; CHECK: // %bb.0: 167; CHECK-NEXT: ldr h0, [x0] 168; CHECK-NEXT: ret 169 %r = load half, ptr %a 170 ret half %r 171} 172 173declare half @test_callee(half %a, half %b) #0 174 175define half @test_call(half %a, half %b) #0 { 176; CHECK-LABEL: test_call: 177; CHECK: // %bb.0: 178; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 179; CHECK-NEXT: bl test_callee 180; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 181; CHECK-NEXT: ret 182 %r = call half @test_callee(half %a, half %b) 183 ret half %r 184} 185 186define half @test_call_flipped(half %a, half %b) #0 { 187; CHECK-LABEL: test_call_flipped: 188; CHECK: // %bb.0: 189; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 190; CHECK-NEXT: fmov s2, s0 191; CHECK-NEXT: fmov s0, s1 192; CHECK-NEXT: fmov s1, s2 193; CHECK-NEXT: bl test_callee 194; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 195; CHECK-NEXT: ret 196 %r = call half @test_callee(half %b, half %a) 197 ret half %r 198} 199 200define half @test_tailcall_flipped(half %a, half %b) #0 { 201; CHECK-LABEL: test_tailcall_flipped: 202; CHECK: // %bb.0: 203; CHECK-NEXT: fmov s2, s0 204; CHECK-NEXT: fmov s0, s1 205; CHECK-NEXT: fmov s1, s2 206; CHECK-NEXT: b test_callee 207 %r = tail call half @test_callee(half %b, half %a) 208 ret half %r 209} 210 211define half @test_select(half %a, half %b, i1 zeroext %c) #0 { 212; CHECK-CVT-SD-LABEL: test_select: 213; CHECK-CVT-SD: // %bb.0: 214; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0 215; CHECK-CVT-SD-NEXT: cmp w0, #0 216; CHECK-CVT-SD-NEXT: // kill: def $h1 killed $h1 def $s1 217; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne 218; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 219; CHECK-CVT-SD-NEXT: ret 220; 221; CHECK-FP16-SD-LABEL: test_select: 222; CHECK-FP16-SD: // %bb.0: 223; CHECK-FP16-SD-NEXT: cmp w0, #0 224; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, ne 225; CHECK-FP16-SD-NEXT: ret 226; 227; CHECK-CVT-GI-LABEL: test_select: 228; CHECK-CVT-GI: // %bb.0: 229; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0 230; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $s1 231; CHECK-CVT-GI-NEXT: fmov w8, s0 232; CHECK-CVT-GI-NEXT: fmov w9, s1 233; CHECK-CVT-GI-NEXT: tst w0, #0x1 234; CHECK-CVT-GI-NEXT: csel w8, w8, w9, ne 235; CHECK-CVT-GI-NEXT: fmov s0, w8 236; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 237; CHECK-CVT-GI-NEXT: ret 238; 239; CHECK-FP16-GI-LABEL: test_select: 240; CHECK-FP16-GI: // %bb.0: 241; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0 242; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $s1 243; CHECK-FP16-GI-NEXT: fmov w8, s0 244; CHECK-FP16-GI-NEXT: fmov w9, s1 245; CHECK-FP16-GI-NEXT: tst w0, #0x1 246; CHECK-FP16-GI-NEXT: csel w8, w8, w9, ne 247; CHECK-FP16-GI-NEXT: fmov s0, w8 248; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 249; CHECK-FP16-GI-NEXT: ret 250 %r = select i1 %c, half %a, half %b 251 ret half %r 252} 253 254define half @test_select_cc(half %a, half %b, half %c, half %d) #0 { 255; CHECK-CVT-SD-LABEL: test_select_cc: 256; CHECK-CVT-SD: // %bb.0: 257; CHECK-CVT-SD-NEXT: fcvt s3, h3 258; CHECK-CVT-SD-NEXT: fcvt s2, h2 259; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0 260; CHECK-CVT-SD-NEXT: // kill: def $h1 killed $h1 def $s1 261; CHECK-CVT-SD-NEXT: fcmp s2, s3 262; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne 263; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 264; CHECK-CVT-SD-NEXT: ret 265; 266; CHECK-FP16-SD-LABEL: test_select_cc: 267; CHECK-FP16-SD: // %bb.0: 268; CHECK-FP16-SD-NEXT: fcmp h2, h3 269; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, ne 270; CHECK-FP16-SD-NEXT: ret 271; 272; CHECK-CVT-GI-LABEL: test_select_cc: 273; CHECK-CVT-GI: // %bb.0: 274; CHECK-CVT-GI-NEXT: fcvt s2, h2 275; CHECK-CVT-GI-NEXT: fcvt s3, h3 276; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0 277; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $s1 278; CHECK-CVT-GI-NEXT: fmov w8, s0 279; CHECK-CVT-GI-NEXT: fmov w9, s1 280; CHECK-CVT-GI-NEXT: fcmp s2, s3 281; CHECK-CVT-GI-NEXT: csel w8, w8, w9, ne 282; CHECK-CVT-GI-NEXT: fmov s0, w8 283; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 284; CHECK-CVT-GI-NEXT: ret 285; 286; CHECK-FP16-GI-LABEL: test_select_cc: 287; CHECK-FP16-GI: // %bb.0: 288; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0 289; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $s1 290; CHECK-FP16-GI-NEXT: fcmp h2, h3 291; CHECK-FP16-GI-NEXT: fmov w8, s0 292; CHECK-FP16-GI-NEXT: fmov w9, s1 293; CHECK-FP16-GI-NEXT: csel w8, w8, w9, ne 294; CHECK-FP16-GI-NEXT: fmov s0, w8 295; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 296; CHECK-FP16-GI-NEXT: ret 297 %cc = fcmp une half %c, %d 298 %r = select i1 %cc, half %a, half %b 299 ret half %r 300} 301 302define float @test_select_cc_f32_f16(float %a, float %b, half %c, half %d) #0 { 303; CHECK-CVT-SD-LABEL: test_select_cc_f32_f16: 304; CHECK-CVT-SD: // %bb.0: 305; CHECK-CVT-SD-NEXT: fcvt s3, h3 306; CHECK-CVT-SD-NEXT: fcvt s2, h2 307; CHECK-CVT-SD-NEXT: fcmp s2, s3 308; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne 309; CHECK-CVT-SD-NEXT: ret 310; 311; CHECK-FP16-LABEL: test_select_cc_f32_f16: 312; CHECK-FP16: // %bb.0: 313; CHECK-FP16-NEXT: fcmp h2, h3 314; CHECK-FP16-NEXT: fcsel s0, s0, s1, ne 315; CHECK-FP16-NEXT: ret 316; 317; CHECK-CVT-GI-LABEL: test_select_cc_f32_f16: 318; CHECK-CVT-GI: // %bb.0: 319; CHECK-CVT-GI-NEXT: fcvt s2, h2 320; CHECK-CVT-GI-NEXT: fcvt s3, h3 321; CHECK-CVT-GI-NEXT: fcmp s2, s3 322; CHECK-CVT-GI-NEXT: fcsel s0, s0, s1, ne 323; CHECK-CVT-GI-NEXT: ret 324 %cc = fcmp une half %c, %d 325 %r = select i1 %cc, float %a, float %b 326 ret float %r 327} 328 329define half @test_select_cc_f16_f32(half %a, half %b, float %c, float %d) #0 { 330; CHECK-CVT-SD-LABEL: test_select_cc_f16_f32: 331; CHECK-CVT-SD: // %bb.0: 332; CHECK-CVT-SD-NEXT: fcmp s2, s3 333; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0 334; CHECK-CVT-SD-NEXT: // kill: def $h1 killed $h1 def $s1 335; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne 336; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 337; CHECK-CVT-SD-NEXT: ret 338; 339; CHECK-FP16-SD-LABEL: test_select_cc_f16_f32: 340; CHECK-FP16-SD: // %bb.0: 341; CHECK-FP16-SD-NEXT: fcmp s2, s3 342; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, ne 343; CHECK-FP16-SD-NEXT: ret 344; 345; CHECK-CVT-GI-LABEL: test_select_cc_f16_f32: 346; CHECK-CVT-GI: // %bb.0: 347; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0 348; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $s1 349; CHECK-CVT-GI-NEXT: fcmp s2, s3 350; CHECK-CVT-GI-NEXT: fmov w8, s0 351; CHECK-CVT-GI-NEXT: fmov w9, s1 352; CHECK-CVT-GI-NEXT: csel w8, w8, w9, ne 353; CHECK-CVT-GI-NEXT: fmov s0, w8 354; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 355; CHECK-CVT-GI-NEXT: ret 356; 357; CHECK-FP16-GI-LABEL: test_select_cc_f16_f32: 358; CHECK-FP16-GI: // %bb.0: 359; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0 360; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $s1 361; CHECK-FP16-GI-NEXT: fcmp s2, s3 362; CHECK-FP16-GI-NEXT: fmov w8, s0 363; CHECK-FP16-GI-NEXT: fmov w9, s1 364; CHECK-FP16-GI-NEXT: csel w8, w8, w9, ne 365; CHECK-FP16-GI-NEXT: fmov s0, w8 366; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 367; CHECK-FP16-GI-NEXT: ret 368 %cc = fcmp une float %c, %d 369 %r = select i1 %cc, half %a, half %b 370 ret half %r 371} 372 373define i1 @test_fcmp_une(half %a, half %b) #0 { 374; CHECK-CVT-SD-LABEL: test_fcmp_une: 375; CHECK-CVT-SD: // %bb.0: 376; CHECK-CVT-SD-NEXT: fcvt s1, h1 377; CHECK-CVT-SD-NEXT: fcvt s0, h0 378; CHECK-CVT-SD-NEXT: fcmp s0, s1 379; CHECK-CVT-SD-NEXT: cset w0, ne 380; CHECK-CVT-SD-NEXT: ret 381; 382; CHECK-FP16-LABEL: test_fcmp_une: 383; CHECK-FP16: // %bb.0: 384; CHECK-FP16-NEXT: fcmp h0, h1 385; CHECK-FP16-NEXT: cset w0, ne 386; CHECK-FP16-NEXT: ret 387; 388; CHECK-CVT-GI-LABEL: test_fcmp_une: 389; CHECK-CVT-GI: // %bb.0: 390; CHECK-CVT-GI-NEXT: fcvt s0, h0 391; CHECK-CVT-GI-NEXT: fcvt s1, h1 392; CHECK-CVT-GI-NEXT: fcmp s0, s1 393; CHECK-CVT-GI-NEXT: cset w0, ne 394; CHECK-CVT-GI-NEXT: ret 395 %r = fcmp une half %a, %b 396 ret i1 %r 397} 398 399define i1 @test_fcmp_ueq(half %a, half %b) #0 { 400; CHECK-CVT-SD-LABEL: test_fcmp_ueq: 401; CHECK-CVT-SD: // %bb.0: 402; CHECK-CVT-SD-NEXT: fcvt s1, h1 403; CHECK-CVT-SD-NEXT: fcvt s0, h0 404; CHECK-CVT-SD-NEXT: fcmp s0, s1 405; CHECK-CVT-SD-NEXT: cset w8, eq 406; CHECK-CVT-SD-NEXT: csinc w0, w8, wzr, vc 407; CHECK-CVT-SD-NEXT: ret 408; 409; CHECK-FP16-SD-LABEL: test_fcmp_ueq: 410; CHECK-FP16-SD: // %bb.0: 411; CHECK-FP16-SD-NEXT: fcmp h0, h1 412; CHECK-FP16-SD-NEXT: cset w8, eq 413; CHECK-FP16-SD-NEXT: csinc w0, w8, wzr, vc 414; CHECK-FP16-SD-NEXT: ret 415; 416; CHECK-CVT-GI-LABEL: test_fcmp_ueq: 417; CHECK-CVT-GI: // %bb.0: 418; CHECK-CVT-GI-NEXT: fcvt s0, h0 419; CHECK-CVT-GI-NEXT: fcvt s1, h1 420; CHECK-CVT-GI-NEXT: fcmp s0, s1 421; CHECK-CVT-GI-NEXT: cset w8, eq 422; CHECK-CVT-GI-NEXT: cset w9, vs 423; CHECK-CVT-GI-NEXT: orr w0, w8, w9 424; CHECK-CVT-GI-NEXT: ret 425; 426; CHECK-FP16-GI-LABEL: test_fcmp_ueq: 427; CHECK-FP16-GI: // %bb.0: 428; CHECK-FP16-GI-NEXT: fcmp h0, h1 429; CHECK-FP16-GI-NEXT: cset w8, eq 430; CHECK-FP16-GI-NEXT: cset w9, vs 431; CHECK-FP16-GI-NEXT: orr w0, w8, w9 432; CHECK-FP16-GI-NEXT: ret 433 %r = fcmp ueq half %a, %b 434 ret i1 %r 435} 436 437define i1 @test_fcmp_ugt(half %a, half %b) #0 { 438; CHECK-CVT-SD-LABEL: test_fcmp_ugt: 439; CHECK-CVT-SD: // %bb.0: 440; CHECK-CVT-SD-NEXT: fcvt s1, h1 441; CHECK-CVT-SD-NEXT: fcvt s0, h0 442; CHECK-CVT-SD-NEXT: fcmp s0, s1 443; CHECK-CVT-SD-NEXT: cset w0, hi 444; CHECK-CVT-SD-NEXT: ret 445; 446; CHECK-FP16-LABEL: test_fcmp_ugt: 447; CHECK-FP16: // %bb.0: 448; CHECK-FP16-NEXT: fcmp h0, h1 449; CHECK-FP16-NEXT: cset w0, hi 450; CHECK-FP16-NEXT: ret 451; 452; CHECK-CVT-GI-LABEL: test_fcmp_ugt: 453; CHECK-CVT-GI: // %bb.0: 454; CHECK-CVT-GI-NEXT: fcvt s0, h0 455; CHECK-CVT-GI-NEXT: fcvt s1, h1 456; CHECK-CVT-GI-NEXT: fcmp s0, s1 457; CHECK-CVT-GI-NEXT: cset w0, hi 458; CHECK-CVT-GI-NEXT: ret 459 %r = fcmp ugt half %a, %b 460 ret i1 %r 461} 462 463define i1 @test_fcmp_uge(half %a, half %b) #0 { 464; CHECK-CVT-SD-LABEL: test_fcmp_uge: 465; CHECK-CVT-SD: // %bb.0: 466; CHECK-CVT-SD-NEXT: fcvt s1, h1 467; CHECK-CVT-SD-NEXT: fcvt s0, h0 468; CHECK-CVT-SD-NEXT: fcmp s0, s1 469; CHECK-CVT-SD-NEXT: cset w0, pl 470; CHECK-CVT-SD-NEXT: ret 471; 472; CHECK-FP16-LABEL: test_fcmp_uge: 473; CHECK-FP16: // %bb.0: 474; CHECK-FP16-NEXT: fcmp h0, h1 475; CHECK-FP16-NEXT: cset w0, pl 476; CHECK-FP16-NEXT: ret 477; 478; CHECK-CVT-GI-LABEL: test_fcmp_uge: 479; CHECK-CVT-GI: // %bb.0: 480; CHECK-CVT-GI-NEXT: fcvt s0, h0 481; CHECK-CVT-GI-NEXT: fcvt s1, h1 482; CHECK-CVT-GI-NEXT: fcmp s0, s1 483; CHECK-CVT-GI-NEXT: cset w0, pl 484; CHECK-CVT-GI-NEXT: ret 485 %r = fcmp uge half %a, %b 486 ret i1 %r 487} 488 489define i1 @test_fcmp_ult(half %a, half %b) #0 { 490; CHECK-CVT-SD-LABEL: test_fcmp_ult: 491; CHECK-CVT-SD: // %bb.0: 492; CHECK-CVT-SD-NEXT: fcvt s1, h1 493; CHECK-CVT-SD-NEXT: fcvt s0, h0 494; CHECK-CVT-SD-NEXT: fcmp s0, s1 495; CHECK-CVT-SD-NEXT: cset w0, lt 496; CHECK-CVT-SD-NEXT: ret 497; 498; CHECK-FP16-LABEL: test_fcmp_ult: 499; CHECK-FP16: // %bb.0: 500; CHECK-FP16-NEXT: fcmp h0, h1 501; CHECK-FP16-NEXT: cset w0, lt 502; CHECK-FP16-NEXT: ret 503; 504; CHECK-CVT-GI-LABEL: test_fcmp_ult: 505; CHECK-CVT-GI: // %bb.0: 506; CHECK-CVT-GI-NEXT: fcvt s0, h0 507; CHECK-CVT-GI-NEXT: fcvt s1, h1 508; CHECK-CVT-GI-NEXT: fcmp s0, s1 509; CHECK-CVT-GI-NEXT: cset w0, lt 510; CHECK-CVT-GI-NEXT: ret 511 %r = fcmp ult half %a, %b 512 ret i1 %r 513} 514 515define i1 @test_fcmp_ule(half %a, half %b) #0 { 516; CHECK-CVT-SD-LABEL: test_fcmp_ule: 517; CHECK-CVT-SD: // %bb.0: 518; CHECK-CVT-SD-NEXT: fcvt s1, h1 519; CHECK-CVT-SD-NEXT: fcvt s0, h0 520; CHECK-CVT-SD-NEXT: fcmp s0, s1 521; CHECK-CVT-SD-NEXT: cset w0, le 522; CHECK-CVT-SD-NEXT: ret 523; 524; CHECK-FP16-LABEL: test_fcmp_ule: 525; CHECK-FP16: // %bb.0: 526; CHECK-FP16-NEXT: fcmp h0, h1 527; CHECK-FP16-NEXT: cset w0, le 528; CHECK-FP16-NEXT: ret 529; 530; CHECK-CVT-GI-LABEL: test_fcmp_ule: 531; CHECK-CVT-GI: // %bb.0: 532; CHECK-CVT-GI-NEXT: fcvt s0, h0 533; CHECK-CVT-GI-NEXT: fcvt s1, h1 534; CHECK-CVT-GI-NEXT: fcmp s0, s1 535; CHECK-CVT-GI-NEXT: cset w0, le 536; CHECK-CVT-GI-NEXT: ret 537 %r = fcmp ule half %a, %b 538 ret i1 %r 539} 540 541define i1 @test_fcmp_uno(half %a, half %b) #0 { 542; CHECK-CVT-SD-LABEL: test_fcmp_uno: 543; CHECK-CVT-SD: // %bb.0: 544; CHECK-CVT-SD-NEXT: fcvt s1, h1 545; CHECK-CVT-SD-NEXT: fcvt s0, h0 546; CHECK-CVT-SD-NEXT: fcmp s0, s1 547; CHECK-CVT-SD-NEXT: cset w0, vs 548; CHECK-CVT-SD-NEXT: ret 549; 550; CHECK-FP16-LABEL: test_fcmp_uno: 551; CHECK-FP16: // %bb.0: 552; CHECK-FP16-NEXT: fcmp h0, h1 553; CHECK-FP16-NEXT: cset w0, vs 554; CHECK-FP16-NEXT: ret 555; 556; CHECK-CVT-GI-LABEL: test_fcmp_uno: 557; CHECK-CVT-GI: // %bb.0: 558; CHECK-CVT-GI-NEXT: fcvt s0, h0 559; CHECK-CVT-GI-NEXT: fcvt s1, h1 560; CHECK-CVT-GI-NEXT: fcmp s0, s1 561; CHECK-CVT-GI-NEXT: cset w0, vs 562; CHECK-CVT-GI-NEXT: ret 563 %r = fcmp uno half %a, %b 564 ret i1 %r 565} 566 567define i1 @test_fcmp_one(half %a, half %b) #0 { 568; CHECK-CVT-SD-LABEL: test_fcmp_one: 569; CHECK-CVT-SD: // %bb.0: 570; CHECK-CVT-SD-NEXT: fcvt s1, h1 571; CHECK-CVT-SD-NEXT: fcvt s0, h0 572; CHECK-CVT-SD-NEXT: fcmp s0, s1 573; CHECK-CVT-SD-NEXT: cset w8, mi 574; CHECK-CVT-SD-NEXT: csinc w0, w8, wzr, le 575; CHECK-CVT-SD-NEXT: ret 576; 577; CHECK-FP16-SD-LABEL: test_fcmp_one: 578; CHECK-FP16-SD: // %bb.0: 579; CHECK-FP16-SD-NEXT: fcmp h0, h1 580; CHECK-FP16-SD-NEXT: cset w8, mi 581; CHECK-FP16-SD-NEXT: csinc w0, w8, wzr, le 582; CHECK-FP16-SD-NEXT: ret 583; 584; CHECK-CVT-GI-LABEL: test_fcmp_one: 585; CHECK-CVT-GI: // %bb.0: 586; CHECK-CVT-GI-NEXT: fcvt s0, h0 587; CHECK-CVT-GI-NEXT: fcvt s1, h1 588; CHECK-CVT-GI-NEXT: fcmp s0, s1 589; CHECK-CVT-GI-NEXT: cset w8, mi 590; CHECK-CVT-GI-NEXT: cset w9, gt 591; CHECK-CVT-GI-NEXT: orr w0, w8, w9 592; CHECK-CVT-GI-NEXT: ret 593; 594; CHECK-FP16-GI-LABEL: test_fcmp_one: 595; CHECK-FP16-GI: // %bb.0: 596; CHECK-FP16-GI-NEXT: fcmp h0, h1 597; CHECK-FP16-GI-NEXT: cset w8, mi 598; CHECK-FP16-GI-NEXT: cset w9, gt 599; CHECK-FP16-GI-NEXT: orr w0, w8, w9 600; CHECK-FP16-GI-NEXT: ret 601 %r = fcmp one half %a, %b 602 ret i1 %r 603} 604 605define i1 @test_fcmp_oeq(half %a, half %b) #0 { 606; CHECK-CVT-SD-LABEL: test_fcmp_oeq: 607; CHECK-CVT-SD: // %bb.0: 608; CHECK-CVT-SD-NEXT: fcvt s1, h1 609; CHECK-CVT-SD-NEXT: fcvt s0, h0 610; CHECK-CVT-SD-NEXT: fcmp s0, s1 611; CHECK-CVT-SD-NEXT: cset w0, eq 612; CHECK-CVT-SD-NEXT: ret 613; 614; CHECK-FP16-LABEL: test_fcmp_oeq: 615; CHECK-FP16: // %bb.0: 616; CHECK-FP16-NEXT: fcmp h0, h1 617; CHECK-FP16-NEXT: cset w0, eq 618; CHECK-FP16-NEXT: ret 619; 620; CHECK-CVT-GI-LABEL: test_fcmp_oeq: 621; CHECK-CVT-GI: // %bb.0: 622; CHECK-CVT-GI-NEXT: fcvt s0, h0 623; CHECK-CVT-GI-NEXT: fcvt s1, h1 624; CHECK-CVT-GI-NEXT: fcmp s0, s1 625; CHECK-CVT-GI-NEXT: cset w0, eq 626; CHECK-CVT-GI-NEXT: ret 627 %r = fcmp oeq half %a, %b 628 ret i1 %r 629} 630 631define i1 @test_fcmp_ogt(half %a, half %b) #0 { 632; CHECK-CVT-SD-LABEL: test_fcmp_ogt: 633; CHECK-CVT-SD: // %bb.0: 634; CHECK-CVT-SD-NEXT: fcvt s1, h1 635; CHECK-CVT-SD-NEXT: fcvt s0, h0 636; CHECK-CVT-SD-NEXT: fcmp s0, s1 637; CHECK-CVT-SD-NEXT: cset w0, gt 638; CHECK-CVT-SD-NEXT: ret 639; 640; CHECK-FP16-LABEL: test_fcmp_ogt: 641; CHECK-FP16: // %bb.0: 642; CHECK-FP16-NEXT: fcmp h0, h1 643; CHECK-FP16-NEXT: cset w0, gt 644; CHECK-FP16-NEXT: ret 645; 646; CHECK-CVT-GI-LABEL: test_fcmp_ogt: 647; CHECK-CVT-GI: // %bb.0: 648; CHECK-CVT-GI-NEXT: fcvt s0, h0 649; CHECK-CVT-GI-NEXT: fcvt s1, h1 650; CHECK-CVT-GI-NEXT: fcmp s0, s1 651; CHECK-CVT-GI-NEXT: cset w0, gt 652; CHECK-CVT-GI-NEXT: ret 653 %r = fcmp ogt half %a, %b 654 ret i1 %r 655} 656 657define i1 @test_fcmp_oge(half %a, half %b) #0 { 658; CHECK-CVT-SD-LABEL: test_fcmp_oge: 659; CHECK-CVT-SD: // %bb.0: 660; CHECK-CVT-SD-NEXT: fcvt s1, h1 661; CHECK-CVT-SD-NEXT: fcvt s0, h0 662; CHECK-CVT-SD-NEXT: fcmp s0, s1 663; CHECK-CVT-SD-NEXT: cset w0, ge 664; CHECK-CVT-SD-NEXT: ret 665; 666; CHECK-FP16-LABEL: test_fcmp_oge: 667; CHECK-FP16: // %bb.0: 668; CHECK-FP16-NEXT: fcmp h0, h1 669; CHECK-FP16-NEXT: cset w0, ge 670; CHECK-FP16-NEXT: ret 671; 672; CHECK-CVT-GI-LABEL: test_fcmp_oge: 673; CHECK-CVT-GI: // %bb.0: 674; CHECK-CVT-GI-NEXT: fcvt s0, h0 675; CHECK-CVT-GI-NEXT: fcvt s1, h1 676; CHECK-CVT-GI-NEXT: fcmp s0, s1 677; CHECK-CVT-GI-NEXT: cset w0, ge 678; CHECK-CVT-GI-NEXT: ret 679 %r = fcmp oge half %a, %b 680 ret i1 %r 681} 682 683define i1 @test_fcmp_olt(half %a, half %b) #0 { 684; CHECK-CVT-SD-LABEL: test_fcmp_olt: 685; CHECK-CVT-SD: // %bb.0: 686; CHECK-CVT-SD-NEXT: fcvt s1, h1 687; CHECK-CVT-SD-NEXT: fcvt s0, h0 688; CHECK-CVT-SD-NEXT: fcmp s0, s1 689; CHECK-CVT-SD-NEXT: cset w0, mi 690; CHECK-CVT-SD-NEXT: ret 691; 692; CHECK-FP16-LABEL: test_fcmp_olt: 693; CHECK-FP16: // %bb.0: 694; CHECK-FP16-NEXT: fcmp h0, h1 695; CHECK-FP16-NEXT: cset w0, mi 696; CHECK-FP16-NEXT: ret 697; 698; CHECK-CVT-GI-LABEL: test_fcmp_olt: 699; CHECK-CVT-GI: // %bb.0: 700; CHECK-CVT-GI-NEXT: fcvt s0, h0 701; CHECK-CVT-GI-NEXT: fcvt s1, h1 702; CHECK-CVT-GI-NEXT: fcmp s0, s1 703; CHECK-CVT-GI-NEXT: cset w0, mi 704; CHECK-CVT-GI-NEXT: ret 705 %r = fcmp olt half %a, %b 706 ret i1 %r 707} 708 709define i1 @test_fcmp_ole(half %a, half %b) #0 { 710; CHECK-CVT-SD-LABEL: test_fcmp_ole: 711; CHECK-CVT-SD: // %bb.0: 712; CHECK-CVT-SD-NEXT: fcvt s1, h1 713; CHECK-CVT-SD-NEXT: fcvt s0, h0 714; CHECK-CVT-SD-NEXT: fcmp s0, s1 715; CHECK-CVT-SD-NEXT: cset w0, ls 716; CHECK-CVT-SD-NEXT: ret 717; 718; CHECK-FP16-LABEL: test_fcmp_ole: 719; CHECK-FP16: // %bb.0: 720; CHECK-FP16-NEXT: fcmp h0, h1 721; CHECK-FP16-NEXT: cset w0, ls 722; CHECK-FP16-NEXT: ret 723; 724; CHECK-CVT-GI-LABEL: test_fcmp_ole: 725; CHECK-CVT-GI: // %bb.0: 726; CHECK-CVT-GI-NEXT: fcvt s0, h0 727; CHECK-CVT-GI-NEXT: fcvt s1, h1 728; CHECK-CVT-GI-NEXT: fcmp s0, s1 729; CHECK-CVT-GI-NEXT: cset w0, ls 730; CHECK-CVT-GI-NEXT: ret 731 %r = fcmp ole half %a, %b 732 ret i1 %r 733} 734 735define i1 @test_fcmp_ord(half %a, half %b) #0 { 736; CHECK-CVT-SD-LABEL: test_fcmp_ord: 737; CHECK-CVT-SD: // %bb.0: 738; CHECK-CVT-SD-NEXT: fcvt s1, h1 739; CHECK-CVT-SD-NEXT: fcvt s0, h0 740; CHECK-CVT-SD-NEXT: fcmp s0, s1 741; CHECK-CVT-SD-NEXT: cset w0, vc 742; CHECK-CVT-SD-NEXT: ret 743; 744; CHECK-FP16-LABEL: test_fcmp_ord: 745; CHECK-FP16: // %bb.0: 746; CHECK-FP16-NEXT: fcmp h0, h1 747; CHECK-FP16-NEXT: cset w0, vc 748; CHECK-FP16-NEXT: ret 749; 750; CHECK-CVT-GI-LABEL: test_fcmp_ord: 751; CHECK-CVT-GI: // %bb.0: 752; CHECK-CVT-GI-NEXT: fcvt s0, h0 753; CHECK-CVT-GI-NEXT: fcvt s1, h1 754; CHECK-CVT-GI-NEXT: fcmp s0, s1 755; CHECK-CVT-GI-NEXT: cset w0, vc 756; CHECK-CVT-GI-NEXT: ret 757 %r = fcmp ord half %a, %b 758 ret i1 %r 759} 760 761define void @test_fccmp(half %in, ptr %out) { 762; CHECK-CVT-SD-LABEL: test_fccmp: 763; CHECK-CVT-SD: // %bb.0: 764; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0 765; CHECK-CVT-SD-NEXT: fcvt s1, h0 766; CHECK-CVT-SD-NEXT: fmov s2, #5.00000000 767; CHECK-CVT-SD-NEXT: adrp x8, .LCPI29_0 768; CHECK-CVT-SD-NEXT: fcmp s1, s2 769; CHECK-CVT-SD-NEXT: fmov s2, #8.00000000 770; CHECK-CVT-SD-NEXT: fccmp s1, s2, #4, mi 771; CHECK-CVT-SD-NEXT: ldr h1, [x8, :lo12:.LCPI29_0] 772; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, gt 773; CHECK-CVT-SD-NEXT: str h0, [x0] 774; CHECK-CVT-SD-NEXT: ret 775; 776; CHECK-FP16-SD-LABEL: test_fccmp: 777; CHECK-FP16-SD: // %bb.0: 778; CHECK-FP16-SD-NEXT: fmov h1, #5.00000000 779; CHECK-FP16-SD-NEXT: fmov h2, #8.00000000 780; CHECK-FP16-SD-NEXT: fcmp h0, h1 781; CHECK-FP16-SD-NEXT: fccmp h0, h2, #4, mi 782; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, gt 783; CHECK-FP16-SD-NEXT: str h0, [x0] 784; CHECK-FP16-SD-NEXT: ret 785; 786; CHECK-CVT-GI-LABEL: test_fccmp: 787; CHECK-CVT-GI: // %bb.0: 788; CHECK-CVT-GI-NEXT: mov w8, #17664 // =0x4500 789; CHECK-CVT-GI-NEXT: mov w9, #18432 // =0x4800 790; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0 791; CHECK-CVT-GI-NEXT: fcvt s2, h0 792; CHECK-CVT-GI-NEXT: fmov s1, w8 793; CHECK-CVT-GI-NEXT: fmov s3, w9 794; CHECK-CVT-GI-NEXT: fmov w9, s0 795; CHECK-CVT-GI-NEXT: fcvt s1, h1 796; CHECK-CVT-GI-NEXT: fcvt s3, h3 797; CHECK-CVT-GI-NEXT: fcmp s2, s1 798; CHECK-CVT-GI-NEXT: fccmp s2, s3, #4, mi 799; CHECK-CVT-GI-NEXT: csel w8, w9, w8, gt 800; CHECK-CVT-GI-NEXT: strh w8, [x0] 801; CHECK-CVT-GI-NEXT: ret 802; 803; CHECK-FP16-GI-LABEL: test_fccmp: 804; CHECK-FP16-GI: // %bb.0: 805; CHECK-FP16-GI-NEXT: fmov h1, #5.00000000 806; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0 807; CHECK-FP16-GI-NEXT: fmov h2, #8.00000000 808; CHECK-FP16-GI-NEXT: fmov w8, s0 809; CHECK-FP16-GI-NEXT: fcmp h0, h1 810; CHECK-FP16-GI-NEXT: fmov w9, s1 811; CHECK-FP16-GI-NEXT: fccmp h0, h2, #4, mi 812; CHECK-FP16-GI-NEXT: csel w8, w8, w9, gt 813; CHECK-FP16-GI-NEXT: strh w8, [x0] 814; CHECK-FP16-GI-NEXT: ret 815 %cmp1 = fcmp ogt half %in, 0xH4800 816 %cmp2 = fcmp olt half %in, 0xH4500 817 %cond = and i1 %cmp1, %cmp2 818 %result = select i1 %cond, half %in, half 0xH4500 819 store half %result, ptr %out 820 ret void 821} 822 823define void @test_br_cc(half %a, half %b, ptr %p1, ptr %p2) #0 { 824; CHECK-CVT-SD-LABEL: test_br_cc: 825; CHECK-CVT-SD: // %bb.0: // %common.ret 826; CHECK-CVT-SD-NEXT: fcvt s1, h1 827; CHECK-CVT-SD-NEXT: fcvt s0, h0 828; CHECK-CVT-SD-NEXT: fcmp s0, s1 829; CHECK-CVT-SD-NEXT: csel x8, x0, x1, pl 830; CHECK-CVT-SD-NEXT: str wzr, [x8] 831; CHECK-CVT-SD-NEXT: ret 832; 833; CHECK-FP16-LABEL: test_br_cc: 834; CHECK-FP16: // %bb.0: // %common.ret 835; CHECK-FP16-NEXT: fcmp h0, h1 836; CHECK-FP16-NEXT: csel x8, x0, x1, pl 837; CHECK-FP16-NEXT: str wzr, [x8] 838; CHECK-FP16-NEXT: ret 839; 840; CHECK-CVT-GI-LABEL: test_br_cc: 841; CHECK-CVT-GI: // %bb.0: // %common.ret 842; CHECK-CVT-GI-NEXT: fcvt s0, h0 843; CHECK-CVT-GI-NEXT: fcvt s1, h1 844; CHECK-CVT-GI-NEXT: fcmp s0, s1 845; CHECK-CVT-GI-NEXT: csel x8, x0, x1, pl 846; CHECK-CVT-GI-NEXT: str wzr, [x8] 847; CHECK-CVT-GI-NEXT: ret 848 %c = fcmp uge half %a, %b 849 br i1 %c, label %then, label %else 850then: 851 store i32 0, ptr %p1 852 ret void 853else: 854 store i32 0, ptr %p2 855 ret void 856} 857 858define half @test_phi(ptr %p1) #0 { 859; CHECK-LABEL: test_phi: 860; CHECK: // %bb.0: // %entry 861; CHECK-NEXT: stp d9, d8, [sp, #-32]! // 16-byte Folded Spill 862; CHECK-NEXT: ldr h9, [x0] 863; CHECK-NEXT: stp x30, x19, [sp, #16] // 16-byte Folded Spill 864; CHECK-NEXT: mov x19, x0 865; CHECK-NEXT: .LBB31_1: // %loop 866; CHECK-NEXT: // =>This Inner Loop Header: Depth=1 867; CHECK-NEXT: fmov s8, s9 868; CHECK-NEXT: ldr h9, [x19] 869; CHECK-NEXT: mov x0, x19 870; CHECK-NEXT: bl test_dummy 871; CHECK-NEXT: tbnz w0, #0, .LBB31_1 872; CHECK-NEXT: // %bb.2: // %return 873; CHECK-NEXT: ldp x30, x19, [sp, #16] // 16-byte Folded Reload 874; CHECK-NEXT: fmov s0, s8 875; CHECK-NEXT: ldp d9, d8, [sp], #32 // 16-byte Folded Reload 876; CHECK-NEXT: ret 877entry: 878 %a = load half, ptr %p1 879 br label %loop 880loop: 881 %r = phi half [%a, %entry], [%b, %loop] 882 %b = load half, ptr %p1 883 %c = call i1 @test_dummy(ptr %p1) 884 br i1 %c, label %loop, label %return 885return: 886 ret half %r 887} 888 889declare i1 @test_dummy(ptr %p1) #0 890 891define i32 @test_fptosi_i32(half %a) #0 { 892; CHECK-CVT-LABEL: test_fptosi_i32: 893; CHECK-CVT: // %bb.0: 894; CHECK-CVT-NEXT: fcvt s0, h0 895; CHECK-CVT-NEXT: fcvtzs w0, s0 896; CHECK-CVT-NEXT: ret 897; 898; CHECK-FP16-LABEL: test_fptosi_i32: 899; CHECK-FP16: // %bb.0: 900; CHECK-FP16-NEXT: fcvtzs w0, h0 901; CHECK-FP16-NEXT: ret 902 %r = fptosi half %a to i32 903 ret i32 %r 904} 905 906define i64 @test_fptosi_i64(half %a) #0 { 907; CHECK-CVT-LABEL: test_fptosi_i64: 908; CHECK-CVT: // %bb.0: 909; CHECK-CVT-NEXT: fcvt s0, h0 910; CHECK-CVT-NEXT: fcvtzs x0, s0 911; CHECK-CVT-NEXT: ret 912; 913; CHECK-FP16-LABEL: test_fptosi_i64: 914; CHECK-FP16: // %bb.0: 915; CHECK-FP16-NEXT: fcvtzs x0, h0 916; CHECK-FP16-NEXT: ret 917 %r = fptosi half %a to i64 918 ret i64 %r 919} 920 921define i32 @test_fptoui_i32(half %a) #0 { 922; CHECK-CVT-LABEL: test_fptoui_i32: 923; CHECK-CVT: // %bb.0: 924; CHECK-CVT-NEXT: fcvt s0, h0 925; CHECK-CVT-NEXT: fcvtzu w0, s0 926; CHECK-CVT-NEXT: ret 927; 928; CHECK-FP16-LABEL: test_fptoui_i32: 929; CHECK-FP16: // %bb.0: 930; CHECK-FP16-NEXT: fcvtzu w0, h0 931; CHECK-FP16-NEXT: ret 932 %r = fptoui half %a to i32 933 ret i32 %r 934} 935 936define i64 @test_fptoui_i64(half %a) #0 { 937; CHECK-CVT-LABEL: test_fptoui_i64: 938; CHECK-CVT: // %bb.0: 939; CHECK-CVT-NEXT: fcvt s0, h0 940; CHECK-CVT-NEXT: fcvtzu x0, s0 941; CHECK-CVT-NEXT: ret 942; 943; CHECK-FP16-LABEL: test_fptoui_i64: 944; CHECK-FP16: // %bb.0: 945; CHECK-FP16-NEXT: fcvtzu x0, h0 946; CHECK-FP16-NEXT: ret 947 %r = fptoui half %a to i64 948 ret i64 %r 949} 950 951define half @test_uitofp_i32(i32 %a) #0 { 952; CHECK-CVT-LABEL: test_uitofp_i32: 953; CHECK-CVT: // %bb.0: 954; CHECK-CVT-NEXT: ucvtf s0, w0 955; CHECK-CVT-NEXT: fcvt h0, s0 956; CHECK-CVT-NEXT: ret 957; 958; CHECK-FP16-LABEL: test_uitofp_i32: 959; CHECK-FP16: // %bb.0: 960; CHECK-FP16-NEXT: ucvtf h0, w0 961; CHECK-FP16-NEXT: ret 962 %r = uitofp i32 %a to half 963 ret half %r 964} 965 966define half @test_uitofp_i64(i64 %a) #0 { 967; CHECK-CVT-LABEL: test_uitofp_i64: 968; CHECK-CVT: // %bb.0: 969; CHECK-CVT-NEXT: ucvtf s0, x0 970; CHECK-CVT-NEXT: fcvt h0, s0 971; CHECK-CVT-NEXT: ret 972; 973; CHECK-FP16-LABEL: test_uitofp_i64: 974; CHECK-FP16: // %bb.0: 975; CHECK-FP16-NEXT: ucvtf h0, x0 976; CHECK-FP16-NEXT: ret 977 %r = uitofp i64 %a to half 978 ret half %r 979} 980 981define half @test_sitofp_i32(i32 %a) #0 { 982; CHECK-CVT-LABEL: test_sitofp_i32: 983; CHECK-CVT: // %bb.0: 984; CHECK-CVT-NEXT: scvtf s0, w0 985; CHECK-CVT-NEXT: fcvt h0, s0 986; CHECK-CVT-NEXT: ret 987; 988; CHECK-FP16-LABEL: test_sitofp_i32: 989; CHECK-FP16: // %bb.0: 990; CHECK-FP16-NEXT: scvtf h0, w0 991; CHECK-FP16-NEXT: ret 992 %r = sitofp i32 %a to half 993 ret half %r 994} 995 996define half @test_sitofp_i64(i64 %a) #0 { 997; CHECK-CVT-LABEL: test_sitofp_i64: 998; CHECK-CVT: // %bb.0: 999; CHECK-CVT-NEXT: scvtf s0, x0 1000; CHECK-CVT-NEXT: fcvt h0, s0 1001; CHECK-CVT-NEXT: ret 1002; 1003; CHECK-FP16-LABEL: test_sitofp_i64: 1004; CHECK-FP16: // %bb.0: 1005; CHECK-FP16-NEXT: scvtf h0, x0 1006; CHECK-FP16-NEXT: ret 1007 %r = sitofp i64 %a to half 1008 ret half %r 1009} 1010 1011define half @test_uitofp_i32_fadd(i32 %a, half %b) #0 { 1012; CHECK-CVT-LABEL: test_uitofp_i32_fadd: 1013; CHECK-CVT: // %bb.0: 1014; CHECK-CVT-NEXT: ucvtf s1, w0 1015; CHECK-CVT-NEXT: fcvt s0, h0 1016; CHECK-CVT-NEXT: fcvt h1, s1 1017; CHECK-CVT-NEXT: fcvt s1, h1 1018; CHECK-CVT-NEXT: fadd s0, s0, s1 1019; CHECK-CVT-NEXT: fcvt h0, s0 1020; CHECK-CVT-NEXT: ret 1021; 1022; CHECK-FP16-LABEL: test_uitofp_i32_fadd: 1023; CHECK-FP16: // %bb.0: 1024; CHECK-FP16-NEXT: ucvtf h1, w0 1025; CHECK-FP16-NEXT: fadd h0, h0, h1 1026; CHECK-FP16-NEXT: ret 1027 %c = uitofp i32 %a to half 1028 %r = fadd half %b, %c 1029 ret half %r 1030} 1031 1032define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 { 1033; CHECK-CVT-LABEL: test_sitofp_i32_fadd: 1034; CHECK-CVT: // %bb.0: 1035; CHECK-CVT-NEXT: scvtf s1, w0 1036; CHECK-CVT-NEXT: fcvt s0, h0 1037; CHECK-CVT-NEXT: fcvt h1, s1 1038; CHECK-CVT-NEXT: fcvt s1, h1 1039; CHECK-CVT-NEXT: fadd s0, s0, s1 1040; CHECK-CVT-NEXT: fcvt h0, s0 1041; CHECK-CVT-NEXT: ret 1042; 1043; CHECK-FP16-LABEL: test_sitofp_i32_fadd: 1044; CHECK-FP16: // %bb.0: 1045; CHECK-FP16-NEXT: scvtf h1, w0 1046; CHECK-FP16-NEXT: fadd h0, h0, h1 1047; CHECK-FP16-NEXT: ret 1048 %c = sitofp i32 %a to half 1049 %r = fadd half %b, %c 1050 ret half %r 1051} 1052 1053define half @test_fptrunc_float(float %a) #0 { 1054; CHECK-LABEL: test_fptrunc_float: 1055; CHECK: // %bb.0: 1056; CHECK-NEXT: fcvt h0, s0 1057; CHECK-NEXT: ret 1058 %r = fptrunc float %a to half 1059 ret half %r 1060} 1061 1062define half @test_fptrunc_double(double %a) #0 { 1063; CHECK-LABEL: test_fptrunc_double: 1064; CHECK: // %bb.0: 1065; CHECK-NEXT: fcvt h0, d0 1066; CHECK-NEXT: ret 1067 %r = fptrunc double %a to half 1068 ret half %r 1069} 1070 1071define float @test_fpext_float(half %a) #0 { 1072; CHECK-LABEL: test_fpext_float: 1073; CHECK: // %bb.0: 1074; CHECK-NEXT: fcvt s0, h0 1075; CHECK-NEXT: ret 1076 %r = fpext half %a to float 1077 ret float %r 1078} 1079 1080define double @test_fpext_double(half %a) #0 { 1081; CHECK-LABEL: test_fpext_double: 1082; CHECK: // %bb.0: 1083; CHECK-NEXT: fcvt d0, h0 1084; CHECK-NEXT: ret 1085 %r = fpext half %a to double 1086 ret double %r 1087} 1088 1089define i16 @test_bitcast_halftoi16(half %a) #0 { 1090; CHECK-LABEL: test_bitcast_halftoi16: 1091; CHECK: // %bb.0: 1092; CHECK-NEXT: // kill: def $h0 killed $h0 def $s0 1093; CHECK-NEXT: fmov w0, s0 1094; CHECK-NEXT: ret 1095 %r = bitcast half %a to i16 1096 ret i16 %r 1097} 1098 1099define half @test_bitcast_i16tohalf(i16 %a) #0 { 1100; CHECK-LABEL: test_bitcast_i16tohalf: 1101; CHECK: // %bb.0: 1102; CHECK-NEXT: fmov s0, w0 1103; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0 1104; CHECK-NEXT: ret 1105 %r = bitcast i16 %a to half 1106 ret half %r 1107} 1108 1109declare half @llvm.sqrt.f16(half %a) #0 1110declare half @llvm.powi.f16.i32(half %a, i32 %b) #0 1111declare half @llvm.sin.f16(half %a) #0 1112declare half @llvm.cos.f16(half %a) #0 1113declare half @llvm.tan.f16(half %a) #0 1114declare half @llvm.asin.f16(half %a) #0 1115declare half @llvm.acos.f16(half %a) #0 1116declare half @llvm.atan.f16(half %a) #0 1117declare half @llvm.atan2.f16(half %a, half %b) #0 1118declare half @llvm.sinh.f16(half %a) #0 1119declare half @llvm.cosh.f16(half %a) #0 1120declare half @llvm.tanh.f16(half %a) #0 1121declare half @llvm.pow.f16(half %a, half %b) #0 1122declare half @llvm.exp.f16(half %a) #0 1123declare half @llvm.exp2.f16(half %a) #0 1124declare half @llvm.log.f16(half %a) #0 1125declare half @llvm.log10.f16(half %a) #0 1126declare half @llvm.log2.f16(half %a) #0 1127declare half @llvm.fma.f16(half %a, half %b, half %c) #0 1128declare half @llvm.fabs.f16(half %a) #0 1129declare half @llvm.minnum.f16(half %a, half %b) #0 1130declare half @llvm.maxnum.f16(half %a, half %b) #0 1131declare half @llvm.copysign.f16(half %a, half %b) #0 1132declare half @llvm.floor.f16(half %a) #0 1133declare half @llvm.ceil.f16(half %a) #0 1134declare half @llvm.trunc.f16(half %a) #0 1135declare half @llvm.rint.f16(half %a) #0 1136declare half @llvm.nearbyint.f16(half %a) #0 1137declare half @llvm.round.f16(half %a) #0 1138declare half @llvm.roundeven.f16(half %a) #0 1139declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0 1140 1141 1142define half @test_sqrt(half %a) #0 { 1143; CHECK-CVT-LABEL: test_sqrt: 1144; CHECK-CVT: // %bb.0: 1145; CHECK-CVT-NEXT: fcvt s0, h0 1146; CHECK-CVT-NEXT: fsqrt s0, s0 1147; CHECK-CVT-NEXT: fcvt h0, s0 1148; CHECK-CVT-NEXT: ret 1149; 1150; CHECK-FP16-LABEL: test_sqrt: 1151; CHECK-FP16: // %bb.0: 1152; CHECK-FP16-NEXT: fsqrt h0, h0 1153; CHECK-FP16-NEXT: ret 1154 %r = call half @llvm.sqrt.f16(half %a) 1155 ret half %r 1156} 1157 1158define half @test_powi(half %a, i32 %b) #0 { 1159; CHECK-LABEL: test_powi: 1160; CHECK: // %bb.0: 1161; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1162; CHECK-NEXT: fcvt s0, h0 1163; CHECK-NEXT: bl __powisf2 1164; CHECK-NEXT: fcvt h0, s0 1165; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1166; CHECK-NEXT: ret 1167 %r = call half @llvm.powi.f16.i32(half %a, i32 %b) 1168 ret half %r 1169} 1170 1171 1172define half @test_sin(half %a) #0 { 1173; CHECK-LABEL: test_sin: 1174; CHECK: // %bb.0: 1175; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1176; CHECK-NEXT: fcvt s0, h0 1177; CHECK-NEXT: bl sinf 1178; CHECK-NEXT: fcvt h0, s0 1179; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1180; CHECK-NEXT: ret 1181 %r = call half @llvm.sin.f16(half %a) 1182 ret half %r 1183} 1184 1185define half @test_cos(half %a) #0 { 1186; CHECK-LABEL: test_cos: 1187; CHECK: // %bb.0: 1188; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1189; CHECK-NEXT: fcvt s0, h0 1190; CHECK-NEXT: bl cosf 1191; CHECK-NEXT: fcvt h0, s0 1192; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1193; CHECK-NEXT: ret 1194 %r = call half @llvm.cos.f16(half %a) 1195 ret half %r 1196} 1197 1198define half @test_tan(half %a) #0 { 1199; CHECK-LABEL: test_tan: 1200; CHECK: // %bb.0: 1201; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1202; CHECK-NEXT: fcvt s0, h0 1203; CHECK-NEXT: bl tanf 1204; CHECK-NEXT: fcvt h0, s0 1205; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1206; CHECK-NEXT: ret 1207 %r = call half @llvm.tan.f16(half %a) 1208 ret half %r 1209} 1210 1211define half @test_acos(half %a) #0 { 1212; CHECK-LABEL: test_acos: 1213; CHECK: // %bb.0: 1214; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1215; CHECK-NEXT: fcvt s0, h0 1216; CHECK-NEXT: bl acosf 1217; CHECK-NEXT: fcvt h0, s0 1218; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1219; CHECK-NEXT: ret 1220 %r = call half @llvm.acos.f16(half %a) 1221 ret half %r 1222} 1223 1224define half @test_asin(half %a) #0 { 1225; CHECK-LABEL: test_asin: 1226; CHECK: // %bb.0: 1227; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1228; CHECK-NEXT: fcvt s0, h0 1229; CHECK-NEXT: bl asinf 1230; CHECK-NEXT: fcvt h0, s0 1231; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1232; CHECK-NEXT: ret 1233 %r = call half @llvm.asin.f16(half %a) 1234 ret half %r 1235} 1236 1237define half @test_atan(half %a) #0 { 1238; CHECK-LABEL: test_atan: 1239; CHECK: // %bb.0: 1240; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1241; CHECK-NEXT: fcvt s0, h0 1242; CHECK-NEXT: bl atanf 1243; CHECK-NEXT: fcvt h0, s0 1244; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1245; CHECK-NEXT: ret 1246 %r = call half @llvm.atan.f16(half %a) 1247 ret half %r 1248} 1249 1250define half @test_atan2(half %a, half %b) #0 { 1251 %r = call half @llvm.atan2.f16(half %a, half %b) 1252 ret half %r 1253} 1254 1255define half @test_cosh(half %a) #0 { 1256; CHECK-LABEL: test_cosh: 1257; CHECK: // %bb.0: 1258; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1259; CHECK-NEXT: fcvt s0, h0 1260; CHECK-NEXT: bl coshf 1261; CHECK-NEXT: fcvt h0, s0 1262; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1263; CHECK-NEXT: ret 1264 %r = call half @llvm.cosh.f16(half %a) 1265 ret half %r 1266} 1267 1268define half @test_sinh(half %a) #0 { 1269; CHECK-LABEL: test_sinh: 1270; CHECK: // %bb.0: 1271; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1272; CHECK-NEXT: fcvt s0, h0 1273; CHECK-NEXT: bl sinhf 1274; CHECK-NEXT: fcvt h0, s0 1275; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1276; CHECK-NEXT: ret 1277 %r = call half @llvm.sinh.f16(half %a) 1278 ret half %r 1279} 1280 1281define half @test_tanh(half %a) #0 { 1282; CHECK-LABEL: test_tanh: 1283; CHECK: // %bb.0: 1284; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1285; CHECK-NEXT: fcvt s0, h0 1286; CHECK-NEXT: bl tanhf 1287; CHECK-NEXT: fcvt h0, s0 1288; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1289; CHECK-NEXT: ret 1290 %r = call half @llvm.tanh.f16(half %a) 1291 ret half %r 1292} 1293 1294define half @test_pow(half %a, half %b) #0 { 1295; CHECK-LABEL: test_pow: 1296; CHECK: // %bb.0: 1297; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1298; CHECK-NEXT: fcvt s0, h0 1299; CHECK-NEXT: fcvt s1, h1 1300; CHECK-NEXT: bl powf 1301; CHECK-NEXT: fcvt h0, s0 1302; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1303; CHECK-NEXT: ret 1304 %r = call half @llvm.pow.f16(half %a, half %b) 1305 ret half %r 1306} 1307 1308define half @test_exp(half %a) #0 { 1309; CHECK-LABEL: test_exp: 1310; CHECK: // %bb.0: 1311; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1312; CHECK-NEXT: fcvt s0, h0 1313; CHECK-NEXT: bl expf 1314; CHECK-NEXT: fcvt h0, s0 1315; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1316; CHECK-NEXT: ret 1317 %r = call half @llvm.exp.f16(half %a) 1318 ret half %r 1319} 1320 1321define half @test_exp2(half %a) #0 { 1322; CHECK-LABEL: test_exp2: 1323; CHECK: // %bb.0: 1324; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1325; CHECK-NEXT: fcvt s0, h0 1326; CHECK-NEXT: bl exp2f 1327; CHECK-NEXT: fcvt h0, s0 1328; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1329; CHECK-NEXT: ret 1330 %r = call half @llvm.exp2.f16(half %a) 1331 ret half %r 1332} 1333 1334define half @test_log(half %a) #0 { 1335; CHECK-LABEL: test_log: 1336; CHECK: // %bb.0: 1337; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1338; CHECK-NEXT: fcvt s0, h0 1339; CHECK-NEXT: bl logf 1340; CHECK-NEXT: fcvt h0, s0 1341; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1342; CHECK-NEXT: ret 1343 %r = call half @llvm.log.f16(half %a) 1344 ret half %r 1345} 1346 1347define half @test_log10(half %a) #0 { 1348; CHECK-LABEL: test_log10: 1349; CHECK: // %bb.0: 1350; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1351; CHECK-NEXT: fcvt s0, h0 1352; CHECK-NEXT: bl log10f 1353; CHECK-NEXT: fcvt h0, s0 1354; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1355; CHECK-NEXT: ret 1356 %r = call half @llvm.log10.f16(half %a) 1357 ret half %r 1358} 1359 1360define half @test_log2(half %a) #0 { 1361; CHECK-LABEL: test_log2: 1362; CHECK: // %bb.0: 1363; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill 1364; CHECK-NEXT: fcvt s0, h0 1365; CHECK-NEXT: bl log2f 1366; CHECK-NEXT: fcvt h0, s0 1367; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload 1368; CHECK-NEXT: ret 1369 %r = call half @llvm.log2.f16(half %a) 1370 ret half %r 1371} 1372 1373define half @test_fma(half %a, half %b, half %c) #0 { 1374; CHECK-CVT-SD-LABEL: test_fma: 1375; CHECK-CVT-SD: // %bb.0: 1376; CHECK-CVT-SD-NEXT: fcvt s2, h2 1377; CHECK-CVT-SD-NEXT: fcvt s1, h1 1378; CHECK-CVT-SD-NEXT: fcvt s0, h0 1379; CHECK-CVT-SD-NEXT: fmadd s0, s0, s1, s2 1380; CHECK-CVT-SD-NEXT: fcvt h0, s0 1381; CHECK-CVT-SD-NEXT: ret 1382; 1383; CHECK-FP16-LABEL: test_fma: 1384; CHECK-FP16: // %bb.0: 1385; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2 1386; CHECK-FP16-NEXT: ret 1387; 1388; CHECK-CVT-GI-LABEL: test_fma: 1389; CHECK-CVT-GI: // %bb.0: 1390; CHECK-CVT-GI-NEXT: fcvt s0, h0 1391; CHECK-CVT-GI-NEXT: fcvt s1, h1 1392; CHECK-CVT-GI-NEXT: fcvt s2, h2 1393; CHECK-CVT-GI-NEXT: fmadd s0, s0, s1, s2 1394; CHECK-CVT-GI-NEXT: fcvt h0, s0 1395; CHECK-CVT-GI-NEXT: ret 1396 %r = call half @llvm.fma.f16(half %a, half %b, half %c) 1397 ret half %r 1398} 1399 1400define half @test_fabs(half %a) #0 { 1401; CHECK-CVT-LABEL: test_fabs: 1402; CHECK-CVT: // %bb.0: 1403; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 def $s0 1404; CHECK-CVT-NEXT: fmov w8, s0 1405; CHECK-CVT-NEXT: and w8, w8, #0x7fff 1406; CHECK-CVT-NEXT: fmov s0, w8 1407; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 1408; CHECK-CVT-NEXT: ret 1409; 1410; CHECK-FP16-LABEL: test_fabs: 1411; CHECK-FP16: // %bb.0: 1412; CHECK-FP16-NEXT: fabs h0, h0 1413; CHECK-FP16-NEXT: ret 1414 %r = call half @llvm.fabs.f16(half %a) 1415 ret half %r 1416} 1417 1418define half @test_minnum(half %a, half %b) #0 { 1419; CHECK-CVT-SD-LABEL: test_minnum: 1420; CHECK-CVT-SD: // %bb.0: 1421; CHECK-CVT-SD-NEXT: fcvt s1, h1 1422; CHECK-CVT-SD-NEXT: fcvt s0, h0 1423; CHECK-CVT-SD-NEXT: fminnm s0, s0, s1 1424; CHECK-CVT-SD-NEXT: fcvt h0, s0 1425; CHECK-CVT-SD-NEXT: ret 1426; 1427; CHECK-FP16-LABEL: test_minnum: 1428; CHECK-FP16: // %bb.0: 1429; CHECK-FP16-NEXT: fminnm h0, h0, h1 1430; CHECK-FP16-NEXT: ret 1431; 1432; CHECK-CVT-GI-LABEL: test_minnum: 1433; CHECK-CVT-GI: // %bb.0: 1434; CHECK-CVT-GI-NEXT: fcvt s0, h0 1435; CHECK-CVT-GI-NEXT: fcvt s1, h1 1436; CHECK-CVT-GI-NEXT: fminnm s0, s0, s1 1437; CHECK-CVT-GI-NEXT: fcvt h0, s0 1438; CHECK-CVT-GI-NEXT: ret 1439 %r = call half @llvm.minnum.f16(half %a, half %b) 1440 ret half %r 1441} 1442 1443define half @test_maxnum(half %a, half %b) #0 { 1444; CHECK-CVT-SD-LABEL: test_maxnum: 1445; CHECK-CVT-SD: // %bb.0: 1446; CHECK-CVT-SD-NEXT: fcvt s1, h1 1447; CHECK-CVT-SD-NEXT: fcvt s0, h0 1448; CHECK-CVT-SD-NEXT: fmaxnm s0, s0, s1 1449; CHECK-CVT-SD-NEXT: fcvt h0, s0 1450; CHECK-CVT-SD-NEXT: ret 1451; 1452; CHECK-FP16-LABEL: test_maxnum: 1453; CHECK-FP16: // %bb.0: 1454; CHECK-FP16-NEXT: fmaxnm h0, h0, h1 1455; CHECK-FP16-NEXT: ret 1456; 1457; CHECK-CVT-GI-LABEL: test_maxnum: 1458; CHECK-CVT-GI: // %bb.0: 1459; CHECK-CVT-GI-NEXT: fcvt s0, h0 1460; CHECK-CVT-GI-NEXT: fcvt s1, h1 1461; CHECK-CVT-GI-NEXT: fmaxnm s0, s0, s1 1462; CHECK-CVT-GI-NEXT: fcvt h0, s0 1463; CHECK-CVT-GI-NEXT: ret 1464 %r = call half @llvm.maxnum.f16(half %a, half %b) 1465 ret half %r 1466} 1467 1468define half @test_copysign(half %a, half %b) #0 { 1469; CHECK-CVT-SD-LABEL: test_copysign: 1470; CHECK-CVT-SD: // %bb.0: 1471; CHECK-CVT-SD-NEXT: fcvt s1, h1 1472; CHECK-CVT-SD-NEXT: fcvt s0, h0 1473; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24 1474; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1475; CHECK-CVT-SD-NEXT: fcvt h0, s0 1476; CHECK-CVT-SD-NEXT: ret 1477; 1478; CHECK-FP16-SD-LABEL: test_copysign: 1479; CHECK-FP16-SD: // %bb.0: 1480; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8 1481; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0 1482; CHECK-FP16-SD-NEXT: // kill: def $h1 killed $h1 def $q1 1483; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1484; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 killed $q0 1485; CHECK-FP16-SD-NEXT: ret 1486; 1487; CHECK-CVT-GI-LABEL: test_copysign: 1488; CHECK-CVT-GI: // %bb.0: 1489; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8 1490; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1491; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $d1 1492; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1493; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $d0 1494; CHECK-CVT-GI-NEXT: ret 1495; 1496; CHECK-FP16-GI-LABEL: test_copysign: 1497; CHECK-FP16-GI: // %bb.0: 1498; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8 1499; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1500; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $d1 1501; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1502; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $d0 1503; CHECK-FP16-GI-NEXT: ret 1504 %r = call half @llvm.copysign.f16(half %a, half %b) 1505 ret half %r 1506} 1507 1508define half @test_copysign_f32(half %a, float %b) #0 { 1509; CHECK-CVT-SD-LABEL: test_copysign_f32: 1510; CHECK-CVT-SD: // %bb.0: 1511; CHECK-CVT-SD-NEXT: fcvt s0, h0 1512; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24 1513; CHECK-CVT-SD-NEXT: // kill: def $s1 killed $s1 def $q1 1514; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1515; CHECK-CVT-SD-NEXT: fcvt h0, s0 1516; CHECK-CVT-SD-NEXT: ret 1517; 1518; CHECK-FP16-SD-LABEL: test_copysign_f32: 1519; CHECK-FP16-SD: // %bb.0: 1520; CHECK-FP16-SD-NEXT: fcvt h1, s1 1521; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8 1522; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0 1523; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1524; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 killed $q0 1525; CHECK-FP16-SD-NEXT: ret 1526; 1527; CHECK-CVT-GI-LABEL: test_copysign_f32: 1528; CHECK-CVT-GI: // %bb.0: 1529; CHECK-CVT-GI-NEXT: fcvt h1, s1 1530; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8 1531; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1532; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1533; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $d0 1534; CHECK-CVT-GI-NEXT: ret 1535; 1536; CHECK-FP16-GI-LABEL: test_copysign_f32: 1537; CHECK-FP16-GI: // %bb.0: 1538; CHECK-FP16-GI-NEXT: fcvt h1, s1 1539; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8 1540; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1541; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1542; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $d0 1543; CHECK-FP16-GI-NEXT: ret 1544 %tb = fptrunc float %b to half 1545 %r = call half @llvm.copysign.f16(half %a, half %tb) 1546 ret half %r 1547} 1548 1549define half @test_copysign_f64(half %a, double %b) #0 { 1550; CHECK-CVT-SD-LABEL: test_copysign_f64: 1551; CHECK-CVT-SD: // %bb.0: 1552; CHECK-CVT-SD-NEXT: fcvt s1, d1 1553; CHECK-CVT-SD-NEXT: fcvt s0, h0 1554; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24 1555; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1556; CHECK-CVT-SD-NEXT: fcvt h0, s0 1557; CHECK-CVT-SD-NEXT: ret 1558; 1559; CHECK-FP16-SD-LABEL: test_copysign_f64: 1560; CHECK-FP16-SD: // %bb.0: 1561; CHECK-FP16-SD-NEXT: fcvt h1, d1 1562; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8 1563; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0 1564; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1565; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 killed $q0 1566; CHECK-FP16-SD-NEXT: ret 1567; 1568; CHECK-CVT-GI-LABEL: test_copysign_f64: 1569; CHECK-CVT-GI: // %bb.0: 1570; CHECK-CVT-GI-NEXT: fcvt h1, d1 1571; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8 1572; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1573; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1574; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $d0 1575; CHECK-CVT-GI-NEXT: ret 1576; 1577; CHECK-FP16-GI-LABEL: test_copysign_f64: 1578; CHECK-FP16-GI: // %bb.0: 1579; CHECK-FP16-GI-NEXT: fcvt h1, d1 1580; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8 1581; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1582; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1583; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $d0 1584; CHECK-FP16-GI-NEXT: ret 1585 %tb = fptrunc double %b to half 1586 %r = call half @llvm.copysign.f16(half %a, half %tb) 1587 ret half %r 1588} 1589 1590; Check that the FP promotion will use a truncating FP_ROUND, so we can fold 1591; away the (fpext (fp_round <result>)) here. 1592 1593define float @test_copysign_extended(half %a, half %b) #0 { 1594; CHECK-CVT-SD-LABEL: test_copysign_extended: 1595; CHECK-CVT-SD: // %bb.0: 1596; CHECK-CVT-SD-NEXT: fcvt s1, h1 1597; CHECK-CVT-SD-NEXT: fcvt s0, h0 1598; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24 1599; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1600; CHECK-CVT-SD-NEXT: // kill: def $s0 killed $s0 killed $q0 1601; CHECK-CVT-SD-NEXT: ret 1602; 1603; CHECK-FP16-SD-LABEL: test_copysign_extended: 1604; CHECK-FP16-SD: // %bb.0: 1605; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8 1606; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0 1607; CHECK-FP16-SD-NEXT: // kill: def $h1 killed $h1 def $q1 1608; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b 1609; CHECK-FP16-SD-NEXT: fcvt s0, h0 1610; CHECK-FP16-SD-NEXT: ret 1611; 1612; CHECK-CVT-GI-LABEL: test_copysign_extended: 1613; CHECK-CVT-GI: // %bb.0: 1614; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8 1615; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1616; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $d1 1617; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1618; CHECK-CVT-GI-NEXT: fcvt s0, h0 1619; CHECK-CVT-GI-NEXT: ret 1620; 1621; CHECK-FP16-GI-LABEL: test_copysign_extended: 1622; CHECK-FP16-GI: // %bb.0: 1623; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8 1624; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0 1625; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $d1 1626; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b 1627; CHECK-FP16-GI-NEXT: fcvt s0, h0 1628; CHECK-FP16-GI-NEXT: ret 1629 %r = call half @llvm.copysign.f16(half %a, half %b) 1630 %xr = fpext half %r to float 1631 ret float %xr 1632} 1633 1634define half @test_floor(half %a) #0 { 1635; CHECK-CVT-LABEL: test_floor: 1636; CHECK-CVT: // %bb.0: 1637; CHECK-CVT-NEXT: fcvt s0, h0 1638; CHECK-CVT-NEXT: frintm s0, s0 1639; CHECK-CVT-NEXT: fcvt h0, s0 1640; CHECK-CVT-NEXT: ret 1641; 1642; CHECK-FP16-LABEL: test_floor: 1643; CHECK-FP16: // %bb.0: 1644; CHECK-FP16-NEXT: frintm h0, h0 1645; CHECK-FP16-NEXT: ret 1646 %r = call half @llvm.floor.f16(half %a) 1647 ret half %r 1648} 1649 1650define half @test_ceil(half %a) #0 { 1651; CHECK-CVT-LABEL: test_ceil: 1652; CHECK-CVT: // %bb.0: 1653; CHECK-CVT-NEXT: fcvt s0, h0 1654; CHECK-CVT-NEXT: frintp s0, s0 1655; CHECK-CVT-NEXT: fcvt h0, s0 1656; CHECK-CVT-NEXT: ret 1657; 1658; CHECK-FP16-LABEL: test_ceil: 1659; CHECK-FP16: // %bb.0: 1660; CHECK-FP16-NEXT: frintp h0, h0 1661; CHECK-FP16-NEXT: ret 1662 %r = call half @llvm.ceil.f16(half %a) 1663 ret half %r 1664} 1665 1666define half @test_trunc(half %a) #0 { 1667; CHECK-CVT-LABEL: test_trunc: 1668; CHECK-CVT: // %bb.0: 1669; CHECK-CVT-NEXT: fcvt s0, h0 1670; CHECK-CVT-NEXT: frintz s0, s0 1671; CHECK-CVT-NEXT: fcvt h0, s0 1672; CHECK-CVT-NEXT: ret 1673; 1674; CHECK-FP16-LABEL: test_trunc: 1675; CHECK-FP16: // %bb.0: 1676; CHECK-FP16-NEXT: frintz h0, h0 1677; CHECK-FP16-NEXT: ret 1678 %r = call half @llvm.trunc.f16(half %a) 1679 ret half %r 1680} 1681 1682define half @test_rint(half %a) #0 { 1683; CHECK-CVT-LABEL: test_rint: 1684; CHECK-CVT: // %bb.0: 1685; CHECK-CVT-NEXT: fcvt s0, h0 1686; CHECK-CVT-NEXT: frintx s0, s0 1687; CHECK-CVT-NEXT: fcvt h0, s0 1688; CHECK-CVT-NEXT: ret 1689; 1690; CHECK-FP16-LABEL: test_rint: 1691; CHECK-FP16: // %bb.0: 1692; CHECK-FP16-NEXT: frintx h0, h0 1693; CHECK-FP16-NEXT: ret 1694 %r = call half @llvm.rint.f16(half %a) 1695 ret half %r 1696} 1697 1698define half @test_nearbyint(half %a) #0 { 1699; CHECK-CVT-LABEL: test_nearbyint: 1700; CHECK-CVT: // %bb.0: 1701; CHECK-CVT-NEXT: fcvt s0, h0 1702; CHECK-CVT-NEXT: frinti s0, s0 1703; CHECK-CVT-NEXT: fcvt h0, s0 1704; CHECK-CVT-NEXT: ret 1705; 1706; CHECK-FP16-LABEL: test_nearbyint: 1707; CHECK-FP16: // %bb.0: 1708; CHECK-FP16-NEXT: frinti h0, h0 1709; CHECK-FP16-NEXT: ret 1710 %r = call half @llvm.nearbyint.f16(half %a) 1711 ret half %r 1712} 1713 1714define half @test_round(half %a) #0 { 1715; CHECK-CVT-LABEL: test_round: 1716; CHECK-CVT: // %bb.0: 1717; CHECK-CVT-NEXT: fcvt s0, h0 1718; CHECK-CVT-NEXT: frinta s0, s0 1719; CHECK-CVT-NEXT: fcvt h0, s0 1720; CHECK-CVT-NEXT: ret 1721; 1722; CHECK-FP16-LABEL: test_round: 1723; CHECK-FP16: // %bb.0: 1724; CHECK-FP16-NEXT: frinta h0, h0 1725; CHECK-FP16-NEXT: ret 1726 %r = call half @llvm.round.f16(half %a) 1727 ret half %r 1728} 1729 1730define half @test_roundeven(half %a) #0 { 1731; CHECK-CVT-LABEL: test_roundeven: 1732; CHECK-CVT: // %bb.0: 1733; CHECK-CVT-NEXT: fcvt s0, h0 1734; CHECK-CVT-NEXT: frintn s0, s0 1735; CHECK-CVT-NEXT: fcvt h0, s0 1736; CHECK-CVT-NEXT: ret 1737; 1738; CHECK-FP16-LABEL: test_roundeven: 1739; CHECK-FP16: // %bb.0: 1740; CHECK-FP16-NEXT: frintn h0, h0 1741; CHECK-FP16-NEXT: ret 1742 %r = call half @llvm.roundeven.f16(half %a) 1743 ret half %r 1744} 1745 1746define half @test_fmuladd(half %a, half %b, half %c) #0 { 1747; CHECK-CVT-SD-LABEL: test_fmuladd: 1748; CHECK-CVT-SD: // %bb.0: 1749; CHECK-CVT-SD-NEXT: fcvt s1, h1 1750; CHECK-CVT-SD-NEXT: fcvt s0, h0 1751; CHECK-CVT-SD-NEXT: fmul s0, s0, s1 1752; CHECK-CVT-SD-NEXT: fcvt s1, h2 1753; CHECK-CVT-SD-NEXT: fcvt h0, s0 1754; CHECK-CVT-SD-NEXT: fcvt s0, h0 1755; CHECK-CVT-SD-NEXT: fadd s0, s0, s1 1756; CHECK-CVT-SD-NEXT: fcvt h0, s0 1757; CHECK-CVT-SD-NEXT: ret 1758; 1759; CHECK-FP16-LABEL: test_fmuladd: 1760; CHECK-FP16: // %bb.0: 1761; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2 1762; CHECK-FP16-NEXT: ret 1763; 1764; CHECK-CVT-GI-LABEL: test_fmuladd: 1765; CHECK-CVT-GI: // %bb.0: 1766; CHECK-CVT-GI-NEXT: fcvt s0, h0 1767; CHECK-CVT-GI-NEXT: fcvt s1, h1 1768; CHECK-CVT-GI-NEXT: fmul s0, s0, s1 1769; CHECK-CVT-GI-NEXT: fcvt s1, h2 1770; CHECK-CVT-GI-NEXT: fcvt h0, s0 1771; CHECK-CVT-GI-NEXT: fcvt s0, h0 1772; CHECK-CVT-GI-NEXT: fadd s0, s0, s1 1773; CHECK-CVT-GI-NEXT: fcvt h0, s0 1774; CHECK-CVT-GI-NEXT: ret 1775 %r = call half @llvm.fmuladd.f16(half %a, half %b, half %c) 1776 ret half %r 1777} 1778 1779attributes #0 = { nounwind } 1780