1; RUN: llc < %s -mtriple=aarch64-eabi -mattr=+v8.2a,+fullfp16 | FileCheck %s 2 3declare half @llvm.aarch64.sisd.fabd.f16(half, half) 4declare half @llvm.aarch64.neon.fmax.f16(half, half) 5declare half @llvm.aarch64.neon.fmin.f16(half, half) 6declare half @llvm.aarch64.neon.frsqrts.f16(half, half) 7declare half @llvm.aarch64.neon.frecps.f16(half, half) 8declare half @llvm.aarch64.neon.fmulx.f16(half, half) 9declare half @llvm.fabs.f16(half) 10declare i32 @llvm.aarch64.neon.facge.i32.f16(half, half) 11declare i32 @llvm.aarch64.neon.facgt.i32.f16(half, half) 12 13define dso_local half @t_vabdh_f16(half %a, half %b) { 14; CHECK-LABEL: t_vabdh_f16: 15; CHECK: fabd h0, h0, h1 16; CHECK-NEXT: ret 17entry: 18 %vabdh_f16 = tail call half @llvm.aarch64.sisd.fabd.f16(half %a, half %b) 19 ret half %vabdh_f16 20} 21 22define dso_local half @t_vabdh_f16_from_fsub_fabs(half %a, half %b) { 23; CHECK-LABEL: t_vabdh_f16_from_fsub_fabs: 24; CHECK: fabd h0, h0, h1 25; CHECK-NEXT: ret 26entry: 27 %sub = fsub half %a, %b 28 %abs = tail call half @llvm.fabs.f16(half %sub) 29 ret half %abs 30} 31 32define dso_local i16 @t_vceqh_f16(half %a, half %b) { 33; CHECK-LABEL: t_vceqh_f16: 34; CHECK: fcmp h0, h1 35; CHECK-NEXT: csetm w0, eq 36; CHECK-NEXT: ret 37entry: 38 %0 = fcmp oeq half %a, %b 39 %vcmpd = sext i1 %0 to i16 40 ret i16 %vcmpd 41} 42 43define dso_local i16 @t_vcgeh_f16(half %a, half %b) { 44; CHECK-LABEL: t_vcgeh_f16: 45; CHECK: fcmp h0, h1 46; CHECK-NEXT: csetm w0, ge 47; CHECK-NEXT: ret 48entry: 49 %0 = fcmp oge half %a, %b 50 %vcmpd = sext i1 %0 to i16 51 ret i16 %vcmpd 52} 53 54define dso_local i16 @t_vcgth_f16(half %a, half %b) { 55; CHECK-LABEL: t_vcgth_f16: 56; CHECK: fcmp h0, h1 57; CHECK-NEXT: csetm w0, gt 58; CHECK-NEXT: ret 59entry: 60 %0 = fcmp ogt half %a, %b 61 %vcmpd = sext i1 %0 to i16 62 ret i16 %vcmpd 63} 64 65define dso_local i16 @t_vcleh_f16(half %a, half %b) { 66; CHECK-LABEL: t_vcleh_f16: 67; CHECK: fcmp h0, h1 68; CHECK-NEXT: csetm w0, ls 69; CHECK-NEXT: ret 70entry: 71 %0 = fcmp ole half %a, %b 72 %vcmpd = sext i1 %0 to i16 73 ret i16 %vcmpd 74} 75 76define dso_local i16 @t_vclth_f16(half %a, half %b) { 77; CHECK-LABEL: t_vclth_f16: 78; CHECK: fcmp h0, h1 79; CHECK-NEXT: csetm w0, mi 80; CHECK-NEXT: ret 81entry: 82 %0 = fcmp olt half %a, %b 83 %vcmpd = sext i1 %0 to i16 84 ret i16 %vcmpd 85} 86 87define dso_local half @t_vmaxh_f16(half %a, half %b) { 88; CHECK-LABEL: t_vmaxh_f16: 89; CHECK: fmax h0, h0, h1 90; CHECK-NEXT: ret 91entry: 92 %vmax = tail call half @llvm.aarch64.neon.fmax.f16(half %a, half %b) 93 ret half %vmax 94} 95 96define dso_local half @t_vminh_f16(half %a, half %b) { 97; CHECK-LABEL: t_vminh_f16: 98; CHECK: fmin h0, h0, h1 99; CHECK-NEXT: ret 100entry: 101 %vmin = tail call half @llvm.aarch64.neon.fmin.f16(half %a, half %b) 102 ret half %vmin 103} 104 105define dso_local half @t_vmulxh_f16(half %a, half %b) { 106; CHECK-LABEL: t_vmulxh_f16: 107; CHECK: fmulx h0, h0, h1 108; CHECK-NEXT: ret 109entry: 110 %vmulxh_f16 = tail call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b) 111 ret half %vmulxh_f16 112} 113 114define dso_local half @t_vrecpsh_f16(half %a, half %b) { 115; CHECK-LABEL: t_vrecpsh_f16: 116; CHECK: frecps h0, h0, h1 117; CHECK-NEXT: ret 118entry: 119 %vrecps = tail call half @llvm.aarch64.neon.frecps.f16(half %a, half %b) 120 ret half %vrecps 121} 122 123define dso_local half @t_vrsqrtsh_f16(half %a, half %b) { 124; CHECK-LABEL: t_vrsqrtsh_f16: 125; CHECK: frsqrts h0, h0, h1 126; CHECK-NEXT: ret 127entry: 128 %vrsqrtsh_f16 = tail call half @llvm.aarch64.neon.frsqrts.f16(half %a, half %b) 129 ret half %vrsqrtsh_f16 130} 131 132declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32, i32) #1 133declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64, i32) #1 134declare i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half, i32) #1 135declare i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half, i32) #1 136declare half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32, i32) #1 137declare i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half, i32) #1 138 139define dso_local half @test_vcvth_n_f16_s16_1(i16 %a) { 140; CHECK-LABEL: test_vcvth_n_f16_s16_1: 141; CHECK: fmov s0, w[[wReg:[0-9]+]] 142; CHECK-NEXT: scvtf h0, h0, #1 143; CHECK-NEXT: ret 144entry: 145 %sext = sext i16 %a to i32 146 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 1) 147 ret half %fcvth_n 148} 149 150define dso_local half @test_vcvth_n_f16_s16_16(i16 %a) { 151; CHECK-LABEL: test_vcvth_n_f16_s16_16: 152; CHECK: fmov s0, w[[wReg:[0-9]+]] 153; CHECK-NEXT: scvtf h0, h0, #16 154; CHECK-NEXT: ret 155entry: 156 %sext = sext i16 %a to i32 157 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 16) 158 ret half %fcvth_n 159} 160 161define dso_local half @test_vcvth_n_f16_s32_1(i32 %a) { 162; CHECK-LABEL: test_vcvth_n_f16_s32_1: 163; CHECK: fmov s0, w0 164; CHECK-NEXT: scvtf h0, h0, #1 165; CHECK-NEXT: ret 166entry: 167 %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 1) 168 ret half %vcvth_n_f16_s32 169} 170 171define dso_local half @test_vcvth_n_f16_s32_16(i32 %a) { 172; CHECK-LABEL: test_vcvth_n_f16_s32_16: 173; CHECK: fmov s0, w0 174; CHECK-NEXT: scvtf h0, h0, #16 175; CHECK-NEXT: ret 176entry: 177 %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 16) 178 ret half %vcvth_n_f16_s32 179} 180 181define dso_local i16 @test_vcvth_n_s16_f16_1(half %a) { 182; CHECK-LABEL: test_vcvth_n_s16_f16_1: 183; CHECK: fcvtzs h0, h0, #1 184; CHECK-NEXT: fmov w0, s0 185; CHECK-NEXT: ret 186entry: 187 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1) 188 %0 = trunc i32 %fcvth_n to i16 189 ret i16 %0 190} 191 192define dso_local i16 @test_vcvth_n_s16_f16_16(half %a) { 193; CHECK-LABEL: test_vcvth_n_s16_f16_16: 194; CHECK: fcvtzs h0, h0, #16 195; CHECK-NEXT: fmov w0, s0 196; CHECK-NEXT: ret 197entry: 198 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16) 199 %0 = trunc i32 %fcvth_n to i16 200 ret i16 %0 201} 202 203define dso_local i32 @test_vcvth_n_s32_f16_1(half %a) { 204; CHECK-LABEL: test_vcvth_n_s32_f16_1: 205; CHECK: fcvtzs h0, h0, #1 206; CHECK-NEXT: fmov w0, s0 207; CHECK-NEXT: ret 208entry: 209 %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1) 210 ret i32 %vcvth_n_s32_f16 211} 212 213define dso_local i32 @test_vcvth_n_s32_f16_16(half %a) { 214; CHECK-LABEL: test_vcvth_n_s32_f16_16: 215; CHECK: fcvtzs h0, h0, #16 216; CHECK-NEXT: fmov w0, s0 217; CHECK-NEXT: ret 218entry: 219 %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16) 220 ret i32 %vcvth_n_s32_f16 221} 222 223define dso_local i64 @test_vcvth_n_s64_f16_1(half %a) { 224; CHECK-LABEL: test_vcvth_n_s64_f16_1: 225; CHECK: fcvtzs h0, h0, #1 226; CHECK-NEXT: fmov x0, d0 227; CHECK-NEXT: ret 228entry: 229 %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 1) 230 ret i64 %vcvth_n_s64_f16 231} 232 233define dso_local i64 @test_vcvth_n_s64_f16_32(half %a) { 234; CHECK-LABEL: test_vcvth_n_s64_f16_32: 235; CHECK: fcvtzs h0, h0, #32 236; CHECK-NEXT: fmov x0, d0 237; CHECK-NEXT: ret 238entry: 239 %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 32) 240 ret i64 %vcvth_n_s64_f16 241} 242 243define dso_local half @test_vcvth_n_f16_u16_1(i16 %a) { 244; CHECK-LABEL: test_vcvth_n_f16_u16_1: 245; CHECK: ucvtf h0, h0, #1 246; CHECK-NEXT: ret 247entry: 248 %0 = zext i16 %a to i32 249 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 1) 250 ret half %fcvth_n 251} 252 253define dso_local half @test_vcvth_n_f16_u16_16(i16 %a) { 254; CHECK-LABEL: test_vcvth_n_f16_u16_16: 255; CHECK: ucvtf h0, h0, #16 256; CHECK-NEXT: ret 257entry: 258 %0 = zext i16 %a to i32 259 %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 16) 260 ret half %fcvth_n 261} 262 263define dso_local half @test_vcvth_n_f16_u32_1(i32 %a) { 264; CHECK-LABEL: test_vcvth_n_f16_u32_1: 265; CHECK: fmov s0, w0 266; CHECK-NEXT: ucvtf h0, h0, #1 267; CHECK-NEXT: ret 268entry: 269 %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 1) 270 ret half %vcvth_n_f16_u32 271} 272 273define dso_local half @test_vcvth_n_f16_u32_16(i32 %a) { 274; CHECK-LABEL: test_vcvth_n_f16_u32_16: 275; CHECK: ucvtf h0, h0, #16 276; CHECK-NEXT: ret 277entry: 278 %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 16) 279 ret half %vcvth_n_f16_u32 280} 281 282define dso_local i16 @test_vcvth_n_u16_f16_1(half %a) { 283; CHECK-LABEL: test_vcvth_n_u16_f16_1: 284; CHECK: fcvtzu h0, h0, #1 285; CHECK-NEXT: fmov w0, s0 286; CHECK-NEXT: ret 287entry: 288 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1) 289 %0 = trunc i32 %fcvth_n to i16 290 ret i16 %0 291} 292 293define dso_local i16 @test_vcvth_n_u16_f16_16(half %a) { 294; CHECK-LABEL: test_vcvth_n_u16_f16_16: 295; CHECK: fcvtzu h0, h0, #16 296; CHECK-NEXT: fmov w0, s0 297; CHECK-NEXT: ret 298entry: 299 %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16) 300 %0 = trunc i32 %fcvth_n to i16 301 ret i16 %0 302} 303 304define dso_local i32 @test_vcvth_n_u32_f16_1(half %a) { 305; CHECK-LABEL: test_vcvth_n_u32_f16_1: 306; CHECK: fcvtzu h0, h0, #1 307; CHECK-NEXT: fmov w0, s0 308; CHECK-NEXT: ret 309entry: 310 %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1) 311 ret i32 %vcvth_n_u32_f16 312} 313 314define dso_local i32 @test_vcvth_n_u32_f16_16(half %a) { 315; CHECK-LABEL: test_vcvth_n_u32_f16_16: 316; CHECK: fcvtzu h0, h0, #16 317; CHECK-NEXT: fmov w0, s0 318; CHECK-NEXT: ret 319entry: 320 %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16) 321 ret i32 %vcvth_n_u32_f16 322} 323 324define dso_local i16 @vcageh_f16_test(half %a, half %b) { 325; CHECK-LABEL: vcageh_f16_test: 326; CHECK: facge h0, h0, h1 327; CHECK-NEXT: fmov w0, s0 328; CHECK-NEXT: ret 329entry: 330 %facg = tail call i32 @llvm.aarch64.neon.facge.i32.f16(half %a, half %b) 331 %0 = trunc i32 %facg to i16 332 ret i16 %0 333} 334 335define dso_local i16 @vcagth_f16_test(half %a, half %b) { 336; CHECK-LABEL: vcagth_f16_test: 337; CHECK: facgt h0, h0, h1 338; CHECK-NEXT: fmov w0, s0 339; CHECK-NEXT: ret 340entry: 341 %facg = tail call i32 @llvm.aarch64.neon.facgt.i32.f16(half %a, half %b) 342 %0 = trunc i32 %facg to i16 343 ret i16 %0 344} 345 346define dso_local half @vcvth_n_f16_s64_test(i64 %a) { 347; CHECK-LABEL: vcvth_n_f16_s64_test: 348; CHECK: fmov d0, x0 349; CHECK-NEXT: scvtf h0, h0, #16 350; CHECK-NEXT: ret 351entry: 352 %vcvth_n_f16_s64 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64 %a, i32 16) 353 ret half %vcvth_n_f16_s64 354} 355