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