1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx,+f16c -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX 3; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2,+f16c -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX 4; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2,+f16c,+fast-variable-crosslane-shuffle,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX 5; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx2,+f16c,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX 6; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx512f -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX512 7; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512vl,+fast-variable-crosslane-shuffle,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX512 8; RUN: llc < %s -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512vl,+fast-variable-perlane-shuffle -verify-machineinstrs | FileCheck %s --check-prefixes=ALL,AVX512 9 10; 11; Half to Float 12; 13 14define float @cvt_i16_to_f32(i16 %a0) nounwind { 15; ALL-LABEL: cvt_i16_to_f32: 16; ALL: # %bb.0: 17; ALL-NEXT: movzwl %di, %eax 18; ALL-NEXT: vmovd %eax, %xmm0 19; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 20; ALL-NEXT: retq 21 %1 = bitcast i16 %a0 to half 22 %2 = fpext half %1 to float 23 ret float %2 24} 25 26define <4 x float> @cvt_4i16_to_4f32(<4 x i16> %a0) nounwind { 27; ALL-LABEL: cvt_4i16_to_4f32: 28; ALL: # %bb.0: 29; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 30; ALL-NEXT: retq 31 %1 = bitcast <4 x i16> %a0 to <4 x half> 32 %2 = fpext <4 x half> %1 to <4 x float> 33 ret <4 x float> %2 34} 35 36define <4 x float> @cvt_8i16_to_4f32(<8 x i16> %a0) nounwind { 37; ALL-LABEL: cvt_8i16_to_4f32: 38; ALL: # %bb.0: 39; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 40; ALL-NEXT: retq 41 %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 42 %2 = bitcast <4 x i16> %1 to <4 x half> 43 %3 = fpext <4 x half> %2 to <4 x float> 44 ret <4 x float> %3 45} 46 47define <8 x float> @cvt_8i16_to_8f32(<8 x i16> %a0) nounwind { 48; ALL-LABEL: cvt_8i16_to_8f32: 49; ALL: # %bb.0: 50; ALL-NEXT: vcvtph2ps %xmm0, %ymm0 51; ALL-NEXT: retq 52 %1 = bitcast <8 x i16> %a0 to <8 x half> 53 %2 = fpext <8 x half> %1 to <8 x float> 54 ret <8 x float> %2 55} 56 57define <16 x float> @cvt_16i16_to_16f32(<16 x i16> %a0) nounwind { 58; AVX-LABEL: cvt_16i16_to_16f32: 59; AVX: # %bb.0: 60; AVX-NEXT: vcvtph2ps %xmm0, %ymm2 61; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 62; AVX-NEXT: vcvtph2ps %xmm0, %ymm1 63; AVX-NEXT: vmovaps %ymm2, %ymm0 64; AVX-NEXT: retq 65; 66; AVX512-LABEL: cvt_16i16_to_16f32: 67; AVX512: # %bb.0: 68; AVX512-NEXT: vcvtph2ps %ymm0, %zmm0 69; AVX512-NEXT: retq 70 %1 = bitcast <16 x i16> %a0 to <16 x half> 71 %2 = fpext <16 x half> %1 to <16 x float> 72 ret <16 x float> %2 73} 74 75define <2 x float> @cvt_2i16_to_2f32_constrained(<2 x i16> %a0) nounwind strictfp { 76; ALL-LABEL: cvt_2i16_to_2f32_constrained: 77; ALL: # %bb.0: 78; ALL-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero 79; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 80; ALL-NEXT: retq 81 %1 = bitcast <2 x i16> %a0 to <2 x half> 82 %2 = call <2 x float> @llvm.experimental.constrained.fpext.v2f32.v2f16(<2 x half> %1, metadata !"fpexcept.strict") strictfp 83 ret <2 x float> %2 84} 85declare <2 x float> @llvm.experimental.constrained.fpext.v2f32.v2f16(<2 x half>, metadata) strictfp 86 87define <4 x float> @cvt_4i16_to_4f32_constrained(<4 x i16> %a0) nounwind strictfp { 88; ALL-LABEL: cvt_4i16_to_4f32_constrained: 89; ALL: # %bb.0: 90; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 91; ALL-NEXT: retq 92 %1 = bitcast <4 x i16> %a0 to <4 x half> 93 %2 = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %1, metadata !"fpexcept.strict") strictfp 94 ret <4 x float> %2 95} 96declare <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half>, metadata) strictfp 97 98define <8 x float> @cvt_8i16_to_8f32_constrained(<8 x i16> %a0) nounwind strictfp { 99; ALL-LABEL: cvt_8i16_to_8f32_constrained: 100; ALL: # %bb.0: 101; ALL-NEXT: vcvtph2ps %xmm0, %ymm0 102; ALL-NEXT: retq 103 %1 = bitcast <8 x i16> %a0 to <8 x half> 104 %2 = call <8 x float> @llvm.experimental.constrained.fpext.v8f32.v8f16(<8 x half> %1, metadata !"fpexcept.strict") strictfp 105 ret <8 x float> %2 106} 107declare <8 x float> @llvm.experimental.constrained.fpext.v8f32.v8f16(<8 x half>, metadata) strictfp 108 109define <16 x float> @cvt_16i16_to_16f32_constrained(<16 x i16> %a0) nounwind strictfp { 110; AVX-LABEL: cvt_16i16_to_16f32_constrained: 111; AVX: # %bb.0: 112; AVX-NEXT: vextractf128 $1, %ymm0, %xmm1 113; AVX-NEXT: vcvtph2ps %xmm1, %ymm1 114; AVX-NEXT: vcvtph2ps %xmm0, %ymm0 115; AVX-NEXT: retq 116; 117; AVX512-LABEL: cvt_16i16_to_16f32_constrained: 118; AVX512: # %bb.0: 119; AVX512-NEXT: vcvtph2ps %ymm0, %zmm0 120; AVX512-NEXT: retq 121 %1 = bitcast <16 x i16> %a0 to <16 x half> 122 %2 = call <16 x float> @llvm.experimental.constrained.fpext.v16f32.v16f16(<16 x half> %1, metadata !"fpexcept.strict") strictfp 123 ret <16 x float> %2 124} 125declare <16 x float> @llvm.experimental.constrained.fpext.v16f32.v16f16(<16 x half>, metadata) strictfp 126 127; 128; Half to Float (Load) 129; 130 131define float @load_cvt_i16_to_f32(ptr %a0) nounwind { 132; ALL-LABEL: load_cvt_i16_to_f32: 133; ALL: # %bb.0: 134; ALL-NEXT: movzwl (%rdi), %eax 135; ALL-NEXT: vmovd %eax, %xmm0 136; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 137; ALL-NEXT: retq 138 %1 = load i16, ptr %a0 139 %2 = bitcast i16 %1 to half 140 %3 = fpext half %2 to float 141 ret float %3 142} 143 144define <4 x float> @load_cvt_4i16_to_4f32(ptr %a0) nounwind { 145; ALL-LABEL: load_cvt_4i16_to_4f32: 146; ALL: # %bb.0: 147; ALL-NEXT: vcvtph2ps (%rdi), %xmm0 148; ALL-NEXT: retq 149 %1 = load <4 x i16>, ptr %a0 150 %2 = bitcast <4 x i16> %1 to <4 x half> 151 %3 = fpext <4 x half> %2 to <4 x float> 152 ret <4 x float> %3 153} 154 155define <4 x float> @load_cvt_8i16_to_4f32(ptr %a0) nounwind { 156; ALL-LABEL: load_cvt_8i16_to_4f32: 157; ALL: # %bb.0: 158; ALL-NEXT: vcvtph2ps (%rdi), %xmm0 159; ALL-NEXT: retq 160 %1 = load <8 x i16>, ptr %a0 161 %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 162 %3 = bitcast <4 x i16> %2 to <4 x half> 163 %4 = fpext <4 x half> %3 to <4 x float> 164 ret <4 x float> %4 165} 166 167define <8 x float> @load_cvt_8i16_to_8f32(ptr %a0) nounwind { 168; ALL-LABEL: load_cvt_8i16_to_8f32: 169; ALL: # %bb.0: 170; ALL-NEXT: vcvtph2ps (%rdi), %ymm0 171; ALL-NEXT: retq 172 %1 = load <8 x i16>, ptr %a0 173 %2 = bitcast <8 x i16> %1 to <8 x half> 174 %3 = fpext <8 x half> %2 to <8 x float> 175 ret <8 x float> %3 176} 177 178define <16 x float> @load_cvt_16i16_to_16f32(ptr %a0) nounwind { 179; AVX-LABEL: load_cvt_16i16_to_16f32: 180; AVX: # %bb.0: 181; AVX-NEXT: vcvtph2ps (%rdi), %ymm0 182; AVX-NEXT: vcvtph2ps 16(%rdi), %ymm1 183; AVX-NEXT: retq 184; 185; AVX512-LABEL: load_cvt_16i16_to_16f32: 186; AVX512: # %bb.0: 187; AVX512-NEXT: vcvtph2ps (%rdi), %zmm0 188; AVX512-NEXT: retq 189 %1 = load <16 x i16>, ptr %a0 190 %2 = bitcast <16 x i16> %1 to <16 x half> 191 %3 = fpext <16 x half> %2 to <16 x float> 192 ret <16 x float> %3 193} 194 195define <4 x float> @load_cvt_4i16_to_4f32_constrained(ptr %a0) nounwind strictfp { 196; ALL-LABEL: load_cvt_4i16_to_4f32_constrained: 197; ALL: # %bb.0: 198; ALL-NEXT: vcvtph2ps (%rdi), %xmm0 199; ALL-NEXT: retq 200 %1 = load <4 x i16>, ptr %a0 201 %2 = bitcast <4 x i16> %1 to <4 x half> 202 %3 = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %2, metadata !"fpexcept.strict") strictfp 203 ret <4 x float> %3 204} 205 206define <4 x float> @load_cvt_8i16_to_4f32_constrained(ptr %a0) nounwind strictfp { 207; ALL-LABEL: load_cvt_8i16_to_4f32_constrained: 208; ALL: # %bb.0: 209; ALL-NEXT: vcvtph2ps (%rdi), %xmm0 210; ALL-NEXT: retq 211 %1 = load <8 x i16>, ptr %a0 212 %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 213 %3 = bitcast <4 x i16> %2 to <4 x half> 214 %4 = call <4 x float> @llvm.experimental.constrained.fpext.v4f32.v4f16(<4 x half> %3, metadata !"fpexcept.strict") strictfp 215 ret <4 x float> %4 216} 217 218; 219; Half to Double 220; 221 222define double @cvt_i16_to_f64(i16 %a0) nounwind { 223; ALL-LABEL: cvt_i16_to_f64: 224; ALL: # %bb.0: 225; ALL-NEXT: movzwl %di, %eax 226; ALL-NEXT: vmovd %eax, %xmm0 227; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 228; ALL-NEXT: vcvtss2sd %xmm0, %xmm0, %xmm0 229; ALL-NEXT: retq 230 %1 = bitcast i16 %a0 to half 231 %2 = fpext half %1 to double 232 ret double %2 233} 234 235define <2 x double> @cvt_2i16_to_2f64(<2 x i16> %a0) nounwind { 236; ALL-LABEL: cvt_2i16_to_2f64: 237; ALL: # %bb.0: 238; ALL-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero 239; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 240; ALL-NEXT: vcvtps2pd %xmm0, %xmm0 241; ALL-NEXT: retq 242 %1 = bitcast <2 x i16> %a0 to <2 x half> 243 %2 = fpext <2 x half> %1 to <2 x double> 244 ret <2 x double> %2 245} 246 247define <4 x double> @cvt_4i16_to_4f64(<4 x i16> %a0) nounwind { 248; ALL-LABEL: cvt_4i16_to_4f64: 249; ALL: # %bb.0: 250; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 251; ALL-NEXT: vcvtps2pd %xmm0, %ymm0 252; ALL-NEXT: retq 253 %1 = bitcast <4 x i16> %a0 to <4 x half> 254 %2 = fpext <4 x half> %1 to <4 x double> 255 ret <4 x double> %2 256} 257 258define <2 x double> @cvt_8i16_to_2f64(<8 x i16> %a0) nounwind { 259; ALL-LABEL: cvt_8i16_to_2f64: 260; ALL: # %bb.0: 261; ALL-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero 262; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 263; ALL-NEXT: vcvtps2pd %xmm0, %xmm0 264; ALL-NEXT: retq 265 %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <2 x i32> <i32 0, i32 1> 266 %2 = bitcast <2 x i16> %1 to <2 x half> 267 %3 = fpext <2 x half> %2 to <2 x double> 268 ret <2 x double> %3 269} 270 271define <4 x double> @cvt_8i16_to_4f64(<8 x i16> %a0) nounwind { 272; ALL-LABEL: cvt_8i16_to_4f64: 273; ALL: # %bb.0: 274; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 275; ALL-NEXT: vcvtps2pd %xmm0, %ymm0 276; ALL-NEXT: retq 277 %1 = shufflevector <8 x i16> %a0, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 278 %2 = bitcast <4 x i16> %1 to <4 x half> 279 %3 = fpext <4 x half> %2 to <4 x double> 280 ret <4 x double> %3 281} 282 283define <8 x double> @cvt_8i16_to_8f64(<8 x i16> %a0) nounwind { 284; AVX-LABEL: cvt_8i16_to_8f64: 285; AVX: # %bb.0: 286; AVX-NEXT: vcvtph2ps %xmm0, %ymm1 287; AVX-NEXT: vcvtps2pd %xmm1, %ymm0 288; AVX-NEXT: vextractf128 $1, %ymm1, %xmm1 289; AVX-NEXT: vcvtps2pd %xmm1, %ymm1 290; AVX-NEXT: retq 291; 292; AVX512-LABEL: cvt_8i16_to_8f64: 293; AVX512: # %bb.0: 294; AVX512-NEXT: vcvtph2ps %xmm0, %ymm0 295; AVX512-NEXT: vcvtps2pd %ymm0, %zmm0 296; AVX512-NEXT: retq 297 %1 = bitcast <8 x i16> %a0 to <8 x half> 298 %2 = fpext <8 x half> %1 to <8 x double> 299 ret <8 x double> %2 300} 301 302define <2 x double> @cvt_2i16_to_2f64_constrained(<2 x i16> %a0) nounwind strictfp { 303; ALL-LABEL: cvt_2i16_to_2f64_constrained: 304; ALL: # %bb.0: 305; ALL-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero 306; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 307; ALL-NEXT: vcvtps2pd %xmm0, %xmm0 308; ALL-NEXT: retq 309 %1 = bitcast <2 x i16> %a0 to <2 x half> 310 %2 = call <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f16(<2 x half> %1, metadata !"fpexcept.strict") strictfp 311 ret <2 x double> %2 312} 313declare <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f16(<2 x half>, metadata) strictfp 314 315define <4 x double> @cvt_4i16_to_4f64_constrained(<4 x i16> %a0) nounwind strictfp { 316; ALL-LABEL: cvt_4i16_to_4f64_constrained: 317; ALL: # %bb.0: 318; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 319; ALL-NEXT: vcvtps2pd %xmm0, %ymm0 320; ALL-NEXT: retq 321 %1 = bitcast <4 x i16> %a0 to <4 x half> 322 %2 = call <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f16(<4 x half> %1, metadata !"fpexcept.strict") strictfp 323 ret <4 x double> %2 324} 325declare <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f16(<4 x half>, metadata) strictfp 326 327define <8 x double> @cvt_8i16_to_8f64_constrained(<8 x i16> %a0) nounwind strictfp { 328; AVX-LABEL: cvt_8i16_to_8f64_constrained: 329; AVX: # %bb.0: 330; AVX-NEXT: vcvtph2ps %xmm0, %ymm0 331; AVX-NEXT: vextractf128 $1, %ymm0, %xmm1 332; AVX-NEXT: vcvtps2pd %xmm1, %ymm1 333; AVX-NEXT: vcvtps2pd %xmm0, %ymm0 334; AVX-NEXT: retq 335; 336; AVX512-LABEL: cvt_8i16_to_8f64_constrained: 337; AVX512: # %bb.0: 338; AVX512-NEXT: vcvtph2ps %xmm0, %ymm0 339; AVX512-NEXT: vcvtps2pd %ymm0, %zmm0 340; AVX512-NEXT: retq 341 %1 = bitcast <8 x i16> %a0 to <8 x half> 342 %2 = call <8 x double> @llvm.experimental.constrained.fpext.v8f64.v8f16(<8 x half> %1, metadata !"fpexcept.strict") strictfp 343 ret <8 x double> %2 344} 345declare <8 x double> @llvm.experimental.constrained.fpext.v8f64.v8f16(<8 x half>, metadata) strictfp 346 347; 348; Half to Double (Load) 349; 350 351define double @load_cvt_i16_to_f64(ptr %a0) nounwind { 352; ALL-LABEL: load_cvt_i16_to_f64: 353; ALL: # %bb.0: 354; ALL-NEXT: movzwl (%rdi), %eax 355; ALL-NEXT: vmovd %eax, %xmm0 356; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 357; ALL-NEXT: vcvtss2sd %xmm0, %xmm0, %xmm0 358; ALL-NEXT: retq 359 %1 = load i16, ptr %a0 360 %2 = bitcast i16 %1 to half 361 %3 = fpext half %2 to double 362 ret double %3 363} 364 365define <2 x double> @load_cvt_2i16_to_2f64(ptr %a0) nounwind { 366; ALL-LABEL: load_cvt_2i16_to_2f64: 367; ALL: # %bb.0: 368; ALL-NEXT: vmovd {{.*#+}} xmm0 = mem[0],zero,zero,zero 369; ALL-NEXT: vpmovzxdq {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero 370; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 371; ALL-NEXT: vcvtps2pd %xmm0, %xmm0 372; ALL-NEXT: retq 373 %1 = load <2 x i16>, ptr %a0 374 %2 = bitcast <2 x i16> %1 to <2 x half> 375 %3 = fpext <2 x half> %2 to <2 x double> 376 ret <2 x double> %3 377} 378 379define <4 x double> @load_cvt_4i16_to_4f64(ptr %a0) nounwind { 380; ALL-LABEL: load_cvt_4i16_to_4f64: 381; ALL: # %bb.0: 382; ALL-NEXT: vcvtph2ps (%rdi), %xmm0 383; ALL-NEXT: vcvtps2pd %xmm0, %ymm0 384; ALL-NEXT: retq 385 %1 = load <4 x i16>, ptr %a0 386 %2 = bitcast <4 x i16> %1 to <4 x half> 387 %3 = fpext <4 x half> %2 to <4 x double> 388 ret <4 x double> %3 389} 390 391define <4 x double> @load_cvt_8i16_to_4f64(ptr %a0) nounwind { 392; ALL-LABEL: load_cvt_8i16_to_4f64: 393; ALL: # %bb.0: 394; ALL-NEXT: vcvtph2ps (%rdi), %xmm0 395; ALL-NEXT: vcvtps2pd %xmm0, %ymm0 396; ALL-NEXT: retq 397 %1 = load <8 x i16>, ptr %a0 398 %2 = shufflevector <8 x i16> %1, <8 x i16> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 399 %3 = bitcast <4 x i16> %2 to <4 x half> 400 %4 = fpext <4 x half> %3 to <4 x double> 401 ret <4 x double> %4 402} 403 404define <8 x double> @load_cvt_8i16_to_8f64(ptr %a0) nounwind { 405; AVX-LABEL: load_cvt_8i16_to_8f64: 406; AVX: # %bb.0: 407; AVX-NEXT: vcvtph2ps (%rdi), %ymm1 408; AVX-NEXT: vcvtps2pd %xmm1, %ymm0 409; AVX-NEXT: vextractf128 $1, %ymm1, %xmm1 410; AVX-NEXT: vcvtps2pd %xmm1, %ymm1 411; AVX-NEXT: retq 412; 413; AVX512-LABEL: load_cvt_8i16_to_8f64: 414; AVX512: # %bb.0: 415; AVX512-NEXT: vcvtph2ps (%rdi), %ymm0 416; AVX512-NEXT: vcvtps2pd %ymm0, %zmm0 417; AVX512-NEXT: retq 418 %1 = load <8 x i16>, ptr %a0 419 %2 = bitcast <8 x i16> %1 to <8 x half> 420 %3 = fpext <8 x half> %2 to <8 x double> 421 ret <8 x double> %3 422} 423 424; 425; Float to Half 426; 427 428define i16 @cvt_f32_to_i16(float %a0) nounwind { 429; ALL-LABEL: cvt_f32_to_i16: 430; ALL: # %bb.0: 431; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 432; ALL-NEXT: vmovd %xmm0, %eax 433; ALL-NEXT: # kill: def $ax killed $ax killed $eax 434; ALL-NEXT: retq 435 %1 = fptrunc float %a0 to half 436 %2 = bitcast half %1 to i16 437 ret i16 %2 438} 439 440define <4 x i16> @cvt_4f32_to_4i16(<4 x float> %a0) nounwind { 441; ALL-LABEL: cvt_4f32_to_4i16: 442; ALL: # %bb.0: 443; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 444; ALL-NEXT: retq 445 %1 = fptrunc <4 x float> %a0 to <4 x half> 446 %2 = bitcast <4 x half> %1 to <4 x i16> 447 ret <4 x i16> %2 448} 449 450define <8 x i16> @cvt_4f32_to_8i16_undef(<4 x float> %a0) nounwind { 451; ALL-LABEL: cvt_4f32_to_8i16_undef: 452; ALL: # %bb.0: 453; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 454; ALL-NEXT: retq 455 %1 = fptrunc <4 x float> %a0 to <4 x half> 456 %2 = bitcast <4 x half> %1 to <4 x i16> 457 %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 458 ret <8 x i16> %3 459} 460 461define <8 x i16> @cvt_4f32_to_8i16_zero(<4 x float> %a0) nounwind { 462; ALL-LABEL: cvt_4f32_to_8i16_zero: 463; ALL: # %bb.0: 464; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 465; ALL-NEXT: retq 466 %1 = fptrunc <4 x float> %a0 to <4 x half> 467 %2 = bitcast <4 x half> %1 to <4 x i16> 468 %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 469 ret <8 x i16> %3 470} 471 472define <8 x i16> @cvt_8f32_to_8i16(<8 x float> %a0) nounwind { 473; ALL-LABEL: cvt_8f32_to_8i16: 474; ALL: # %bb.0: 475; ALL-NEXT: vcvtps2ph $4, %ymm0, %xmm0 476; ALL-NEXT: vzeroupper 477; ALL-NEXT: retq 478 %1 = fptrunc <8 x float> %a0 to <8 x half> 479 %2 = bitcast <8 x half> %1 to <8 x i16> 480 ret <8 x i16> %2 481} 482 483define <16 x i16> @cvt_16f32_to_16i16(<16 x float> %a0) nounwind { 484; AVX-LABEL: cvt_16f32_to_16i16: 485; AVX: # %bb.0: 486; AVX-NEXT: vcvtps2ph $4, %ymm0, %xmm0 487; AVX-NEXT: vcvtps2ph $4, %ymm1, %xmm1 488; AVX-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 489; AVX-NEXT: retq 490; 491; AVX512-LABEL: cvt_16f32_to_16i16: 492; AVX512: # %bb.0: 493; AVX512-NEXT: vcvtps2ph $4, %zmm0, %ymm0 494; AVX512-NEXT: retq 495 %1 = fptrunc <16 x float> %a0 to <16 x half> 496 %2 = bitcast <16 x half> %1 to <16 x i16> 497 ret <16 x i16> %2 498} 499 500; 501; Float to Half (Store) 502; 503 504define void @store_cvt_f32_to_i16(float %a0, ptr %a1) nounwind { 505; ALL-LABEL: store_cvt_f32_to_i16: 506; ALL: # %bb.0: 507; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 508; ALL-NEXT: vmovd %xmm0, %eax 509; ALL-NEXT: movw %ax, (%rdi) 510; ALL-NEXT: retq 511 %1 = fptrunc float %a0 to half 512 %2 = bitcast half %1 to i16 513 store i16 %2, ptr %a1 514 ret void 515} 516 517define void @store_cvt_4f32_to_4i16(<4 x float> %a0, ptr %a1) nounwind { 518; ALL-LABEL: store_cvt_4f32_to_4i16: 519; ALL: # %bb.0: 520; ALL-NEXT: vcvtps2ph $4, %xmm0, (%rdi) 521; ALL-NEXT: retq 522 %1 = fptrunc <4 x float> %a0 to <4 x half> 523 %2 = bitcast <4 x half> %1 to <4 x i16> 524 store <4 x i16> %2, ptr %a1 525 ret void 526} 527 528define void @store_cvt_4f32_to_8i16_undef(<4 x float> %a0, ptr %a1) nounwind { 529; ALL-LABEL: store_cvt_4f32_to_8i16_undef: 530; ALL: # %bb.0: 531; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 532; ALL-NEXT: vmovaps %xmm0, (%rdi) 533; ALL-NEXT: retq 534 %1 = fptrunc <4 x float> %a0 to <4 x half> 535 %2 = bitcast <4 x half> %1 to <4 x i16> 536 %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 537 store <8 x i16> %3, ptr %a1 538 ret void 539} 540 541define void @store_cvt_4f32_to_8i16_zero(<4 x float> %a0, ptr %a1) nounwind { 542; ALL-LABEL: store_cvt_4f32_to_8i16_zero: 543; ALL: # %bb.0: 544; ALL-NEXT: vcvtps2ph $4, %xmm0, %xmm0 545; ALL-NEXT: vmovaps %xmm0, (%rdi) 546; ALL-NEXT: retq 547 %1 = fptrunc <4 x float> %a0 to <4 x half> 548 %2 = bitcast <4 x half> %1 to <4 x i16> 549 %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 550 store <8 x i16> %3, ptr %a1 551 ret void 552} 553 554define void @store_cvt_8f32_to_8i16(<8 x float> %a0, ptr %a1) nounwind { 555; ALL-LABEL: store_cvt_8f32_to_8i16: 556; ALL: # %bb.0: 557; ALL-NEXT: vcvtps2ph $4, %ymm0, (%rdi) 558; ALL-NEXT: vzeroupper 559; ALL-NEXT: retq 560 %1 = fptrunc <8 x float> %a0 to <8 x half> 561 %2 = bitcast <8 x half> %1 to <8 x i16> 562 store <8 x i16> %2, ptr %a1 563 ret void 564} 565 566define void @store_cvt_16f32_to_16i16(<16 x float> %a0, ptr %a1) nounwind { 567; AVX-LABEL: store_cvt_16f32_to_16i16: 568; AVX: # %bb.0: 569; AVX-NEXT: vcvtps2ph $4, %ymm1, 16(%rdi) 570; AVX-NEXT: vcvtps2ph $4, %ymm0, (%rdi) 571; AVX-NEXT: vzeroupper 572; AVX-NEXT: retq 573; 574; AVX512-LABEL: store_cvt_16f32_to_16i16: 575; AVX512: # %bb.0: 576; AVX512-NEXT: vcvtps2ph $4, %zmm0, (%rdi) 577; AVX512-NEXT: vzeroupper 578; AVX512-NEXT: retq 579 %1 = fptrunc <16 x float> %a0 to <16 x half> 580 %2 = bitcast <16 x half> %1 to <16 x i16> 581 store <16 x i16> %2, ptr %a1 582 ret void 583} 584 585; 586; Double to Half 587; 588 589define i16 @cvt_f64_to_i16(double %a0) nounwind { 590; ALL-LABEL: cvt_f64_to_i16: 591; ALL: # %bb.0: 592; ALL-NEXT: pushq %rax 593; ALL-NEXT: callq __truncdfhf2@PLT 594; ALL-NEXT: vpextrw $0, %xmm0, %eax 595; ALL-NEXT: # kill: def $ax killed $ax killed $eax 596; ALL-NEXT: popq %rcx 597; ALL-NEXT: retq 598 %1 = fptrunc double %a0 to half 599 %2 = bitcast half %1 to i16 600 ret i16 %2 601} 602 603define <2 x i16> @cvt_2f64_to_2i16(<2 x double> %a0) nounwind { 604; AVX-LABEL: cvt_2f64_to_2i16: 605; AVX: # %bb.0: 606; AVX-NEXT: subq $40, %rsp 607; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 608; AVX-NEXT: callq __truncdfhf2@PLT 609; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 610; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 611; AVX-NEXT: # xmm0 = mem[1,0] 612; AVX-NEXT: callq __truncdfhf2@PLT 613; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 614; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 615; AVX-NEXT: addq $40, %rsp 616; AVX-NEXT: retq 617 %1 = fptrunc <2 x double> %a0 to <2 x half> 618 %2 = bitcast <2 x half> %1 to <2 x i16> 619 ret <2 x i16> %2 620} 621 622define <4 x i16> @cvt_4f64_to_4i16(<4 x double> %a0) nounwind { 623; AVX-LABEL: cvt_4f64_to_4i16: 624; AVX: # %bb.0: 625; AVX-NEXT: subq $72, %rsp 626; AVX-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 627; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 628; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 629; AVX-NEXT: vzeroupper 630; AVX-NEXT: callq __truncdfhf2@PLT 631; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 632; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 633; AVX-NEXT: # xmm0 = mem[1,0] 634; AVX-NEXT: callq __truncdfhf2@PLT 635; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 636; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 637; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 638; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 639; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 640; AVX-NEXT: vzeroupper 641; AVX-NEXT: callq __truncdfhf2@PLT 642; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 643; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 644; AVX-NEXT: # xmm0 = mem[1,0] 645; AVX-NEXT: callq __truncdfhf2@PLT 646; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 647; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 648; AVX-NEXT: vinsertps $28, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 649; AVX-NEXT: # xmm0 = xmm0[0],mem[0],zero,zero 650; AVX-NEXT: addq $72, %rsp 651; AVX-NEXT: retq 652; 653; AVX512-LABEL: cvt_4f64_to_4i16: 654; AVX512: # %bb.0: 655; AVX512-NEXT: subq $72, %rsp 656; AVX512-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 657; AVX512-NEXT: vextractf128 $1, %ymm0, %xmm0 658; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 659; AVX512-NEXT: vzeroupper 660; AVX512-NEXT: callq __truncdfhf2@PLT 661; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 662; AVX512-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 663; AVX512-NEXT: # xmm0 = mem[1,0] 664; AVX512-NEXT: callq __truncdfhf2@PLT 665; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 666; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 667; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 668; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 669; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 670; AVX512-NEXT: vzeroupper 671; AVX512-NEXT: callq __truncdfhf2@PLT 672; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 673; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 674; AVX512-NEXT: # xmm0 = mem[1,0] 675; AVX512-NEXT: callq __truncdfhf2@PLT 676; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 677; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 678; AVX512-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 679; AVX512-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 680; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 681; AVX512-NEXT: callq __truncdfhf2@PLT 682; AVX512-NEXT: vpbroadcastw %xmm0, %xmm0 683; AVX512-NEXT: vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 684; AVX512-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0] 685; AVX512-NEXT: addq $72, %rsp 686; AVX512-NEXT: retq 687 %1 = fptrunc <4 x double> %a0 to <4 x half> 688 %2 = bitcast <4 x half> %1 to <4 x i16> 689 ret <4 x i16> %2 690} 691 692define <8 x i16> @cvt_4f64_to_8i16_undef(<4 x double> %a0) nounwind { 693; AVX-LABEL: cvt_4f64_to_8i16_undef: 694; AVX: # %bb.0: 695; AVX-NEXT: subq $72, %rsp 696; AVX-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 697; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 698; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 699; AVX-NEXT: vzeroupper 700; AVX-NEXT: callq __truncdfhf2@PLT 701; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 702; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 703; AVX-NEXT: # xmm0 = mem[1,0] 704; AVX-NEXT: callq __truncdfhf2@PLT 705; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 706; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 707; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 708; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 709; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 710; AVX-NEXT: vzeroupper 711; AVX-NEXT: callq __truncdfhf2@PLT 712; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 713; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 714; AVX-NEXT: # xmm0 = mem[1,0] 715; AVX-NEXT: callq __truncdfhf2@PLT 716; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 717; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 718; AVX-NEXT: vinsertps $28, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 719; AVX-NEXT: # xmm0 = xmm0[0],mem[0],zero,zero 720; AVX-NEXT: addq $72, %rsp 721; AVX-NEXT: retq 722; 723; AVX512-LABEL: cvt_4f64_to_8i16_undef: 724; AVX512: # %bb.0: 725; AVX512-NEXT: subq $72, %rsp 726; AVX512-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 727; AVX512-NEXT: vextractf128 $1, %ymm0, %xmm0 728; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 729; AVX512-NEXT: vzeroupper 730; AVX512-NEXT: callq __truncdfhf2@PLT 731; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 732; AVX512-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 733; AVX512-NEXT: # xmm0 = mem[1,0] 734; AVX512-NEXT: callq __truncdfhf2@PLT 735; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 736; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 737; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 738; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 739; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 740; AVX512-NEXT: vzeroupper 741; AVX512-NEXT: callq __truncdfhf2@PLT 742; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 743; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 744; AVX512-NEXT: # xmm0 = mem[1,0] 745; AVX512-NEXT: callq __truncdfhf2@PLT 746; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 747; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 748; AVX512-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 749; AVX512-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 750; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 751; AVX512-NEXT: callq __truncdfhf2@PLT 752; AVX512-NEXT: vpbroadcastw %xmm0, %xmm0 753; AVX512-NEXT: vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 754; AVX512-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0] 755; AVX512-NEXT: addq $72, %rsp 756; AVX512-NEXT: retq 757 %1 = fptrunc <4 x double> %a0 to <4 x half> 758 %2 = bitcast <4 x half> %1 to <4 x i16> 759 %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 760 ret <8 x i16> %3 761} 762 763define <8 x i16> @cvt_4f64_to_8i16_zero(<4 x double> %a0) nounwind { 764; ALL-LABEL: cvt_4f64_to_8i16_zero: 765; ALL: # %bb.0: 766; ALL-NEXT: subq $72, %rsp 767; ALL-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 768; ALL-NEXT: vextractf128 $1, %ymm0, %xmm0 769; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 770; ALL-NEXT: vzeroupper 771; ALL-NEXT: callq __truncdfhf2@PLT 772; ALL-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 773; ALL-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 774; ALL-NEXT: # xmm0 = mem[1,0] 775; ALL-NEXT: callq __truncdfhf2@PLT 776; ALL-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 777; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 778; ALL-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 779; ALL-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 780; ALL-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 781; ALL-NEXT: vzeroupper 782; ALL-NEXT: callq __truncdfhf2@PLT 783; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 784; ALL-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 785; ALL-NEXT: # xmm0 = mem[1,0] 786; ALL-NEXT: callq __truncdfhf2@PLT 787; ALL-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 788; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 789; ALL-NEXT: vinsertps $28, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 790; ALL-NEXT: # xmm0 = xmm0[0],mem[0],zero,zero 791; ALL-NEXT: addq $72, %rsp 792; ALL-NEXT: retq 793 %1 = fptrunc <4 x double> %a0 to <4 x half> 794 %2 = bitcast <4 x half> %1 to <4 x i16> 795 %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 796 ret <8 x i16> %3 797} 798 799define <8 x i16> @cvt_8f64_to_8i16(<8 x double> %a0) nounwind { 800; AVX-LABEL: cvt_8f64_to_8i16: 801; AVX: # %bb.0: 802; AVX-NEXT: subq $104, %rsp 803; AVX-NEXT: vmovups %ymm1, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 804; AVX-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 805; AVX-NEXT: vextractf128 $1, %ymm1, %xmm0 806; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 807; AVX-NEXT: vzeroupper 808; AVX-NEXT: callq __truncdfhf2@PLT 809; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 810; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 811; AVX-NEXT: # xmm0 = mem[1,0] 812; AVX-NEXT: callq __truncdfhf2@PLT 813; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 814; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 815; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 816; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 817; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 818; AVX-NEXT: vzeroupper 819; AVX-NEXT: callq __truncdfhf2@PLT 820; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 821; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 822; AVX-NEXT: # xmm0 = mem[1,0] 823; AVX-NEXT: callq __truncdfhf2@PLT 824; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 825; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 826; AVX-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 827; AVX-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 828; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 829; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 830; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 831; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 832; AVX-NEXT: vzeroupper 833; AVX-NEXT: callq __truncdfhf2@PLT 834; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 835; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 836; AVX-NEXT: # xmm0 = mem[1,0] 837; AVX-NEXT: callq __truncdfhf2@PLT 838; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 839; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 840; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 841; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 842; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 843; AVX-NEXT: vzeroupper 844; AVX-NEXT: callq __truncdfhf2@PLT 845; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 846; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 847; AVX-NEXT: # xmm0 = mem[1,0] 848; AVX-NEXT: callq __truncdfhf2@PLT 849; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 850; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 851; AVX-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 852; AVX-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 853; AVX-NEXT: vpunpcklqdq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 854; AVX-NEXT: # xmm0 = xmm0[0],mem[0] 855; AVX-NEXT: addq $104, %rsp 856; AVX-NEXT: retq 857; 858; AVX512-LABEL: cvt_8f64_to_8i16: 859; AVX512: # %bb.0: 860; AVX512-NEXT: subq $120, %rsp 861; AVX512-NEXT: vmovups %zmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 64-byte Spill 862; AVX512-NEXT: vextractf32x4 $3, %zmm0, %xmm0 863; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 864; AVX512-NEXT: vzeroupper 865; AVX512-NEXT: callq __truncdfhf2@PLT 866; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 867; AVX512-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 868; AVX512-NEXT: # xmm0 = mem[1,0] 869; AVX512-NEXT: callq __truncdfhf2@PLT 870; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 871; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 872; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 873; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %zmm0 # 64-byte Reload 874; AVX512-NEXT: vextractf32x4 $2, %zmm0, %xmm0 875; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 876; AVX512-NEXT: vzeroupper 877; AVX512-NEXT: callq __truncdfhf2@PLT 878; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 879; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 880; AVX512-NEXT: # xmm0 = mem[1,0] 881; AVX512-NEXT: callq __truncdfhf2@PLT 882; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 883; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 884; AVX512-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 885; AVX512-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 886; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 887; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %zmm0 # 64-byte Reload 888; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 killed $zmm0 889; AVX512-NEXT: vzeroupper 890; AVX512-NEXT: callq __truncdfhf2@PLT 891; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 892; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 893; AVX512-NEXT: # xmm0 = mem[1,0] 894; AVX512-NEXT: callq __truncdfhf2@PLT 895; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 896; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 897; AVX512-NEXT: vmovdqa %xmm0, (%rsp) # 16-byte Spill 898; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %zmm0 # 64-byte Reload 899; AVX512-NEXT: vextractf128 $1, %ymm0, %xmm0 900; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 901; AVX512-NEXT: vzeroupper 902; AVX512-NEXT: callq __truncdfhf2@PLT 903; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 904; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 905; AVX512-NEXT: # xmm0 = mem[1,0] 906; AVX512-NEXT: callq __truncdfhf2@PLT 907; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 908; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 909; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 910; AVX512-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 911; AVX512-NEXT: vpunpcklqdq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 912; AVX512-NEXT: # xmm0 = xmm0[0],mem[0] 913; AVX512-NEXT: addq $120, %rsp 914; AVX512-NEXT: retq 915 %1 = fptrunc <8 x double> %a0 to <8 x half> 916 %2 = bitcast <8 x half> %1 to <8 x i16> 917 ret <8 x i16> %2 918} 919 920; 921; Double to Half (Store) 922; 923 924define void @store_cvt_f64_to_i16(double %a0, ptr %a1) nounwind { 925; ALL-LABEL: store_cvt_f64_to_i16: 926; ALL: # %bb.0: 927; ALL-NEXT: pushq %rbx 928; ALL-NEXT: movq %rdi, %rbx 929; ALL-NEXT: callq __truncdfhf2@PLT 930; ALL-NEXT: vpextrw $0, %xmm0, (%rbx) 931; ALL-NEXT: popq %rbx 932; ALL-NEXT: retq 933 %1 = fptrunc double %a0 to half 934 %2 = bitcast half %1 to i16 935 store i16 %2, ptr %a1 936 ret void 937} 938 939define void @store_cvt_2f64_to_2i16(<2 x double> %a0, ptr %a1) nounwind { 940; ALL-LABEL: store_cvt_2f64_to_2i16: 941; ALL: # %bb.0: 942; ALL-NEXT: pushq %rbx 943; ALL-NEXT: subq $32, %rsp 944; ALL-NEXT: movq %rdi, %rbx 945; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 946; ALL-NEXT: callq __truncdfhf2@PLT 947; ALL-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 948; ALL-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 949; ALL-NEXT: # xmm0 = mem[1,0] 950; ALL-NEXT: callq __truncdfhf2@PLT 951; ALL-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 952; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 953; ALL-NEXT: vmovd %xmm0, (%rbx) 954; ALL-NEXT: addq $32, %rsp 955; ALL-NEXT: popq %rbx 956; ALL-NEXT: retq 957 %1 = fptrunc <2 x double> %a0 to <2 x half> 958 %2 = bitcast <2 x half> %1 to <2 x i16> 959 store <2 x i16> %2, ptr %a1 960 ret void 961} 962 963define void @store_cvt_4f64_to_4i16(<4 x double> %a0, ptr %a1) nounwind { 964; ALL-LABEL: store_cvt_4f64_to_4i16: 965; ALL: # %bb.0: 966; ALL-NEXT: pushq %rbx 967; ALL-NEXT: subq $64, %rsp 968; ALL-NEXT: movq %rdi, %rbx 969; ALL-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 970; ALL-NEXT: vextractf128 $1, %ymm0, %xmm0 971; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 972; ALL-NEXT: vzeroupper 973; ALL-NEXT: callq __truncdfhf2@PLT 974; ALL-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 975; ALL-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 976; ALL-NEXT: # xmm0 = mem[1,0] 977; ALL-NEXT: callq __truncdfhf2@PLT 978; ALL-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 979; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 980; ALL-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 981; ALL-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 982; ALL-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 983; ALL-NEXT: vzeroupper 984; ALL-NEXT: callq __truncdfhf2@PLT 985; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 986; ALL-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 987; ALL-NEXT: # xmm0 = mem[1,0] 988; ALL-NEXT: callq __truncdfhf2@PLT 989; ALL-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 990; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 991; ALL-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 992; ALL-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 993; ALL-NEXT: vmovq %xmm0, (%rbx) 994; ALL-NEXT: addq $64, %rsp 995; ALL-NEXT: popq %rbx 996; ALL-NEXT: retq 997 %1 = fptrunc <4 x double> %a0 to <4 x half> 998 %2 = bitcast <4 x half> %1 to <4 x i16> 999 store <4 x i16> %2, ptr %a1 1000 ret void 1001} 1002 1003define void @store_cvt_4f64_to_8i16_undef(<4 x double> %a0, ptr %a1) nounwind { 1004; AVX-LABEL: store_cvt_4f64_to_8i16_undef: 1005; AVX: # %bb.0: 1006; AVX-NEXT: pushq %rbx 1007; AVX-NEXT: subq $64, %rsp 1008; AVX-NEXT: movq %rdi, %rbx 1009; AVX-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 1010; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 1011; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1012; AVX-NEXT: vzeroupper 1013; AVX-NEXT: callq __truncdfhf2@PLT 1014; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1015; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 1016; AVX-NEXT: # xmm0 = mem[1,0] 1017; AVX-NEXT: callq __truncdfhf2@PLT 1018; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1019; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1020; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1021; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 1022; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 1023; AVX-NEXT: vzeroupper 1024; AVX-NEXT: callq __truncdfhf2@PLT 1025; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1026; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1027; AVX-NEXT: # xmm0 = mem[1,0] 1028; AVX-NEXT: callq __truncdfhf2@PLT 1029; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1030; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1031; AVX-NEXT: vinsertps $28, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1032; AVX-NEXT: # xmm0 = xmm0[0],mem[0],zero,zero 1033; AVX-NEXT: vmovaps %xmm0, (%rbx) 1034; AVX-NEXT: addq $64, %rsp 1035; AVX-NEXT: popq %rbx 1036; AVX-NEXT: retq 1037; 1038; AVX512-LABEL: store_cvt_4f64_to_8i16_undef: 1039; AVX512: # %bb.0: 1040; AVX512-NEXT: pushq %rbx 1041; AVX512-NEXT: subq $64, %rsp 1042; AVX512-NEXT: movq %rdi, %rbx 1043; AVX512-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 1044; AVX512-NEXT: vextractf128 $1, %ymm0, %xmm0 1045; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1046; AVX512-NEXT: vzeroupper 1047; AVX512-NEXT: callq __truncdfhf2@PLT 1048; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1049; AVX512-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 1050; AVX512-NEXT: # xmm0 = mem[1,0] 1051; AVX512-NEXT: callq __truncdfhf2@PLT 1052; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1053; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1054; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1055; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 1056; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 1057; AVX512-NEXT: vzeroupper 1058; AVX512-NEXT: callq __truncdfhf2@PLT 1059; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1060; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1061; AVX512-NEXT: # xmm0 = mem[1,0] 1062; AVX512-NEXT: callq __truncdfhf2@PLT 1063; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1064; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1065; AVX512-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1066; AVX512-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 1067; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1068; AVX512-NEXT: callq __truncdfhf2@PLT 1069; AVX512-NEXT: vpbroadcastw %xmm0, %xmm0 1070; AVX512-NEXT: vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1071; AVX512-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0] 1072; AVX512-NEXT: vmovaps %xmm0, (%rbx) 1073; AVX512-NEXT: addq $64, %rsp 1074; AVX512-NEXT: popq %rbx 1075; AVX512-NEXT: retq 1076 %1 = fptrunc <4 x double> %a0 to <4 x half> 1077 %2 = bitcast <4 x half> %1 to <4 x i16> 1078 %3 = shufflevector <4 x i16> %2, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1079 store <8 x i16> %3, ptr %a1 1080 ret void 1081} 1082 1083define void @store_cvt_4f64_to_8i16_zero(<4 x double> %a0, ptr %a1) nounwind { 1084; ALL-LABEL: store_cvt_4f64_to_8i16_zero: 1085; ALL: # %bb.0: 1086; ALL-NEXT: pushq %rbx 1087; ALL-NEXT: subq $64, %rsp 1088; ALL-NEXT: movq %rdi, %rbx 1089; ALL-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 1090; ALL-NEXT: vextractf128 $1, %ymm0, %xmm0 1091; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1092; ALL-NEXT: vzeroupper 1093; ALL-NEXT: callq __truncdfhf2@PLT 1094; ALL-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1095; ALL-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 1096; ALL-NEXT: # xmm0 = mem[1,0] 1097; ALL-NEXT: callq __truncdfhf2@PLT 1098; ALL-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1099; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1100; ALL-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1101; ALL-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 1102; ALL-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 1103; ALL-NEXT: vzeroupper 1104; ALL-NEXT: callq __truncdfhf2@PLT 1105; ALL-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1106; ALL-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1107; ALL-NEXT: # xmm0 = mem[1,0] 1108; ALL-NEXT: callq __truncdfhf2@PLT 1109; ALL-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1110; ALL-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1111; ALL-NEXT: vinsertps $28, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1112; ALL-NEXT: # xmm0 = xmm0[0],mem[0],zero,zero 1113; ALL-NEXT: vmovaps %xmm0, (%rbx) 1114; ALL-NEXT: addq $64, %rsp 1115; ALL-NEXT: popq %rbx 1116; ALL-NEXT: retq 1117 %1 = fptrunc <4 x double> %a0 to <4 x half> 1118 %2 = bitcast <4 x half> %1 to <4 x i16> 1119 %3 = shufflevector <4 x i16> %2, <4 x i16> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1120 store <8 x i16> %3, ptr %a1 1121 ret void 1122} 1123 1124define void @store_cvt_8f64_to_8i16(<8 x double> %a0, ptr %a1) nounwind { 1125; AVX-LABEL: store_cvt_8f64_to_8i16: 1126; AVX: # %bb.0: 1127; AVX-NEXT: pushq %rbx 1128; AVX-NEXT: subq $96, %rsp 1129; AVX-NEXT: movq %rdi, %rbx 1130; AVX-NEXT: vmovups %ymm1, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 1131; AVX-NEXT: vmovups %ymm0, {{[-0-9]+}}(%r{{[sb]}}p) # 32-byte Spill 1132; AVX-NEXT: vextractf128 $1, %ymm1, %xmm0 1133; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1134; AVX-NEXT: vzeroupper 1135; AVX-NEXT: callq __truncdfhf2@PLT 1136; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1137; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 1138; AVX-NEXT: # xmm0 = mem[1,0] 1139; AVX-NEXT: callq __truncdfhf2@PLT 1140; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1141; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1142; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1143; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 1144; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 1145; AVX-NEXT: vzeroupper 1146; AVX-NEXT: callq __truncdfhf2@PLT 1147; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1148; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1149; AVX-NEXT: # xmm0 = mem[1,0] 1150; AVX-NEXT: callq __truncdfhf2@PLT 1151; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1152; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1153; AVX-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1154; AVX-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 1155; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1156; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 1157; AVX-NEXT: vextractf128 $1, %ymm0, %xmm0 1158; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1159; AVX-NEXT: vzeroupper 1160; AVX-NEXT: callq __truncdfhf2@PLT 1161; AVX-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1162; AVX-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 1163; AVX-NEXT: # xmm0 = mem[1,0] 1164; AVX-NEXT: callq __truncdfhf2@PLT 1165; AVX-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1166; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1167; AVX-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1168; AVX-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %ymm0 # 32-byte Reload 1169; AVX-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 1170; AVX-NEXT: vzeroupper 1171; AVX-NEXT: callq __truncdfhf2@PLT 1172; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1173; AVX-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1174; AVX-NEXT: # xmm0 = mem[1,0] 1175; AVX-NEXT: callq __truncdfhf2@PLT 1176; AVX-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1177; AVX-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1178; AVX-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1179; AVX-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 1180; AVX-NEXT: vpunpcklqdq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1181; AVX-NEXT: # xmm0 = xmm0[0],mem[0] 1182; AVX-NEXT: vmovdqa %xmm0, (%rbx) 1183; AVX-NEXT: addq $96, %rsp 1184; AVX-NEXT: popq %rbx 1185; AVX-NEXT: retq 1186; 1187; AVX512-LABEL: store_cvt_8f64_to_8i16: 1188; AVX512: # %bb.0: 1189; AVX512-NEXT: pushq %rbx 1190; AVX512-NEXT: subq $112, %rsp 1191; AVX512-NEXT: movq %rdi, %rbx 1192; AVX512-NEXT: vmovups %zmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 64-byte Spill 1193; AVX512-NEXT: vextractf32x4 $3, %zmm0, %xmm0 1194; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1195; AVX512-NEXT: vzeroupper 1196; AVX512-NEXT: callq __truncdfhf2@PLT 1197; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1198; AVX512-NEXT: vpermilpd $1, (%rsp), %xmm0 # 16-byte Folded Reload 1199; AVX512-NEXT: # xmm0 = mem[1,0] 1200; AVX512-NEXT: callq __truncdfhf2@PLT 1201; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1202; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1203; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1204; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %zmm0 # 64-byte Reload 1205; AVX512-NEXT: vextractf32x4 $2, %zmm0, %xmm0 1206; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1207; AVX512-NEXT: vzeroupper 1208; AVX512-NEXT: callq __truncdfhf2@PLT 1209; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1210; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1211; AVX512-NEXT: # xmm0 = mem[1,0] 1212; AVX512-NEXT: callq __truncdfhf2@PLT 1213; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1214; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1215; AVX512-NEXT: vpunpckldq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1216; AVX512-NEXT: # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] 1217; AVX512-NEXT: vmovdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1218; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %zmm0 # 64-byte Reload 1219; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 killed $zmm0 1220; AVX512-NEXT: vzeroupper 1221; AVX512-NEXT: callq __truncdfhf2@PLT 1222; AVX512-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 1223; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1224; AVX512-NEXT: # xmm0 = mem[1,0] 1225; AVX512-NEXT: callq __truncdfhf2@PLT 1226; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1227; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1228; AVX512-NEXT: vmovdqa %xmm0, (%rsp) # 16-byte Spill 1229; AVX512-NEXT: vmovups {{[-0-9]+}}(%r{{[sb]}}p), %zmm0 # 64-byte Reload 1230; AVX512-NEXT: vextractf128 $1, %ymm0, %xmm0 1231; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1232; AVX512-NEXT: vzeroupper 1233; AVX512-NEXT: callq __truncdfhf2@PLT 1234; AVX512-NEXT: vmovaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill 1235; AVX512-NEXT: vpermilpd $1, {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Folded Reload 1236; AVX512-NEXT: # xmm0 = mem[1,0] 1237; AVX512-NEXT: callq __truncdfhf2@PLT 1238; AVX512-NEXT: vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload 1239; AVX512-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] 1240; AVX512-NEXT: vmovdqa (%rsp), %xmm1 # 16-byte Reload 1241; AVX512-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 1242; AVX512-NEXT: vpunpcklqdq {{[-0-9]+}}(%r{{[sb]}}p), %xmm0, %xmm0 # 16-byte Folded Reload 1243; AVX512-NEXT: # xmm0 = xmm0[0],mem[0] 1244; AVX512-NEXT: vmovdqa %xmm0, (%rbx) 1245; AVX512-NEXT: addq $112, %rsp 1246; AVX512-NEXT: popq %rbx 1247; AVX512-NEXT: retq 1248 %1 = fptrunc <8 x double> %a0 to <8 x half> 1249 %2 = bitcast <8 x half> %1 to <8 x i16> 1250 store <8 x i16> %2, ptr %a1 1251 ret void 1252} 1253 1254define void @store_cvt_32f32_to_32f16(<32 x float> %a0, ptr %a1) nounwind { 1255; AVX-LABEL: store_cvt_32f32_to_32f16: 1256; AVX: # %bb.0: 1257; AVX-NEXT: vcvtps2ph $4, %ymm3, 48(%rdi) 1258; AVX-NEXT: vcvtps2ph $4, %ymm2, 32(%rdi) 1259; AVX-NEXT: vcvtps2ph $4, %ymm1, 16(%rdi) 1260; AVX-NEXT: vcvtps2ph $4, %ymm0, (%rdi) 1261; AVX-NEXT: vzeroupper 1262; AVX-NEXT: retq 1263; 1264; AVX512-LABEL: store_cvt_32f32_to_32f16: 1265; AVX512: # %bb.0: 1266; AVX512-NEXT: vcvtps2ph $4, %zmm1, 32(%rdi) 1267; AVX512-NEXT: vcvtps2ph $4, %zmm0, (%rdi) 1268; AVX512-NEXT: vzeroupper 1269; AVX512-NEXT: retq 1270 %1 = fptrunc <32 x float> %a0 to <32 x half> 1271 store <32 x half> %1, ptr %a1 1272 ret void 1273} 1274 1275define <4 x i32> @fptosi_2f16_to_4i32(<2 x half> %a) nounwind { 1276; ALL-LABEL: fptosi_2f16_to_4i32: 1277; ALL: # %bb.0: 1278; ALL-NEXT: vpsrld $16, %xmm0, %xmm1 1279; ALL-NEXT: vpextrw $0, %xmm1, %eax 1280; ALL-NEXT: movzwl %ax, %eax 1281; ALL-NEXT: vmovd %eax, %xmm1 1282; ALL-NEXT: vcvtph2ps %xmm1, %xmm1 1283; ALL-NEXT: vcvttss2si %xmm1, %eax 1284; ALL-NEXT: vpextrw $0, %xmm0, %ecx 1285; ALL-NEXT: movzwl %cx, %ecx 1286; ALL-NEXT: vmovd %ecx, %xmm0 1287; ALL-NEXT: vcvtph2ps %xmm0, %xmm0 1288; ALL-NEXT: vcvttss2si %xmm0, %ecx 1289; ALL-NEXT: vmovd %ecx, %xmm0 1290; ALL-NEXT: vmovd %eax, %xmm1 1291; ALL-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1292; ALL-NEXT: vmovq {{.*#+}} xmm0 = xmm0[0],zero 1293; ALL-NEXT: retq 1294 %cvt = fptosi <2 x half> %a to <2 x i32> 1295 %ext = shufflevector <2 x i32> %cvt, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1296 ret <4 x i32> %ext 1297} 1298