1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41 5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1 6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX,AVX2,AVX2-SLOW 7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX,AVX2,AVX2-FAST 8; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefix=AVX512 --check-prefix=AVX512F 9; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512VL 10; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512BW 11; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512bw,+avx512vl,+fast-variable-shuffle | FileCheck %s --check-prefixes=AVX512,AVX512BWVL 12 13define <8 x i32> @trunc8i64_8i32(<8 x i64> %a) { 14; SSE-LABEL: trunc8i64_8i32: 15; SSE: # %bb.0: # %entry 16; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] 17; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2] 18; SSE-NEXT: movaps %xmm2, %xmm1 19; SSE-NEXT: retq 20; 21; AVX1-LABEL: trunc8i64_8i32: 22; AVX1: # %bb.0: # %entry 23; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 24; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 25; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] 26; AVX1-NEXT: retq 27; 28; AVX2-SLOW-LABEL: trunc8i64_8i32: 29; AVX2-SLOW: # %bb.0: # %entry 30; AVX2-SLOW-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 31; AVX2-SLOW-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 32; AVX2-SLOW-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] 33; AVX2-SLOW-NEXT: retq 34; 35; AVX2-FAST-LABEL: trunc8i64_8i32: 36; AVX2-FAST: # %bb.0: # %entry 37; AVX2-FAST-NEXT: vmovaps {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7] 38; AVX2-FAST-NEXT: vpermps %ymm0, %ymm2, %ymm0 39; AVX2-FAST-NEXT: vpermps %ymm1, %ymm2, %ymm1 40; AVX2-FAST-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 41; AVX2-FAST-NEXT: retq 42; 43; AVX512-LABEL: trunc8i64_8i32: 44; AVX512: # %bb.0: # %entry 45; AVX512-NEXT: vpmovqd %zmm0, %ymm0 46; AVX512-NEXT: retq 47entry: 48 %0 = trunc <8 x i64> %a to <8 x i32> 49 ret <8 x i32> %0 50} 51 52define <8 x i32> @trunc8i64_8i32_ashr(<8 x i64> %a) { 53; SSE-LABEL: trunc8i64_8i32_ashr: 54; SSE: # %bb.0: # %entry 55; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3] 56; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3] 57; SSE-NEXT: movaps %xmm2, %xmm1 58; SSE-NEXT: retq 59; 60; AVX1-LABEL: trunc8i64_8i32_ashr: 61; AVX1: # %bb.0: # %entry 62; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 63; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 64; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,3],ymm2[1,3],ymm0[5,7],ymm2[5,7] 65; AVX1-NEXT: retq 66; 67; AVX2-SLOW-LABEL: trunc8i64_8i32_ashr: 68; AVX2-SLOW: # %bb.0: # %entry 69; AVX2-SLOW-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 70; AVX2-SLOW-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 71; AVX2-SLOW-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,3],ymm2[1,3],ymm0[5,7],ymm2[5,7] 72; AVX2-SLOW-NEXT: retq 73; 74; AVX2-FAST-LABEL: trunc8i64_8i32_ashr: 75; AVX2-FAST: # %bb.0: # %entry 76; AVX2-FAST-NEXT: vmovaps {{.*#+}} ymm2 = [1,3,5,7,5,7,6,7] 77; AVX2-FAST-NEXT: vpermps %ymm0, %ymm2, %ymm0 78; AVX2-FAST-NEXT: vpermps %ymm1, %ymm2, %ymm1 79; AVX2-FAST-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 80; AVX2-FAST-NEXT: retq 81; 82; AVX512-LABEL: trunc8i64_8i32_ashr: 83; AVX512: # %bb.0: # %entry 84; AVX512-NEXT: vpsraq $32, %zmm0, %zmm0 85; AVX512-NEXT: vpmovqd %zmm0, %ymm0 86; AVX512-NEXT: retq 87entry: 88 %0 = ashr <8 x i64> %a, <i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32> 89 %1 = trunc <8 x i64> %0 to <8 x i32> 90 ret <8 x i32> %1 91} 92 93define <8 x i32> @trunc8i64_8i32_lshr(<8 x i64> %a) { 94; SSE-LABEL: trunc8i64_8i32_lshr: 95; SSE: # %bb.0: # %entry 96; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,3],xmm1[1,3] 97; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[1,3],xmm3[1,3] 98; SSE-NEXT: movaps %xmm2, %xmm1 99; SSE-NEXT: retq 100; 101; AVX1-LABEL: trunc8i64_8i32_lshr: 102; AVX1: # %bb.0: # %entry 103; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 104; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 105; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[1,3],ymm2[1,3],ymm0[5,7],ymm2[5,7] 106; AVX1-NEXT: retq 107; 108; AVX2-SLOW-LABEL: trunc8i64_8i32_lshr: 109; AVX2-SLOW: # %bb.0: # %entry 110; AVX2-SLOW-NEXT: vpsrlq $32, %ymm1, %ymm1 111; AVX2-SLOW-NEXT: vpsrlq $32, %ymm0, %ymm0 112; AVX2-SLOW-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 113; AVX2-SLOW-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 114; AVX2-SLOW-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] 115; AVX2-SLOW-NEXT: retq 116; 117; AVX2-FAST-LABEL: trunc8i64_8i32_lshr: 118; AVX2-FAST: # %bb.0: # %entry 119; AVX2-FAST-NEXT: vpsrlq $32, %ymm1, %ymm1 120; AVX2-FAST-NEXT: vpsrlq $32, %ymm0, %ymm0 121; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7] 122; AVX2-FAST-NEXT: vpermd %ymm0, %ymm2, %ymm0 123; AVX2-FAST-NEXT: vpermd %ymm1, %ymm2, %ymm1 124; AVX2-FAST-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 125; AVX2-FAST-NEXT: retq 126; 127; AVX512-LABEL: trunc8i64_8i32_lshr: 128; AVX512: # %bb.0: # %entry 129; AVX512-NEXT: vpsrlq $32, %zmm0, %zmm0 130; AVX512-NEXT: vpmovqd %zmm0, %ymm0 131; AVX512-NEXT: retq 132entry: 133 %0 = lshr <8 x i64> %a, <i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32, i64 32> 134 %1 = trunc <8 x i64> %0 to <8 x i32> 135 ret <8 x i32> %1 136} 137 138define <8 x i16> @trunc8i64_8i16(<8 x i64> %a) { 139; SSE2-LABEL: trunc8i64_8i16: 140; SSE2: # %bb.0: # %entry 141; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 142; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7] 143; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 144; SSE2-NEXT: pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7] 145; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1] 146; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3] 147; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7] 148; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 149; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7] 150; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 151; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1] 152; SSE2-NEXT: retq 153; 154; SSSE3-LABEL: trunc8i64_8i16: 155; SSSE3: # %bb.0: # %entry 156; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 157; SSSE3-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7] 158; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 159; SSSE3-NEXT: pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7] 160; SSSE3-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1] 161; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3] 162; SSSE3-NEXT: pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7] 163; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 164; SSSE3-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7] 165; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 166; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1] 167; SSSE3-NEXT: retq 168; 169; SSE41-LABEL: trunc8i64_8i16: 170; SSE41: # %bb.0: # %entry 171; SSE41-NEXT: pxor %xmm4, %xmm4 172; SSE41-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1,2,3],xmm3[4],xmm4[5,6,7] 173; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1,2,3],xmm2[4],xmm4[5,6,7] 174; SSE41-NEXT: packusdw %xmm3, %xmm2 175; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1,2,3],xmm1[4],xmm4[5,6,7] 176; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1,2,3],xmm0[4],xmm4[5,6,7] 177; SSE41-NEXT: packusdw %xmm1, %xmm0 178; SSE41-NEXT: packusdw %xmm2, %xmm0 179; SSE41-NEXT: retq 180; 181; AVX1-LABEL: trunc8i64_8i16: 182; AVX1: # %bb.0: # %entry 183; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535] 184; AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1 185; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 186; AVX1-NEXT: vpackusdw %xmm3, %xmm1, %xmm1 187; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0 188; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 189; AVX1-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 190; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 191; AVX1-NEXT: vzeroupper 192; AVX1-NEXT: retq 193; 194; AVX2-SLOW-LABEL: trunc8i64_8i16: 195; AVX2-SLOW: # %bb.0: # %entry 196; AVX2-SLOW-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 197; AVX2-SLOW-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 198; AVX2-SLOW-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] 199; AVX2-SLOW-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u] 200; AVX2-SLOW-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 201; AVX2-SLOW-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 202; AVX2-SLOW-NEXT: vzeroupper 203; AVX2-SLOW-NEXT: retq 204; 205; AVX2-FAST-LABEL: trunc8i64_8i16: 206; AVX2-FAST: # %bb.0: # %entry 207; AVX2-FAST-NEXT: vmovdqa {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7] 208; AVX2-FAST-NEXT: vpermd %ymm0, %ymm2, %ymm0 209; AVX2-FAST-NEXT: vpermd %ymm1, %ymm2, %ymm1 210; AVX2-FAST-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 211; AVX2-FAST-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u] 212; AVX2-FAST-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 213; AVX2-FAST-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 214; AVX2-FAST-NEXT: vzeroupper 215; AVX2-FAST-NEXT: retq 216; 217; AVX512-LABEL: trunc8i64_8i16: 218; AVX512: # %bb.0: # %entry 219; AVX512-NEXT: vpmovqw %zmm0, %xmm0 220; AVX512-NEXT: vzeroupper 221; AVX512-NEXT: retq 222entry: 223 %0 = trunc <8 x i64> %a to <8 x i16> 224 ret <8 x i16> %0 225} 226 227define void @trunc8i64_8i8(<8 x i64> %a) { 228; SSE2-LABEL: trunc8i64_8i8: 229; SSE2: # %bb.0: # %entry 230; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0] 231; SSE2-NEXT: pand %xmm4, %xmm3 232; SSE2-NEXT: pand %xmm4, %xmm2 233; SSE2-NEXT: packuswb %xmm3, %xmm2 234; SSE2-NEXT: pand %xmm4, %xmm1 235; SSE2-NEXT: pand %xmm4, %xmm0 236; SSE2-NEXT: packuswb %xmm1, %xmm0 237; SSE2-NEXT: packuswb %xmm2, %xmm0 238; SSE2-NEXT: packuswb %xmm0, %xmm0 239; SSE2-NEXT: movq %xmm0, (%rax) 240; SSE2-NEXT: retq 241; 242; SSSE3-LABEL: trunc8i64_8i8: 243; SSSE3: # %bb.0: # %entry 244; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0] 245; SSSE3-NEXT: pand %xmm4, %xmm3 246; SSSE3-NEXT: pand %xmm4, %xmm2 247; SSSE3-NEXT: packuswb %xmm3, %xmm2 248; SSSE3-NEXT: pand %xmm4, %xmm1 249; SSSE3-NEXT: pand %xmm4, %xmm0 250; SSSE3-NEXT: packuswb %xmm1, %xmm0 251; SSSE3-NEXT: packuswb %xmm2, %xmm0 252; SSSE3-NEXT: packuswb %xmm0, %xmm0 253; SSSE3-NEXT: movq %xmm0, (%rax) 254; SSSE3-NEXT: retq 255; 256; SSE41-LABEL: trunc8i64_8i8: 257; SSE41: # %bb.0: # %entry 258; SSE41-NEXT: movdqa {{.*#+}} xmm4 = [255,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0] 259; SSE41-NEXT: pand %xmm4, %xmm3 260; SSE41-NEXT: pand %xmm4, %xmm2 261; SSE41-NEXT: packusdw %xmm3, %xmm2 262; SSE41-NEXT: pand %xmm4, %xmm1 263; SSE41-NEXT: pand %xmm4, %xmm0 264; SSE41-NEXT: packusdw %xmm1, %xmm0 265; SSE41-NEXT: packusdw %xmm2, %xmm0 266; SSE41-NEXT: packuswb %xmm0, %xmm0 267; SSE41-NEXT: movq %xmm0, (%rax) 268; SSE41-NEXT: retq 269; 270; AVX1-LABEL: trunc8i64_8i8: 271; AVX1: # %bb.0: # %entry 272; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [255,255,255,255] 273; AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1 274; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 275; AVX1-NEXT: vpackusdw %xmm3, %xmm1, %xmm1 276; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0 277; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 278; AVX1-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 279; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 280; AVX1-NEXT: vpackuswb %xmm0, %xmm0, %xmm0 281; AVX1-NEXT: vmovq %xmm0, (%rax) 282; AVX1-NEXT: vzeroupper 283; AVX1-NEXT: retq 284; 285; AVX2-LABEL: trunc8i64_8i8: 286; AVX2: # %bb.0: # %entry 287; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm2 288; AVX2-NEXT: vmovdqa {{.*#+}} xmm3 = <u,u,0,8,u,u,u,u,u,u,u,u,u,u,u,u> 289; AVX2-NEXT: vpshufb %xmm3, %xmm2, %xmm2 290; AVX2-NEXT: vpshufb %xmm3, %xmm1, %xmm1 291; AVX2-NEXT: vpunpcklwd {{.*#+}} xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1],xmm1[2],xmm2[2],xmm1[3],xmm2[3] 292; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 293; AVX2-NEXT: vmovdqa {{.*#+}} xmm3 = <0,8,u,u,u,u,u,u,u,u,u,u,u,u,u,u> 294; AVX2-NEXT: vpshufb %xmm3, %xmm2, %xmm2 295; AVX2-NEXT: vpshufb %xmm3, %xmm0, %xmm0 296; AVX2-NEXT: vpunpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] 297; AVX2-NEXT: vpblendd {{.*#+}} xmm0 = xmm0[0],xmm1[1],xmm0[2,3] 298; AVX2-NEXT: vmovq %xmm0, (%rax) 299; AVX2-NEXT: vzeroupper 300; AVX2-NEXT: retq 301; 302; AVX512-LABEL: trunc8i64_8i8: 303; AVX512: # %bb.0: # %entry 304; AVX512-NEXT: vpmovqb %zmm0, (%rax) 305; AVX512-NEXT: vzeroupper 306; AVX512-NEXT: retq 307entry: 308 %0 = trunc <8 x i64> %a to <8 x i8> 309 store <8 x i8> %0, <8 x i8>* undef, align 4 310 ret void 311} 312 313define <8 x i16> @trunc8i32_8i16(<8 x i32> %a) { 314; SSE2-LABEL: trunc8i32_8i16: 315; SSE2: # %bb.0: # %entry 316; SSE2-NEXT: pslld $16, %xmm1 317; SSE2-NEXT: psrad $16, %xmm1 318; SSE2-NEXT: pslld $16, %xmm0 319; SSE2-NEXT: psrad $16, %xmm0 320; SSE2-NEXT: packssdw %xmm1, %xmm0 321; SSE2-NEXT: retq 322; 323; SSSE3-LABEL: trunc8i32_8i16: 324; SSSE3: # %bb.0: # %entry 325; SSSE3-NEXT: movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 326; SSSE3-NEXT: pshufb %xmm2, %xmm1 327; SSSE3-NEXT: pshufb %xmm2, %xmm0 328; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 329; SSSE3-NEXT: retq 330; 331; SSE41-LABEL: trunc8i32_8i16: 332; SSE41: # %bb.0: # %entry 333; SSE41-NEXT: pxor %xmm2, %xmm2 334; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] 335; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] 336; SSE41-NEXT: packusdw %xmm1, %xmm0 337; SSE41-NEXT: retq 338; 339; AVX1-LABEL: trunc8i32_8i16: 340; AVX1: # %bb.0: # %entry 341; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 342; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 343; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1 344; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0 345; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 346; AVX1-NEXT: vzeroupper 347; AVX1-NEXT: retq 348; 349; AVX2-LABEL: trunc8i32_8i16: 350; AVX2: # %bb.0: # %entry 351; AVX2-NEXT: vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u,16,17,20,21,24,25,28,29,u,u,u,u,u,u,u,u] 352; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 353; AVX2-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 354; AVX2-NEXT: vzeroupper 355; AVX2-NEXT: retq 356; 357; AVX512F-LABEL: trunc8i32_8i16: 358; AVX512F: # %bb.0: # %entry 359; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 360; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 361; AVX512F-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 362; AVX512F-NEXT: vzeroupper 363; AVX512F-NEXT: retq 364; 365; AVX512VL-LABEL: trunc8i32_8i16: 366; AVX512VL: # %bb.0: # %entry 367; AVX512VL-NEXT: vpmovdw %ymm0, %xmm0 368; AVX512VL-NEXT: vzeroupper 369; AVX512VL-NEXT: retq 370; 371; AVX512BW-LABEL: trunc8i32_8i16: 372; AVX512BW: # %bb.0: # %entry 373; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 374; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 375; AVX512BW-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 376; AVX512BW-NEXT: vzeroupper 377; AVX512BW-NEXT: retq 378; 379; AVX512BWVL-LABEL: trunc8i32_8i16: 380; AVX512BWVL: # %bb.0: # %entry 381; AVX512BWVL-NEXT: vpmovdw %ymm0, %xmm0 382; AVX512BWVL-NEXT: vzeroupper 383; AVX512BWVL-NEXT: retq 384entry: 385 %0 = trunc <8 x i32> %a to <8 x i16> 386 ret <8 x i16> %0 387} 388 389define <8 x i16> @trunc8i32_8i16_ashr(<8 x i32> %a) { 390; SSE-LABEL: trunc8i32_8i16_ashr: 391; SSE: # %bb.0: # %entry 392; SSE-NEXT: psrad $16, %xmm1 393; SSE-NEXT: psrad $16, %xmm0 394; SSE-NEXT: packssdw %xmm1, %xmm0 395; SSE-NEXT: retq 396; 397; AVX1-LABEL: trunc8i32_8i16_ashr: 398; AVX1: # %bb.0: # %entry 399; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 400; AVX1-NEXT: vpsrad $16, %xmm1, %xmm1 401; AVX1-NEXT: vpsrad $16, %xmm0, %xmm0 402; AVX1-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 403; AVX1-NEXT: vzeroupper 404; AVX1-NEXT: retq 405; 406; AVX2-LABEL: trunc8i32_8i16_ashr: 407; AVX2: # %bb.0: # %entry 408; AVX2-NEXT: vpsrad $16, %ymm0, %ymm0 409; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 410; AVX2-NEXT: vpackssdw %xmm1, %xmm0, %xmm0 411; AVX2-NEXT: vzeroupper 412; AVX2-NEXT: retq 413; 414; AVX512F-LABEL: trunc8i32_8i16_ashr: 415; AVX512F: # %bb.0: # %entry 416; AVX512F-NEXT: vpsrad $16, %ymm0, %ymm0 417; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 418; AVX512F-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 419; AVX512F-NEXT: vzeroupper 420; AVX512F-NEXT: retq 421; 422; AVX512VL-LABEL: trunc8i32_8i16_ashr: 423; AVX512VL: # %bb.0: # %entry 424; AVX512VL-NEXT: vpsrad $16, %ymm0, %ymm0 425; AVX512VL-NEXT: vpmovdw %ymm0, %xmm0 426; AVX512VL-NEXT: vzeroupper 427; AVX512VL-NEXT: retq 428; 429; AVX512BW-LABEL: trunc8i32_8i16_ashr: 430; AVX512BW: # %bb.0: # %entry 431; AVX512BW-NEXT: vpsrad $16, %ymm0, %ymm0 432; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 433; AVX512BW-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 434; AVX512BW-NEXT: vzeroupper 435; AVX512BW-NEXT: retq 436; 437; AVX512BWVL-LABEL: trunc8i32_8i16_ashr: 438; AVX512BWVL: # %bb.0: # %entry 439; AVX512BWVL-NEXT: vpsrad $16, %ymm0, %ymm0 440; AVX512BWVL-NEXT: vpmovdw %ymm0, %xmm0 441; AVX512BWVL-NEXT: vzeroupper 442; AVX512BWVL-NEXT: retq 443entry: 444 %0 = ashr <8 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 445 %1 = trunc <8 x i32> %0 to <8 x i16> 446 ret <8 x i16> %1 447} 448 449define <8 x i16> @trunc8i32_8i16_lshr(<8 x i32> %a) { 450; SSE2-LABEL: trunc8i32_8i16_lshr: 451; SSE2: # %bb.0: # %entry 452; SSE2-NEXT: psrad $16, %xmm1 453; SSE2-NEXT: psrad $16, %xmm0 454; SSE2-NEXT: packssdw %xmm1, %xmm0 455; SSE2-NEXT: retq 456; 457; SSSE3-LABEL: trunc8i32_8i16_lshr: 458; SSSE3: # %bb.0: # %entry 459; SSSE3-NEXT: movdqa {{.*#+}} xmm2 = [2,3,6,7,10,11,14,15,10,11,14,15,14,15,128,128] 460; SSSE3-NEXT: pshufb %xmm2, %xmm1 461; SSSE3-NEXT: pshufb %xmm2, %xmm0 462; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 463; SSSE3-NEXT: retq 464; 465; SSE41-LABEL: trunc8i32_8i16_lshr: 466; SSE41: # %bb.0: # %entry 467; SSE41-NEXT: psrld $16, %xmm1 468; SSE41-NEXT: psrld $16, %xmm0 469; SSE41-NEXT: packusdw %xmm1, %xmm0 470; SSE41-NEXT: retq 471; 472; AVX1-LABEL: trunc8i32_8i16_lshr: 473; AVX1: # %bb.0: # %entry 474; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 475; AVX1-NEXT: vpsrld $16, %xmm1, %xmm1 476; AVX1-NEXT: vpsrld $16, %xmm0, %xmm0 477; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 478; AVX1-NEXT: vzeroupper 479; AVX1-NEXT: retq 480; 481; AVX2-LABEL: trunc8i32_8i16_lshr: 482; AVX2: # %bb.0: # %entry 483; AVX2-NEXT: vpsrld $16, %ymm0, %ymm0 484; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 485; AVX2-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 486; AVX2-NEXT: vzeroupper 487; AVX2-NEXT: retq 488; 489; AVX512F-LABEL: trunc8i32_8i16_lshr: 490; AVX512F: # %bb.0: # %entry 491; AVX512F-NEXT: vpsrld $16, %ymm0, %ymm0 492; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 493; AVX512F-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 494; AVX512F-NEXT: vzeroupper 495; AVX512F-NEXT: retq 496; 497; AVX512VL-LABEL: trunc8i32_8i16_lshr: 498; AVX512VL: # %bb.0: # %entry 499; AVX512VL-NEXT: vpsrld $16, %ymm0, %ymm0 500; AVX512VL-NEXT: vpmovdw %ymm0, %xmm0 501; AVX512VL-NEXT: vzeroupper 502; AVX512VL-NEXT: retq 503; 504; AVX512BW-LABEL: trunc8i32_8i16_lshr: 505; AVX512BW: # %bb.0: # %entry 506; AVX512BW-NEXT: vpsrld $16, %ymm0, %ymm0 507; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 508; AVX512BW-NEXT: # kill: def $xmm0 killed $xmm0 killed $ymm0 509; AVX512BW-NEXT: vzeroupper 510; AVX512BW-NEXT: retq 511; 512; AVX512BWVL-LABEL: trunc8i32_8i16_lshr: 513; AVX512BWVL: # %bb.0: # %entry 514; AVX512BWVL-NEXT: vpsrld $16, %ymm0, %ymm0 515; AVX512BWVL-NEXT: vpmovdw %ymm0, %xmm0 516; AVX512BWVL-NEXT: vzeroupper 517; AVX512BWVL-NEXT: retq 518entry: 519 %0 = lshr <8 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 520 %1 = trunc <8 x i32> %0 to <8 x i16> 521 ret <8 x i16> %1 522} 523 524define void @trunc8i32_8i8(<8 x i32> %a) { 525; SSE2-LABEL: trunc8i32_8i8: 526; SSE2: # %bb.0: # %entry 527; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0] 528; SSE2-NEXT: pand %xmm2, %xmm1 529; SSE2-NEXT: pand %xmm2, %xmm0 530; SSE2-NEXT: packuswb %xmm1, %xmm0 531; SSE2-NEXT: packuswb %xmm0, %xmm0 532; SSE2-NEXT: movq %xmm0, (%rax) 533; SSE2-NEXT: retq 534; 535; SSSE3-LABEL: trunc8i32_8i8: 536; SSSE3: # %bb.0: # %entry 537; SSSE3-NEXT: movdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u> 538; SSSE3-NEXT: pshufb %xmm2, %xmm1 539; SSSE3-NEXT: pshufb %xmm2, %xmm0 540; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 541; SSSE3-NEXT: movq %xmm0, (%rax) 542; SSSE3-NEXT: retq 543; 544; SSE41-LABEL: trunc8i32_8i8: 545; SSE41: # %bb.0: # %entry 546; SSE41-NEXT: movdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u> 547; SSE41-NEXT: pshufb %xmm2, %xmm1 548; SSE41-NEXT: pshufb %xmm2, %xmm0 549; SSE41-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 550; SSE41-NEXT: movq %xmm0, (%rax) 551; SSE41-NEXT: retq 552; 553; AVX1-LABEL: trunc8i32_8i8: 554; AVX1: # %bb.0: # %entry 555; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 556; AVX1-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u> 557; AVX1-NEXT: vpshufb %xmm2, %xmm1, %xmm1 558; AVX1-NEXT: vpshufb %xmm2, %xmm0, %xmm0 559; AVX1-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 560; AVX1-NEXT: vmovq %xmm0, (%rax) 561; AVX1-NEXT: vzeroupper 562; AVX1-NEXT: retq 563; 564; AVX2-LABEL: trunc8i32_8i8: 565; AVX2: # %bb.0: # %entry 566; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 567; AVX2-NEXT: vmovdqa {{.*#+}} xmm2 = <0,4,8,12,u,u,u,u,u,u,u,u,u,u,u,u> 568; AVX2-NEXT: vpshufb %xmm2, %xmm1, %xmm1 569; AVX2-NEXT: vpshufb %xmm2, %xmm0, %xmm0 570; AVX2-NEXT: vpunpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 571; AVX2-NEXT: vmovq %xmm0, (%rax) 572; AVX2-NEXT: vzeroupper 573; AVX2-NEXT: retq 574; 575; AVX512F-LABEL: trunc8i32_8i8: 576; AVX512F: # %bb.0: # %entry 577; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 578; AVX512F-NEXT: vpmovdb %zmm0, %xmm0 579; AVX512F-NEXT: vmovq %xmm0, (%rax) 580; AVX512F-NEXT: vzeroupper 581; AVX512F-NEXT: retq 582; 583; AVX512VL-LABEL: trunc8i32_8i8: 584; AVX512VL: # %bb.0: # %entry 585; AVX512VL-NEXT: vpmovdb %ymm0, (%rax) 586; AVX512VL-NEXT: vzeroupper 587; AVX512VL-NEXT: retq 588; 589; AVX512BW-LABEL: trunc8i32_8i8: 590; AVX512BW: # %bb.0: # %entry 591; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 592; AVX512BW-NEXT: vpmovdb %zmm0, %xmm0 593; AVX512BW-NEXT: vmovq %xmm0, (%rax) 594; AVX512BW-NEXT: vzeroupper 595; AVX512BW-NEXT: retq 596; 597; AVX512BWVL-LABEL: trunc8i32_8i8: 598; AVX512BWVL: # %bb.0: # %entry 599; AVX512BWVL-NEXT: vpmovdb %ymm0, (%rax) 600; AVX512BWVL-NEXT: vzeroupper 601; AVX512BWVL-NEXT: retq 602entry: 603 %0 = trunc <8 x i32> %a to <8 x i8> 604 store <8 x i8> %0, <8 x i8>* undef, align 4 605 ret void 606} 607 608define void @trunc16i32_16i16(<16 x i32> %a) { 609; SSE2-LABEL: trunc16i32_16i16: 610; SSE2: # %bb.0: # %entry 611; SSE2-NEXT: pslld $16, %xmm1 612; SSE2-NEXT: psrad $16, %xmm1 613; SSE2-NEXT: pslld $16, %xmm0 614; SSE2-NEXT: psrad $16, %xmm0 615; SSE2-NEXT: packssdw %xmm1, %xmm0 616; SSE2-NEXT: pslld $16, %xmm3 617; SSE2-NEXT: psrad $16, %xmm3 618; SSE2-NEXT: pslld $16, %xmm2 619; SSE2-NEXT: psrad $16, %xmm2 620; SSE2-NEXT: packssdw %xmm3, %xmm2 621; SSE2-NEXT: movdqu %xmm2, (%rax) 622; SSE2-NEXT: movdqu %xmm0, (%rax) 623; SSE2-NEXT: retq 624; 625; SSSE3-LABEL: trunc16i32_16i16: 626; SSSE3: # %bb.0: # %entry 627; SSSE3-NEXT: pslld $16, %xmm1 628; SSSE3-NEXT: psrad $16, %xmm1 629; SSSE3-NEXT: pslld $16, %xmm0 630; SSSE3-NEXT: psrad $16, %xmm0 631; SSSE3-NEXT: packssdw %xmm1, %xmm0 632; SSSE3-NEXT: pslld $16, %xmm3 633; SSSE3-NEXT: psrad $16, %xmm3 634; SSSE3-NEXT: pslld $16, %xmm2 635; SSSE3-NEXT: psrad $16, %xmm2 636; SSSE3-NEXT: packssdw %xmm3, %xmm2 637; SSSE3-NEXT: movdqu %xmm2, (%rax) 638; SSSE3-NEXT: movdqu %xmm0, (%rax) 639; SSSE3-NEXT: retq 640; 641; SSE41-LABEL: trunc16i32_16i16: 642; SSE41: # %bb.0: # %entry 643; SSE41-NEXT: pxor %xmm4, %xmm4 644; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] 645; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] 646; SSE41-NEXT: packusdw %xmm1, %xmm0 647; SSE41-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] 648; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] 649; SSE41-NEXT: packusdw %xmm3, %xmm2 650; SSE41-NEXT: movdqu %xmm2, (%rax) 651; SSE41-NEXT: movdqu %xmm0, (%rax) 652; SSE41-NEXT: retq 653; 654; AVX1-LABEL: trunc16i32_16i16: 655; AVX1: # %bb.0: # %entry 656; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [65535,65535,65535,65535,65535,65535,65535,65535] 657; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0 658; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 659; AVX1-NEXT: vpackusdw %xmm3, %xmm0, %xmm0 660; AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1 661; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 662; AVX1-NEXT: vpackusdw %xmm2, %xmm1, %xmm1 663; AVX1-NEXT: vmovdqu %xmm1, (%rax) 664; AVX1-NEXT: vmovdqu %xmm0, (%rax) 665; AVX1-NEXT: vzeroupper 666; AVX1-NEXT: retq 667; 668; AVX2-LABEL: trunc16i32_16i16: 669; AVX2: # %bb.0: # %entry 670; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31] 671; AVX2-NEXT: vpshufb %ymm2, %ymm0, %ymm0 672; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 673; AVX2-NEXT: vpshufb %ymm2, %ymm1, %ymm1 674; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3] 675; AVX2-NEXT: vmovdqu %xmm1, (%rax) 676; AVX2-NEXT: vmovdqu %xmm0, (%rax) 677; AVX2-NEXT: vzeroupper 678; AVX2-NEXT: retq 679; 680; AVX512-LABEL: trunc16i32_16i16: 681; AVX512: # %bb.0: # %entry 682; AVX512-NEXT: vpmovdw %zmm0, (%rax) 683; AVX512-NEXT: vzeroupper 684; AVX512-NEXT: retq 685entry: 686 %0 = trunc <16 x i32> %a to <16 x i16> 687 store <16 x i16> %0, <16 x i16>* undef, align 4 688 ret void 689} 690 691define void @trunc16i32_16i16_ashr(<16 x i32> %a) { 692; SSE-LABEL: trunc16i32_16i16_ashr: 693; SSE: # %bb.0: # %entry 694; SSE-NEXT: psrad $16, %xmm3 695; SSE-NEXT: psrad $16, %xmm2 696; SSE-NEXT: packssdw %xmm3, %xmm2 697; SSE-NEXT: psrad $16, %xmm1 698; SSE-NEXT: psrad $16, %xmm0 699; SSE-NEXT: packssdw %xmm1, %xmm0 700; SSE-NEXT: movdqu %xmm2, (%rax) 701; SSE-NEXT: movdqu %xmm0, (%rax) 702; SSE-NEXT: retq 703; 704; AVX1-LABEL: trunc16i32_16i16_ashr: 705; AVX1: # %bb.0: # %entry 706; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 707; AVX1-NEXT: vpsrad $16, %xmm2, %xmm2 708; AVX1-NEXT: vpsrad $16, %xmm1, %xmm1 709; AVX1-NEXT: vpackssdw %xmm2, %xmm1, %xmm1 710; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 711; AVX1-NEXT: vpsrad $16, %xmm2, %xmm2 712; AVX1-NEXT: vpsrad $16, %xmm0, %xmm0 713; AVX1-NEXT: vpackssdw %xmm2, %xmm0, %xmm0 714; AVX1-NEXT: vmovdqu %xmm1, (%rax) 715; AVX1-NEXT: vmovdqu %xmm0, (%rax) 716; AVX1-NEXT: vzeroupper 717; AVX1-NEXT: retq 718; 719; AVX2-LABEL: trunc16i32_16i16_ashr: 720; AVX2: # %bb.0: # %entry 721; AVX2-NEXT: vpsrad $16, %ymm1, %ymm1 722; AVX2-NEXT: vpsrad $16, %ymm0, %ymm0 723; AVX2-NEXT: vpackssdw %ymm1, %ymm0, %ymm0 724; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] 725; AVX2-NEXT: vmovdqu %ymm0, (%rax) 726; AVX2-NEXT: vzeroupper 727; AVX2-NEXT: retq 728; 729; AVX512-LABEL: trunc16i32_16i16_ashr: 730; AVX512: # %bb.0: # %entry 731; AVX512-NEXT: vpsrld $16, %zmm0, %zmm0 732; AVX512-NEXT: vpmovdw %zmm0, (%rax) 733; AVX512-NEXT: vzeroupper 734; AVX512-NEXT: retq 735entry: 736 %0 = ashr <16 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 737 %1 = trunc <16 x i32> %0 to <16 x i16> 738 store <16 x i16> %1, <16 x i16>* undef, align 4 739 ret void 740} 741 742define void @trunc16i32_16i16_lshr(<16 x i32> %a) { 743; SSE2-LABEL: trunc16i32_16i16_lshr: 744; SSE2: # %bb.0: # %entry 745; SSE2-NEXT: psrad $16, %xmm1 746; SSE2-NEXT: psrad $16, %xmm0 747; SSE2-NEXT: packssdw %xmm1, %xmm0 748; SSE2-NEXT: psrad $16, %xmm3 749; SSE2-NEXT: psrad $16, %xmm2 750; SSE2-NEXT: packssdw %xmm3, %xmm2 751; SSE2-NEXT: movdqu %xmm2, (%rax) 752; SSE2-NEXT: movdqu %xmm0, (%rax) 753; SSE2-NEXT: retq 754; 755; SSSE3-LABEL: trunc16i32_16i16_lshr: 756; SSSE3: # %bb.0: # %entry 757; SSSE3-NEXT: psrad $16, %xmm1 758; SSSE3-NEXT: psrad $16, %xmm0 759; SSSE3-NEXT: packssdw %xmm1, %xmm0 760; SSSE3-NEXT: psrad $16, %xmm3 761; SSSE3-NEXT: psrad $16, %xmm2 762; SSSE3-NEXT: packssdw %xmm3, %xmm2 763; SSSE3-NEXT: movdqu %xmm2, (%rax) 764; SSSE3-NEXT: movdqu %xmm0, (%rax) 765; SSSE3-NEXT: retq 766; 767; SSE41-LABEL: trunc16i32_16i16_lshr: 768; SSE41: # %bb.0: # %entry 769; SSE41-NEXT: psrld $16, %xmm3 770; SSE41-NEXT: psrld $16, %xmm2 771; SSE41-NEXT: packusdw %xmm3, %xmm2 772; SSE41-NEXT: psrld $16, %xmm1 773; SSE41-NEXT: psrld $16, %xmm0 774; SSE41-NEXT: packusdw %xmm1, %xmm0 775; SSE41-NEXT: movdqu %xmm2, (%rax) 776; SSE41-NEXT: movdqu %xmm0, (%rax) 777; SSE41-NEXT: retq 778; 779; AVX1-LABEL: trunc16i32_16i16_lshr: 780; AVX1: # %bb.0: # %entry 781; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 782; AVX1-NEXT: vpsrld $16, %xmm2, %xmm2 783; AVX1-NEXT: vpsrld $16, %xmm1, %xmm1 784; AVX1-NEXT: vpackusdw %xmm2, %xmm1, %xmm1 785; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 786; AVX1-NEXT: vpsrld $16, %xmm2, %xmm2 787; AVX1-NEXT: vpsrld $16, %xmm0, %xmm0 788; AVX1-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 789; AVX1-NEXT: vmovdqu %xmm1, (%rax) 790; AVX1-NEXT: vmovdqu %xmm0, (%rax) 791; AVX1-NEXT: vzeroupper 792; AVX1-NEXT: retq 793; 794; AVX2-LABEL: trunc16i32_16i16_lshr: 795; AVX2: # %bb.0: # %entry 796; AVX2-NEXT: vpsrld $16, %ymm1, %ymm1 797; AVX2-NEXT: vpsrld $16, %ymm0, %ymm0 798; AVX2-NEXT: vpackusdw %ymm1, %ymm0, %ymm0 799; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] 800; AVX2-NEXT: vmovdqu %ymm0, (%rax) 801; AVX2-NEXT: vzeroupper 802; AVX2-NEXT: retq 803; 804; AVX512-LABEL: trunc16i32_16i16_lshr: 805; AVX512: # %bb.0: # %entry 806; AVX512-NEXT: vpsrld $16, %zmm0, %zmm0 807; AVX512-NEXT: vpmovdw %zmm0, (%rax) 808; AVX512-NEXT: vzeroupper 809; AVX512-NEXT: retq 810entry: 811 %0 = lshr <16 x i32> %a, <i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16, i32 16> 812 %1 = trunc <16 x i32> %0 to <16 x i16> 813 store <16 x i16> %1, <16 x i16>* undef, align 4 814 ret void 815} 816 817define void @trunc16i32_16i8(<16 x i32> %a) { 818; SSE2-LABEL: trunc16i32_16i8: 819; SSE2: # %bb.0: # %entry 820; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0] 821; SSE2-NEXT: pand %xmm4, %xmm3 822; SSE2-NEXT: pand %xmm4, %xmm2 823; SSE2-NEXT: packuswb %xmm3, %xmm2 824; SSE2-NEXT: pand %xmm4, %xmm1 825; SSE2-NEXT: pand %xmm4, %xmm0 826; SSE2-NEXT: packuswb %xmm1, %xmm0 827; SSE2-NEXT: packuswb %xmm2, %xmm0 828; SSE2-NEXT: movdqu %xmm0, (%rax) 829; SSE2-NEXT: retq 830; 831; SSSE3-LABEL: trunc16i32_16i8: 832; SSSE3: # %bb.0: # %entry 833; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0] 834; SSSE3-NEXT: pand %xmm4, %xmm3 835; SSSE3-NEXT: pand %xmm4, %xmm2 836; SSSE3-NEXT: packuswb %xmm3, %xmm2 837; SSSE3-NEXT: pand %xmm4, %xmm1 838; SSSE3-NEXT: pand %xmm4, %xmm0 839; SSSE3-NEXT: packuswb %xmm1, %xmm0 840; SSSE3-NEXT: packuswb %xmm2, %xmm0 841; SSSE3-NEXT: movdqu %xmm0, (%rax) 842; SSSE3-NEXT: retq 843; 844; SSE41-LABEL: trunc16i32_16i8: 845; SSE41: # %bb.0: # %entry 846; SSE41-NEXT: movdqa {{.*#+}} xmm4 = [255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0] 847; SSE41-NEXT: pand %xmm4, %xmm3 848; SSE41-NEXT: pand %xmm4, %xmm2 849; SSE41-NEXT: packusdw %xmm3, %xmm2 850; SSE41-NEXT: pand %xmm4, %xmm1 851; SSE41-NEXT: pand %xmm4, %xmm0 852; SSE41-NEXT: packusdw %xmm1, %xmm0 853; SSE41-NEXT: packuswb %xmm2, %xmm0 854; SSE41-NEXT: movdqu %xmm0, (%rax) 855; SSE41-NEXT: retq 856; 857; AVX1-LABEL: trunc16i32_16i8: 858; AVX1: # %bb.0: # %entry 859; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255] 860; AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1 861; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm3 862; AVX1-NEXT: vpackusdw %xmm3, %xmm1, %xmm1 863; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0 864; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 865; AVX1-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 866; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 867; AVX1-NEXT: vmovdqu %xmm0, (%rax) 868; AVX1-NEXT: vzeroupper 869; AVX1-NEXT: retq 870; 871; AVX2-LABEL: trunc16i32_16i8: 872; AVX2: # %bb.0: # %entry 873; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31] 874; AVX2-NEXT: vpshufb %ymm2, %ymm1, %ymm1 875; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3] 876; AVX2-NEXT: vmovdqa {{.*#+}} xmm3 = [255,255,255,255,255,255,255,255] 877; AVX2-NEXT: vpand %xmm3, %xmm1, %xmm1 878; AVX2-NEXT: vpshufb %ymm2, %ymm0, %ymm0 879; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 880; AVX2-NEXT: vpand %xmm3, %xmm0, %xmm0 881; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 882; AVX2-NEXT: vmovdqu %xmm0, (%rax) 883; AVX2-NEXT: vzeroupper 884; AVX2-NEXT: retq 885; 886; AVX512-LABEL: trunc16i32_16i8: 887; AVX512: # %bb.0: # %entry 888; AVX512-NEXT: vpmovdb %zmm0, (%rax) 889; AVX512-NEXT: vzeroupper 890; AVX512-NEXT: retq 891entry: 892 %0 = trunc <16 x i32> %a to <16 x i8> 893 store <16 x i8> %0, <16 x i8>* undef, align 4 894 ret void 895} 896 897define void @trunc16i32_16i8_ashr(<16 x i32> %a) { 898; SSE-LABEL: trunc16i32_16i8_ashr: 899; SSE: # %bb.0: # %entry 900; SSE-NEXT: psrad $24, %xmm1 901; SSE-NEXT: psrad $24, %xmm0 902; SSE-NEXT: packssdw %xmm1, %xmm0 903; SSE-NEXT: psrad $24, %xmm3 904; SSE-NEXT: psrad $24, %xmm2 905; SSE-NEXT: packssdw %xmm3, %xmm2 906; SSE-NEXT: packsswb %xmm2, %xmm0 907; SSE-NEXT: movdqu %xmm0, (%rax) 908; SSE-NEXT: retq 909; 910; AVX1-LABEL: trunc16i32_16i8_ashr: 911; AVX1: # %bb.0: # %entry 912; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 913; AVX1-NEXT: vpsrad $24, %xmm2, %xmm2 914; AVX1-NEXT: vpsrad $24, %xmm0, %xmm0 915; AVX1-NEXT: vpackssdw %xmm2, %xmm0, %xmm0 916; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 917; AVX1-NEXT: vpsrad $24, %xmm2, %xmm2 918; AVX1-NEXT: vpsrad $24, %xmm1, %xmm1 919; AVX1-NEXT: vpackssdw %xmm2, %xmm1, %xmm1 920; AVX1-NEXT: vpacksswb %xmm1, %xmm0, %xmm0 921; AVX1-NEXT: vmovdqu %xmm0, (%rax) 922; AVX1-NEXT: vzeroupper 923; AVX1-NEXT: retq 924; 925; AVX2-LABEL: trunc16i32_16i8_ashr: 926; AVX2: # %bb.0: # %entry 927; AVX2-NEXT: vpsrad $24, %ymm1, %ymm1 928; AVX2-NEXT: vpsrad $24, %ymm0, %ymm0 929; AVX2-NEXT: vpackssdw %ymm1, %ymm0, %ymm0 930; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 931; AVX2-NEXT: vpacksswb %xmm1, %xmm0, %xmm0 932; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 933; AVX2-NEXT: vmovdqu %xmm0, (%rax) 934; AVX2-NEXT: vzeroupper 935; AVX2-NEXT: retq 936; 937; AVX512-LABEL: trunc16i32_16i8_ashr: 938; AVX512: # %bb.0: # %entry 939; AVX512-NEXT: vpsrld $24, %zmm0, %zmm0 940; AVX512-NEXT: vpmovdb %zmm0, (%rax) 941; AVX512-NEXT: vzeroupper 942; AVX512-NEXT: retq 943entry: 944 %0 = ashr <16 x i32> %a, <i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24> 945 %1 = trunc <16 x i32> %0 to <16 x i8> 946 store <16 x i8> %1, <16 x i8>* undef, align 4 947 ret void 948} 949 950define void @trunc16i32_16i8_lshr(<16 x i32> %a) { 951; SSE2-LABEL: trunc16i32_16i8_lshr: 952; SSE2: # %bb.0: # %entry 953; SSE2-NEXT: psrld $24, %xmm1 954; SSE2-NEXT: psrld $24, %xmm0 955; SSE2-NEXT: packuswb %xmm1, %xmm0 956; SSE2-NEXT: psrld $24, %xmm3 957; SSE2-NEXT: psrld $24, %xmm2 958; SSE2-NEXT: packuswb %xmm3, %xmm2 959; SSE2-NEXT: packuswb %xmm2, %xmm0 960; SSE2-NEXT: movdqu %xmm0, (%rax) 961; SSE2-NEXT: retq 962; 963; SSSE3-LABEL: trunc16i32_16i8_lshr: 964; SSSE3: # %bb.0: # %entry 965; SSSE3-NEXT: psrld $24, %xmm1 966; SSSE3-NEXT: psrld $24, %xmm0 967; SSSE3-NEXT: packuswb %xmm1, %xmm0 968; SSSE3-NEXT: psrld $24, %xmm3 969; SSSE3-NEXT: psrld $24, %xmm2 970; SSSE3-NEXT: packuswb %xmm3, %xmm2 971; SSSE3-NEXT: packuswb %xmm2, %xmm0 972; SSSE3-NEXT: movdqu %xmm0, (%rax) 973; SSSE3-NEXT: retq 974; 975; SSE41-LABEL: trunc16i32_16i8_lshr: 976; SSE41: # %bb.0: # %entry 977; SSE41-NEXT: psrld $24, %xmm1 978; SSE41-NEXT: psrld $24, %xmm0 979; SSE41-NEXT: packusdw %xmm1, %xmm0 980; SSE41-NEXT: psrld $24, %xmm3 981; SSE41-NEXT: psrld $24, %xmm2 982; SSE41-NEXT: packusdw %xmm3, %xmm2 983; SSE41-NEXT: packuswb %xmm2, %xmm0 984; SSE41-NEXT: movdqu %xmm0, (%rax) 985; SSE41-NEXT: retq 986; 987; AVX1-LABEL: trunc16i32_16i8_lshr: 988; AVX1: # %bb.0: # %entry 989; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 990; AVX1-NEXT: vpsrld $24, %xmm2, %xmm2 991; AVX1-NEXT: vpsrld $24, %xmm0, %xmm0 992; AVX1-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 993; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 994; AVX1-NEXT: vpsrld $24, %xmm2, %xmm2 995; AVX1-NEXT: vpsrld $24, %xmm1, %xmm1 996; AVX1-NEXT: vpackusdw %xmm2, %xmm1, %xmm1 997; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 998; AVX1-NEXT: vmovdqu %xmm0, (%rax) 999; AVX1-NEXT: vzeroupper 1000; AVX1-NEXT: retq 1001; 1002; AVX2-LABEL: trunc16i32_16i8_lshr: 1003; AVX2: # %bb.0: # %entry 1004; AVX2-NEXT: vpsrld $24, %ymm1, %ymm1 1005; AVX2-NEXT: vpsrld $24, %ymm0, %ymm0 1006; AVX2-NEXT: vpackusdw %ymm1, %ymm0, %ymm0 1007; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 1008; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1009; AVX2-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,1,3] 1010; AVX2-NEXT: vmovdqu %xmm0, (%rax) 1011; AVX2-NEXT: vzeroupper 1012; AVX2-NEXT: retq 1013; 1014; AVX512-LABEL: trunc16i32_16i8_lshr: 1015; AVX512: # %bb.0: # %entry 1016; AVX512-NEXT: vpsrld $24, %zmm0, %zmm0 1017; AVX512-NEXT: vpmovdb %zmm0, (%rax) 1018; AVX512-NEXT: vzeroupper 1019; AVX512-NEXT: retq 1020entry: 1021 %0 = lshr <16 x i32> %a, <i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24, i32 24> 1022 %1 = trunc <16 x i32> %0 to <16 x i8> 1023 store <16 x i8> %1, <16 x i8>* undef, align 4 1024 ret void 1025} 1026 1027;PR25684 1028define void @trunc16i16_16i8(<16 x i16> %a) { 1029; SSE-LABEL: trunc16i16_16i8: 1030; SSE: # %bb.0: # %entry 1031; SSE-NEXT: movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1032; SSE-NEXT: pand %xmm2, %xmm1 1033; SSE-NEXT: pand %xmm2, %xmm0 1034; SSE-NEXT: packuswb %xmm1, %xmm0 1035; SSE-NEXT: movdqu %xmm0, (%rax) 1036; SSE-NEXT: retq 1037; 1038; AVX1-LABEL: trunc16i16_16i8: 1039; AVX1: # %bb.0: # %entry 1040; AVX1-NEXT: vandps {{.*}}(%rip), %ymm0, %ymm0 1041; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 1042; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1043; AVX1-NEXT: vmovdqu %xmm0, (%rax) 1044; AVX1-NEXT: vzeroupper 1045; AVX1-NEXT: retq 1046; 1047; AVX2-LABEL: trunc16i16_16i8: 1048; AVX2: # %bb.0: # %entry 1049; AVX2-NEXT: vpand {{.*}}(%rip), %ymm0, %ymm0 1050; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 1051; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1052; AVX2-NEXT: vmovdqu %xmm0, (%rax) 1053; AVX2-NEXT: vzeroupper 1054; AVX2-NEXT: retq 1055; 1056; AVX512F-LABEL: trunc16i16_16i8: 1057; AVX512F: # %bb.0: # %entry 1058; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1059; AVX512F-NEXT: vpmovdb %zmm0, (%rax) 1060; AVX512F-NEXT: vzeroupper 1061; AVX512F-NEXT: retq 1062; 1063; AVX512VL-LABEL: trunc16i16_16i8: 1064; AVX512VL: # %bb.0: # %entry 1065; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1066; AVX512VL-NEXT: vpmovdb %zmm0, (%rax) 1067; AVX512VL-NEXT: vzeroupper 1068; AVX512VL-NEXT: retq 1069; 1070; AVX512BW-LABEL: trunc16i16_16i8: 1071; AVX512BW: # %bb.0: # %entry 1072; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1073; AVX512BW-NEXT: vpmovwb %zmm0, %ymm0 1074; AVX512BW-NEXT: vmovdqu %xmm0, (%rax) 1075; AVX512BW-NEXT: vzeroupper 1076; AVX512BW-NEXT: retq 1077; 1078; AVX512BWVL-LABEL: trunc16i16_16i8: 1079; AVX512BWVL: # %bb.0: # %entry 1080; AVX512BWVL-NEXT: vpmovwb %ymm0, (%rax) 1081; AVX512BWVL-NEXT: vzeroupper 1082; AVX512BWVL-NEXT: retq 1083entry: 1084 %0 = trunc <16 x i16> %a to <16 x i8> 1085 store <16 x i8> %0, <16 x i8>* undef, align 4 1086 ret void 1087} 1088 1089define void @trunc16i16_16i8_ashr(<16 x i16> %a) { 1090; SSE-LABEL: trunc16i16_16i8_ashr: 1091; SSE: # %bb.0: # %entry 1092; SSE-NEXT: psraw $8, %xmm1 1093; SSE-NEXT: psraw $8, %xmm0 1094; SSE-NEXT: packsswb %xmm1, %xmm0 1095; SSE-NEXT: movdqu %xmm0, (%rax) 1096; SSE-NEXT: retq 1097; 1098; AVX1-LABEL: trunc16i16_16i8_ashr: 1099; AVX1: # %bb.0: # %entry 1100; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 1101; AVX1-NEXT: vpsraw $8, %xmm1, %xmm1 1102; AVX1-NEXT: vpsraw $8, %xmm0, %xmm0 1103; AVX1-NEXT: vpacksswb %xmm1, %xmm0, %xmm0 1104; AVX1-NEXT: vmovdqu %xmm0, (%rax) 1105; AVX1-NEXT: vzeroupper 1106; AVX1-NEXT: retq 1107; 1108; AVX2-LABEL: trunc16i16_16i8_ashr: 1109; AVX2: # %bb.0: # %entry 1110; AVX2-NEXT: vpsraw $8, %ymm0, %ymm0 1111; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 1112; AVX2-NEXT: vpacksswb %xmm1, %xmm0, %xmm0 1113; AVX2-NEXT: vmovdqu %xmm0, (%rax) 1114; AVX2-NEXT: vzeroupper 1115; AVX2-NEXT: retq 1116; 1117; AVX512F-LABEL: trunc16i16_16i8_ashr: 1118; AVX512F: # %bb.0: # %entry 1119; AVX512F-NEXT: vpsrlw $8, %ymm0, %ymm0 1120; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1121; AVX512F-NEXT: vpmovdb %zmm0, (%rax) 1122; AVX512F-NEXT: vzeroupper 1123; AVX512F-NEXT: retq 1124; 1125; AVX512VL-LABEL: trunc16i16_16i8_ashr: 1126; AVX512VL: # %bb.0: # %entry 1127; AVX512VL-NEXT: vpsrlw $8, %ymm0, %ymm0 1128; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1129; AVX512VL-NEXT: vpmovdb %zmm0, (%rax) 1130; AVX512VL-NEXT: vzeroupper 1131; AVX512VL-NEXT: retq 1132; 1133; AVX512BW-LABEL: trunc16i16_16i8_ashr: 1134; AVX512BW: # %bb.0: # %entry 1135; AVX512BW-NEXT: vpsraw $8, %ymm0, %ymm0 1136; AVX512BW-NEXT: vpmovwb %zmm0, %ymm0 1137; AVX512BW-NEXT: vmovdqu %xmm0, (%rax) 1138; AVX512BW-NEXT: vzeroupper 1139; AVX512BW-NEXT: retq 1140; 1141; AVX512BWVL-LABEL: trunc16i16_16i8_ashr: 1142; AVX512BWVL: # %bb.0: # %entry 1143; AVX512BWVL-NEXT: vpsrlw $8, %ymm0, %ymm0 1144; AVX512BWVL-NEXT: vpmovwb %ymm0, (%rax) 1145; AVX512BWVL-NEXT: vzeroupper 1146; AVX512BWVL-NEXT: retq 1147entry: 1148 %0 = ashr <16 x i16> %a, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8> 1149 %1 = trunc <16 x i16> %0 to <16 x i8> 1150 store <16 x i8> %1, <16 x i8>* undef, align 4 1151 ret void 1152} 1153 1154define void @trunc16i16_16i8_lshr(<16 x i16> %a) { 1155; SSE-LABEL: trunc16i16_16i8_lshr: 1156; SSE: # %bb.0: # %entry 1157; SSE-NEXT: psrlw $8, %xmm1 1158; SSE-NEXT: psrlw $8, %xmm0 1159; SSE-NEXT: packuswb %xmm1, %xmm0 1160; SSE-NEXT: movdqu %xmm0, (%rax) 1161; SSE-NEXT: retq 1162; 1163; AVX1-LABEL: trunc16i16_16i8_lshr: 1164; AVX1: # %bb.0: # %entry 1165; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm1 1166; AVX1-NEXT: vpsrlw $8, %xmm1, %xmm1 1167; AVX1-NEXT: vpsrlw $8, %xmm0, %xmm0 1168; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1169; AVX1-NEXT: vmovdqu %xmm0, (%rax) 1170; AVX1-NEXT: vzeroupper 1171; AVX1-NEXT: retq 1172; 1173; AVX2-LABEL: trunc16i16_16i8_lshr: 1174; AVX2: # %bb.0: # %entry 1175; AVX2-NEXT: vpsrlw $8, %ymm0, %ymm0 1176; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 1177; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1178; AVX2-NEXT: vmovdqu %xmm0, (%rax) 1179; AVX2-NEXT: vzeroupper 1180; AVX2-NEXT: retq 1181; 1182; AVX512F-LABEL: trunc16i16_16i8_lshr: 1183; AVX512F: # %bb.0: # %entry 1184; AVX512F-NEXT: vpsrlw $8, %ymm0, %ymm0 1185; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1186; AVX512F-NEXT: vpmovdb %zmm0, (%rax) 1187; AVX512F-NEXT: vzeroupper 1188; AVX512F-NEXT: retq 1189; 1190; AVX512VL-LABEL: trunc16i16_16i8_lshr: 1191; AVX512VL: # %bb.0: # %entry 1192; AVX512VL-NEXT: vpsrlw $8, %ymm0, %ymm0 1193; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1194; AVX512VL-NEXT: vpmovdb %zmm0, (%rax) 1195; AVX512VL-NEXT: vzeroupper 1196; AVX512VL-NEXT: retq 1197; 1198; AVX512BW-LABEL: trunc16i16_16i8_lshr: 1199; AVX512BW: # %bb.0: # %entry 1200; AVX512BW-NEXT: vpsrlw $8, %ymm0, %ymm0 1201; AVX512BW-NEXT: vpmovwb %zmm0, %ymm0 1202; AVX512BW-NEXT: vmovdqu %xmm0, (%rax) 1203; AVX512BW-NEXT: vzeroupper 1204; AVX512BW-NEXT: retq 1205; 1206; AVX512BWVL-LABEL: trunc16i16_16i8_lshr: 1207; AVX512BWVL: # %bb.0: # %entry 1208; AVX512BWVL-NEXT: vpsrlw $8, %ymm0, %ymm0 1209; AVX512BWVL-NEXT: vpmovwb %ymm0, (%rax) 1210; AVX512BWVL-NEXT: vzeroupper 1211; AVX512BWVL-NEXT: retq 1212entry: 1213 %0 = lshr <16 x i16> %a, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8> 1214 %1 = trunc <16 x i16> %0 to <16 x i8> 1215 store <16 x i8> %1, <16 x i8>* undef, align 4 1216 ret void 1217} 1218 1219define void @trunc32i16_32i8(<32 x i16> %a) { 1220; SSE-LABEL: trunc32i16_32i8: 1221; SSE: # %bb.0: # %entry 1222; SSE-NEXT: movdqa {{.*#+}} xmm4 = [255,255,255,255,255,255,255,255] 1223; SSE-NEXT: pand %xmm4, %xmm1 1224; SSE-NEXT: pand %xmm4, %xmm0 1225; SSE-NEXT: packuswb %xmm1, %xmm0 1226; SSE-NEXT: pand %xmm4, %xmm3 1227; SSE-NEXT: pand %xmm4, %xmm2 1228; SSE-NEXT: packuswb %xmm3, %xmm2 1229; SSE-NEXT: movdqu %xmm2, (%rax) 1230; SSE-NEXT: movdqu %xmm0, (%rax) 1231; SSE-NEXT: retq 1232; 1233; AVX1-LABEL: trunc32i16_32i8: 1234; AVX1: # %bb.0: # %entry 1235; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255] 1236; AVX1-NEXT: vandps %ymm2, %ymm0, %ymm0 1237; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm3 1238; AVX1-NEXT: vpackuswb %xmm3, %xmm0, %xmm0 1239; AVX1-NEXT: vandps %ymm2, %ymm1, %ymm1 1240; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 1241; AVX1-NEXT: vpackuswb %xmm2, %xmm1, %xmm1 1242; AVX1-NEXT: vmovdqu %xmm1, (%rax) 1243; AVX1-NEXT: vmovdqu %xmm0, (%rax) 1244; AVX1-NEXT: vzeroupper 1245; AVX1-NEXT: retq 1246; 1247; AVX2-LABEL: trunc32i16_32i8: 1248; AVX2: # %bb.0: # %entry 1249; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255] 1250; AVX2-NEXT: vpand %ymm2, %ymm1, %ymm1 1251; AVX2-NEXT: vpand %ymm2, %ymm0, %ymm0 1252; AVX2-NEXT: vperm2i128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 1253; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1254; AVX2-NEXT: vpackuswb %ymm2, %ymm0, %ymm0 1255; AVX2-NEXT: vmovdqu %ymm0, (%rax) 1256; AVX2-NEXT: vzeroupper 1257; AVX2-NEXT: retq 1258; 1259; AVX512F-LABEL: trunc32i16_32i8: 1260; AVX512F: # %bb.0: # %entry 1261; AVX512F-NEXT: vextracti64x4 $1, %zmm0, %ymm1 1262; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero 1263; AVX512F-NEXT: vpmovdb %zmm1, (%rax) 1264; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1265; AVX512F-NEXT: vpmovdb %zmm0, (%rax) 1266; AVX512F-NEXT: vzeroupper 1267; AVX512F-NEXT: retq 1268; 1269; AVX512VL-LABEL: trunc32i16_32i8: 1270; AVX512VL: # %bb.0: # %entry 1271; AVX512VL-NEXT: vextracti64x4 $1, %zmm0, %ymm1 1272; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm1 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero 1273; AVX512VL-NEXT: vpmovdb %zmm1, (%rax) 1274; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1275; AVX512VL-NEXT: vpmovdb %zmm0, (%rax) 1276; AVX512VL-NEXT: vzeroupper 1277; AVX512VL-NEXT: retq 1278; 1279; AVX512BW-LABEL: trunc32i16_32i8: 1280; AVX512BW: # %bb.0: # %entry 1281; AVX512BW-NEXT: vpmovwb %zmm0, (%rax) 1282; AVX512BW-NEXT: vzeroupper 1283; AVX512BW-NEXT: retq 1284; 1285; AVX512BWVL-LABEL: trunc32i16_32i8: 1286; AVX512BWVL: # %bb.0: # %entry 1287; AVX512BWVL-NEXT: vpmovwb %zmm0, (%rax) 1288; AVX512BWVL-NEXT: vzeroupper 1289; AVX512BWVL-NEXT: retq 1290entry: 1291 %0 = trunc <32 x i16> %a to <32 x i8> 1292 store <32 x i8> %0, <32 x i8>* undef, align 4 1293 ret void 1294} 1295 1296define <8 x i32> @trunc2x4i64_8i32(<4 x i64> %a, <4 x i64> %b) { 1297; SSE-LABEL: trunc2x4i64_8i32: 1298; SSE: # %bb.0: # %entry 1299; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] 1300; SSE-NEXT: shufps {{.*#+}} xmm2 = xmm2[0,2],xmm3[0,2] 1301; SSE-NEXT: movaps %xmm2, %xmm1 1302; SSE-NEXT: retq 1303; 1304; AVX1-LABEL: trunc2x4i64_8i32: 1305; AVX1: # %bb.0: # %entry 1306; AVX1-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 1307; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 1308; AVX1-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] 1309; AVX1-NEXT: retq 1310; 1311; AVX2-SLOW-LABEL: trunc2x4i64_8i32: 1312; AVX2-SLOW: # %bb.0: # %entry 1313; AVX2-SLOW-NEXT: vperm2f128 {{.*#+}} ymm2 = ymm0[2,3],ymm1[2,3] 1314; AVX2-SLOW-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 1315; AVX2-SLOW-NEXT: vshufps {{.*#+}} ymm0 = ymm0[0,2],ymm2[0,2],ymm0[4,6],ymm2[4,6] 1316; AVX2-SLOW-NEXT: retq 1317; 1318; AVX2-FAST-LABEL: trunc2x4i64_8i32: 1319; AVX2-FAST: # %bb.0: # %entry 1320; AVX2-FAST-NEXT: vmovaps {{.*#+}} ymm2 = [0,2,4,6,4,6,6,7] 1321; AVX2-FAST-NEXT: vpermps %ymm0, %ymm2, %ymm0 1322; AVX2-FAST-NEXT: vpermps %ymm1, %ymm2, %ymm1 1323; AVX2-FAST-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 1324; AVX2-FAST-NEXT: retq 1325; 1326; AVX512F-LABEL: trunc2x4i64_8i32: 1327; AVX512F: # %bb.0: # %entry 1328; AVX512F-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 1329; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1330; AVX512F-NEXT: vpmovqd %zmm0, %ymm0 1331; AVX512F-NEXT: vpmovqd %zmm1, %ymm1 1332; AVX512F-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1333; AVX512F-NEXT: retq 1334; 1335; AVX512VL-LABEL: trunc2x4i64_8i32: 1336; AVX512VL: # %bb.0: # %entry 1337; AVX512VL-NEXT: vpmovqd %ymm0, %xmm0 1338; AVX512VL-NEXT: vpmovqd %ymm1, %xmm1 1339; AVX512VL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1340; AVX512VL-NEXT: retq 1341; 1342; AVX512BW-LABEL: trunc2x4i64_8i32: 1343; AVX512BW: # %bb.0: # %entry 1344; AVX512BW-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 1345; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1346; AVX512BW-NEXT: vpmovqd %zmm0, %ymm0 1347; AVX512BW-NEXT: vpmovqd %zmm1, %ymm1 1348; AVX512BW-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1349; AVX512BW-NEXT: retq 1350; 1351; AVX512BWVL-LABEL: trunc2x4i64_8i32: 1352; AVX512BWVL: # %bb.0: # %entry 1353; AVX512BWVL-NEXT: vpmovqd %ymm0, %xmm0 1354; AVX512BWVL-NEXT: vpmovqd %ymm1, %xmm1 1355; AVX512BWVL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1356; AVX512BWVL-NEXT: retq 1357entry: 1358 %0 = trunc <4 x i64> %a to <4 x i32> 1359 %1 = trunc <4 x i64> %b to <4 x i32> 1360 %2 = shufflevector <4 x i32> %0, <4 x i32> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1361 ret <8 x i32> %2 1362} 1363 1364define <8 x i16> @trunc2x4i64_8i16(<4 x i64> %a, <4 x i64> %b) { 1365; SSE2-LABEL: trunc2x4i64_8i16: 1366; SSE2: # %bb.0: # %entry 1367; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 1368; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7] 1369; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1370; SSE2-NEXT: pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7] 1371; SSE2-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1] 1372; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3] 1373; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7] 1374; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 1375; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7] 1376; SSE2-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1377; SSE2-NEXT: movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1] 1378; SSE2-NEXT: retq 1379; 1380; SSSE3-LABEL: trunc2x4i64_8i16: 1381; SSSE3: # %bb.0: # %entry 1382; SSSE3-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 1383; SSSE3-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7] 1384; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1385; SSSE3-NEXT: pshuflw {{.*#+}} xmm4 = xmm0[0,2,2,3,4,5,6,7] 1386; SSSE3-NEXT: punpckldq {{.*#+}} xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1] 1387; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm3[0,2,2,3] 1388; SSSE3-NEXT: pshuflw {{.*#+}} xmm1 = xmm0[0,1,0,2,4,5,6,7] 1389; SSSE3-NEXT: pshufd {{.*#+}} xmm0 = xmm2[0,2,2,3] 1390; SSSE3-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,1,0,2,4,5,6,7] 1391; SSSE3-NEXT: punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] 1392; SSSE3-NEXT: movsd {{.*#+}} xmm0 = xmm4[0],xmm0[1] 1393; SSSE3-NEXT: retq 1394; 1395; SSE41-LABEL: trunc2x4i64_8i16: 1396; SSE41: # %bb.0: # %entry 1397; SSE41-NEXT: pxor %xmm4, %xmm4 1398; SSE41-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1,2,3],xmm3[4],xmm4[5,6,7] 1399; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1,2,3],xmm2[4],xmm4[5,6,7] 1400; SSE41-NEXT: packusdw %xmm3, %xmm2 1401; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1,2,3],xmm1[4],xmm4[5,6,7] 1402; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1,2,3],xmm0[4],xmm4[5,6,7] 1403; SSE41-NEXT: packusdw %xmm1, %xmm0 1404; SSE41-NEXT: packusdw %xmm2, %xmm0 1405; SSE41-NEXT: retq 1406; 1407; AVX1-LABEL: trunc2x4i64_8i16: 1408; AVX1: # %bb.0: # %entry 1409; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 1410; AVX1-NEXT: vpxor %xmm3, %xmm3, %xmm3 1411; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7] 1412; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3],xmm1[4],xmm3[5,6,7] 1413; AVX1-NEXT: vpackusdw %xmm2, %xmm1, %xmm1 1414; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 1415; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7] 1416; AVX1-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm3[1,2,3],xmm0[4],xmm3[5,6,7] 1417; AVX1-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 1418; AVX1-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 1419; AVX1-NEXT: vzeroupper 1420; AVX1-NEXT: retq 1421; 1422; AVX2-LABEL: trunc2x4i64_8i16: 1423; AVX2: # %bb.0: # %entry 1424; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm2 1425; AVX2-NEXT: vpxor %xmm3, %xmm3, %xmm3 1426; AVX2-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7] 1427; AVX2-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm3[1,2,3],xmm1[4],xmm3[5,6,7] 1428; AVX2-NEXT: vpackusdw %xmm2, %xmm1, %xmm1 1429; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 1430; AVX2-NEXT: vpblendw {{.*#+}} xmm2 = xmm2[0],xmm3[1,2,3],xmm2[4],xmm3[5,6,7] 1431; AVX2-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm3[1,2,3],xmm0[4],xmm3[5,6,7] 1432; AVX2-NEXT: vpackusdw %xmm2, %xmm0, %xmm0 1433; AVX2-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 1434; AVX2-NEXT: vzeroupper 1435; AVX2-NEXT: retq 1436; 1437; AVX512F-LABEL: trunc2x4i64_8i16: 1438; AVX512F: # %bb.0: # %entry 1439; AVX512F-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 1440; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1441; AVX512F-NEXT: vpmovqw %zmm0, %xmm0 1442; AVX512F-NEXT: vpmovqw %zmm1, %xmm1 1443; AVX512F-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1444; AVX512F-NEXT: vzeroupper 1445; AVX512F-NEXT: retq 1446; 1447; AVX512VL-LABEL: trunc2x4i64_8i16: 1448; AVX512VL: # %bb.0: # %entry 1449; AVX512VL-NEXT: vpmovqw %ymm0, %xmm0 1450; AVX512VL-NEXT: vpmovqw %ymm1, %xmm1 1451; AVX512VL-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1452; AVX512VL-NEXT: vzeroupper 1453; AVX512VL-NEXT: retq 1454; 1455; AVX512BW-LABEL: trunc2x4i64_8i16: 1456; AVX512BW: # %bb.0: # %entry 1457; AVX512BW-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 1458; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1459; AVX512BW-NEXT: vpmovqw %zmm0, %xmm0 1460; AVX512BW-NEXT: vpmovqw %zmm1, %xmm1 1461; AVX512BW-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1462; AVX512BW-NEXT: vzeroupper 1463; AVX512BW-NEXT: retq 1464; 1465; AVX512BWVL-LABEL: trunc2x4i64_8i16: 1466; AVX512BWVL: # %bb.0: # %entry 1467; AVX512BWVL-NEXT: vpmovqw %ymm0, %xmm0 1468; AVX512BWVL-NEXT: vpmovqw %ymm1, %xmm1 1469; AVX512BWVL-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1470; AVX512BWVL-NEXT: vzeroupper 1471; AVX512BWVL-NEXT: retq 1472entry: 1473 %0 = trunc <4 x i64> %a to <4 x i16> 1474 %1 = trunc <4 x i64> %b to <4 x i16> 1475 %2 = shufflevector <4 x i16> %0, <4 x i16> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1476 ret <8 x i16> %2 1477} 1478 1479define <4 x i32> @trunc2x2i64_4i32(<2 x i64> %a, <2 x i64> %b) { 1480; SSE-LABEL: trunc2x2i64_4i32: 1481; SSE: # %bb.0: # %entry 1482; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] 1483; SSE-NEXT: retq 1484; 1485; AVX-LABEL: trunc2x2i64_4i32: 1486; AVX: # %bb.0: # %entry 1487; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] 1488; AVX-NEXT: retq 1489; 1490; AVX512F-LABEL: trunc2x2i64_4i32: 1491; AVX512F: # %bb.0: # %entry 1492; AVX512F-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] 1493; AVX512F-NEXT: retq 1494; 1495; AVX512VL-LABEL: trunc2x2i64_4i32: 1496; AVX512VL: # %bb.0: # %entry 1497; AVX512VL-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 1498; AVX512VL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1499; AVX512VL-NEXT: vpmovqd %ymm0, %xmm0 1500; AVX512VL-NEXT: vzeroupper 1501; AVX512VL-NEXT: retq 1502; 1503; AVX512BW-LABEL: trunc2x2i64_4i32: 1504; AVX512BW: # %bb.0: # %entry 1505; AVX512BW-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2] 1506; AVX512BW-NEXT: retq 1507; 1508; AVX512BWVL-LABEL: trunc2x2i64_4i32: 1509; AVX512BWVL: # %bb.0: # %entry 1510; AVX512BWVL-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 1511; AVX512BWVL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1512; AVX512BWVL-NEXT: vpmovqd %ymm0, %xmm0 1513; AVX512BWVL-NEXT: vzeroupper 1514; AVX512BWVL-NEXT: retq 1515entry: 1516 %0 = trunc <2 x i64> %a to <2 x i32> 1517 %1 = trunc <2 x i64> %b to <2 x i32> 1518 %2 = shufflevector <2 x i32> %0, <2 x i32> %1, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 1519 ret <4 x i32> %2 1520} 1521 1522define i64 @trunc2i64_i64(<2 x i64> %inval) { 1523; SSE-LABEL: trunc2i64_i64: 1524; SSE: # %bb.0: # %entry 1525; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1526; SSE-NEXT: movq %xmm0, %rax 1527; SSE-NEXT: retq 1528; 1529; AVX-LABEL: trunc2i64_i64: 1530; AVX: # %bb.0: # %entry 1531; AVX-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1532; AVX-NEXT: vmovq %xmm0, %rax 1533; AVX-NEXT: retq 1534; 1535; AVX512-LABEL: trunc2i64_i64: 1536; AVX512: # %bb.0: # %entry 1537; AVX512-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1538; AVX512-NEXT: vmovq %xmm0, %rax 1539; AVX512-NEXT: retq 1540entry: 1541 %0 = trunc <2 x i64> %inval to <2 x i32> 1542 %1 = bitcast <2 x i32> %0 to i64 1543 ret i64 %1 1544} 1545 1546define <8 x i16> @trunc2x4i32_8i16(<4 x i32> %a, <4 x i32> %b) { 1547; SSE2-LABEL: trunc2x4i32_8i16: 1548; SSE2: # %bb.0: # %entry 1549; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7] 1550; SSE2-NEXT: pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7] 1551; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] 1552; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7] 1553; SSE2-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7] 1554; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1555; SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1556; SSE2-NEXT: retq 1557; 1558; SSSE3-LABEL: trunc2x4i32_8i16: 1559; SSSE3: # %bb.0: # %entry 1560; SSSE3-NEXT: movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 1561; SSSE3-NEXT: pshufb %xmm2, %xmm1 1562; SSSE3-NEXT: pshufb %xmm2, %xmm0 1563; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1564; SSSE3-NEXT: retq 1565; 1566; SSE41-LABEL: trunc2x4i32_8i16: 1567; SSE41: # %bb.0: # %entry 1568; SSE41-NEXT: pxor %xmm2, %xmm2 1569; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] 1570; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] 1571; SSE41-NEXT: packusdw %xmm1, %xmm0 1572; SSE41-NEXT: retq 1573; 1574; AVX-LABEL: trunc2x4i32_8i16: 1575; AVX: # %bb.0: # %entry 1576; AVX-NEXT: vpxor %xmm2, %xmm2, %xmm2 1577; AVX-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] 1578; AVX-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] 1579; AVX-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 1580; AVX-NEXT: retq 1581; 1582; AVX512F-LABEL: trunc2x4i32_8i16: 1583; AVX512F: # %bb.0: # %entry 1584; AVX512F-NEXT: vpxor %xmm2, %xmm2, %xmm2 1585; AVX512F-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] 1586; AVX512F-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] 1587; AVX512F-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 1588; AVX512F-NEXT: retq 1589; 1590; AVX512VL-LABEL: trunc2x4i32_8i16: 1591; AVX512VL: # %bb.0: # %entry 1592; AVX512VL-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 1593; AVX512VL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1594; AVX512VL-NEXT: vpmovdw %ymm0, %xmm0 1595; AVX512VL-NEXT: vzeroupper 1596; AVX512VL-NEXT: retq 1597; 1598; AVX512BW-LABEL: trunc2x4i32_8i16: 1599; AVX512BW: # %bb.0: # %entry 1600; AVX512BW-NEXT: vpxor %xmm2, %xmm2, %xmm2 1601; AVX512BW-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0],xmm2[1],xmm1[2],xmm2[3],xmm1[4],xmm2[5],xmm1[6],xmm2[7] 1602; AVX512BW-NEXT: vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7] 1603; AVX512BW-NEXT: vpackusdw %xmm1, %xmm0, %xmm0 1604; AVX512BW-NEXT: retq 1605; 1606; AVX512BWVL-LABEL: trunc2x4i32_8i16: 1607; AVX512BWVL: # %bb.0: # %entry 1608; AVX512BWVL-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 1609; AVX512BWVL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1610; AVX512BWVL-NEXT: vpmovdw %ymm0, %xmm0 1611; AVX512BWVL-NEXT: vzeroupper 1612; AVX512BWVL-NEXT: retq 1613entry: 1614 %0 = trunc <4 x i32> %a to <4 x i16> 1615 %1 = trunc <4 x i32> %b to <4 x i16> 1616 %2 = shufflevector <4 x i16> %0, <4 x i16> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 1617 ret <8 x i16> %2 1618} 1619 1620; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524 1621define i64 @trunc4i32_i64(<4 x i32> %inval) { 1622; SSE2-LABEL: trunc4i32_i64: 1623; SSE2: # %bb.0: # %entry 1624; SSE2-NEXT: pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7] 1625; SSE2-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7] 1626; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1627; SSE2-NEXT: movq %xmm0, %rax 1628; SSE2-NEXT: retq 1629; 1630; SSSE3-LABEL: trunc4i32_i64: 1631; SSSE3: # %bb.0: # %entry 1632; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u] 1633; SSSE3-NEXT: movq %xmm0, %rax 1634; SSSE3-NEXT: retq 1635; 1636; SSE41-LABEL: trunc4i32_i64: 1637; SSE41: # %bb.0: # %entry 1638; SSE41-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u] 1639; SSE41-NEXT: movq %xmm0, %rax 1640; SSE41-NEXT: retq 1641; 1642; AVX-LABEL: trunc4i32_i64: 1643; AVX: # %bb.0: # %entry 1644; AVX-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u] 1645; AVX-NEXT: vmovq %xmm0, %rax 1646; AVX-NEXT: retq 1647; 1648; AVX512F-LABEL: trunc4i32_i64: 1649; AVX512F: # %bb.0: # %entry 1650; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u] 1651; AVX512F-NEXT: vmovq %xmm0, %rax 1652; AVX512F-NEXT: retq 1653; 1654; AVX512VL-LABEL: trunc4i32_i64: 1655; AVX512VL: # %bb.0: # %entry 1656; AVX512VL-NEXT: vpmovdw %xmm0, %xmm0 1657; AVX512VL-NEXT: vmovq %xmm0, %rax 1658; AVX512VL-NEXT: retq 1659; 1660; AVX512BW-LABEL: trunc4i32_i64: 1661; AVX512BW: # %bb.0: # %entry 1662; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,u,u,u,u,u,u,u,u] 1663; AVX512BW-NEXT: vmovq %xmm0, %rax 1664; AVX512BW-NEXT: retq 1665; 1666; AVX512BWVL-LABEL: trunc4i32_i64: 1667; AVX512BWVL: # %bb.0: # %entry 1668; AVX512BWVL-NEXT: vpmovdw %xmm0, %xmm0 1669; AVX512BWVL-NEXT: vmovq %xmm0, %rax 1670; AVX512BWVL-NEXT: retq 1671entry: 1672 %0 = trunc <4 x i32> %inval to <4 x i16> 1673 %1 = bitcast <4 x i16> %0 to i64 1674 ret i64 %1 1675} 1676 1677define <16 x i8> @trunc2x8i16_16i8(<8 x i16> %a, <8 x i16> %b) { 1678; SSE-LABEL: trunc2x8i16_16i8: 1679; SSE: # %bb.0: # %entry 1680; SSE-NEXT: movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1681; SSE-NEXT: pand %xmm2, %xmm1 1682; SSE-NEXT: pand %xmm2, %xmm0 1683; SSE-NEXT: packuswb %xmm1, %xmm0 1684; SSE-NEXT: retq 1685; 1686; AVX-LABEL: trunc2x8i16_16i8: 1687; AVX: # %bb.0: # %entry 1688; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1689; AVX-NEXT: vpand %xmm2, %xmm1, %xmm1 1690; AVX-NEXT: vpand %xmm2, %xmm0, %xmm0 1691; AVX-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1692; AVX-NEXT: retq 1693; 1694; AVX512F-LABEL: trunc2x8i16_16i8: 1695; AVX512F: # %bb.0: # %entry 1696; AVX512F-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1697; AVX512F-NEXT: vpand %xmm2, %xmm1, %xmm1 1698; AVX512F-NEXT: vpand %xmm2, %xmm0, %xmm0 1699; AVX512F-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1700; AVX512F-NEXT: retq 1701; 1702; AVX512VL-LABEL: trunc2x8i16_16i8: 1703; AVX512VL: # %bb.0: # %entry 1704; AVX512VL-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1705; AVX512VL-NEXT: vpand %xmm2, %xmm1, %xmm1 1706; AVX512VL-NEXT: vpand %xmm2, %xmm0, %xmm0 1707; AVX512VL-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1708; AVX512VL-NEXT: retq 1709; 1710; AVX512BW-LABEL: trunc2x8i16_16i8: 1711; AVX512BW: # %bb.0: # %entry 1712; AVX512BW-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1713; AVX512BW-NEXT: vpand %xmm2, %xmm1, %xmm1 1714; AVX512BW-NEXT: vpand %xmm2, %xmm0, %xmm0 1715; AVX512BW-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1716; AVX512BW-NEXT: retq 1717; 1718; AVX512BWVL-LABEL: trunc2x8i16_16i8: 1719; AVX512BWVL: # %bb.0: # %entry 1720; AVX512BWVL-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 1721; AVX512BWVL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1722; AVX512BWVL-NEXT: vpmovwb %ymm0, %xmm0 1723; AVX512BWVL-NEXT: vzeroupper 1724; AVX512BWVL-NEXT: retq 1725entry: 1726 %0 = trunc <8 x i16> %a to <8 x i8> 1727 %1 = trunc <8 x i16> %b to <8 x i8> 1728 %2 = shufflevector <8 x i8> %0, <8 x i8> %1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 1729 ret <16 x i8> %2 1730} 1731 1732; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524 1733define i64 @trunc8i16_i64(<8 x i16> %inval) { 1734; SSE2-LABEL: trunc8i16_i64: 1735; SSE2: # %bb.0: # %entry 1736; SSE2-NEXT: pand {{.*}}(%rip), %xmm0 1737; SSE2-NEXT: packuswb %xmm0, %xmm0 1738; SSE2-NEXT: movq %xmm0, %rax 1739; SSE2-NEXT: retq 1740; 1741; SSSE3-LABEL: trunc8i16_i64: 1742; SSSE3: # %bb.0: # %entry 1743; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1744; SSSE3-NEXT: movq %xmm0, %rax 1745; SSSE3-NEXT: retq 1746; 1747; SSE41-LABEL: trunc8i16_i64: 1748; SSE41: # %bb.0: # %entry 1749; SSE41-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1750; SSE41-NEXT: movq %xmm0, %rax 1751; SSE41-NEXT: retq 1752; 1753; AVX-LABEL: trunc8i16_i64: 1754; AVX: # %bb.0: # %entry 1755; AVX-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1756; AVX-NEXT: vmovq %xmm0, %rax 1757; AVX-NEXT: retq 1758; 1759; AVX512F-LABEL: trunc8i16_i64: 1760; AVX512F: # %bb.0: # %entry 1761; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1762; AVX512F-NEXT: vmovq %xmm0, %rax 1763; AVX512F-NEXT: retq 1764; 1765; AVX512VL-LABEL: trunc8i16_i64: 1766; AVX512VL: # %bb.0: # %entry 1767; AVX512VL-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1768; AVX512VL-NEXT: vmovq %xmm0, %rax 1769; AVX512VL-NEXT: retq 1770; 1771; AVX512BW-LABEL: trunc8i16_i64: 1772; AVX512BW: # %bb.0: # %entry 1773; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1774; AVX512BW-NEXT: vmovq %xmm0, %rax 1775; AVX512BW-NEXT: retq 1776; 1777; AVX512BWVL-LABEL: trunc8i16_i64: 1778; AVX512BWVL: # %bb.0: # %entry 1779; AVX512BWVL-NEXT: vpmovwb %xmm0, %xmm0 1780; AVX512BWVL-NEXT: vmovq %xmm0, %rax 1781; AVX512BWVL-NEXT: retq 1782entry: 1783 %0 = trunc <8 x i16> %inval to <8 x i8> 1784 %1 = bitcast <8 x i8> %0 to i64 1785 ret i64 %1 1786} 1787 1788define <16 x i8> @trunc16i64_16i8_const() { 1789; SSE-LABEL: trunc16i64_16i8_const: 1790; SSE: # %bb.0: # %entry 1791; SSE-NEXT: xorps %xmm0, %xmm0 1792; SSE-NEXT: retq 1793; 1794; AVX-LABEL: trunc16i64_16i8_const: 1795; AVX: # %bb.0: # %entry 1796; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 1797; AVX-NEXT: retq 1798; 1799; AVX512-LABEL: trunc16i64_16i8_const: 1800; AVX512: # %bb.0: # %entry 1801; AVX512-NEXT: vxorps %xmm0, %xmm0, %xmm0 1802; AVX512-NEXT: retq 1803 1804entry: 1805 %0 = trunc <16 x i64> zeroinitializer to <16 x i8> 1806 %1 = shufflevector <16 x i8> %0, <16 x i8> %0, <16 x i32> <i32 28, i32 30, i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 undef, i32 14, i32 16, i32 18, i32 20, i32 22, i32 24, i32 26> 1807 ret <16 x i8> %1 1808} 1809 1810define <8 x i16> @PR32160(<8 x i32> %x) { 1811; SSE-LABEL: PR32160: 1812; SSE: # %bb.0: 1813; SSE-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,4,6,7] 1814; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,2,2,2] 1815; SSE-NEXT: retq 1816; 1817; AVX1-LABEL: PR32160: 1818; AVX1: # %bb.0: 1819; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9] 1820; AVX1-NEXT: vzeroupper 1821; AVX1-NEXT: retq 1822; 1823; AVX2-SLOW-LABEL: PR32160: 1824; AVX2-SLOW: # %bb.0: 1825; AVX2-SLOW-NEXT: vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] 1826; AVX2-SLOW-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[2,2,2,3,4,5,6,7] 1827; AVX2-SLOW-NEXT: vpbroadcastd %xmm0, %xmm0 1828; AVX2-SLOW-NEXT: vzeroupper 1829; AVX2-SLOW-NEXT: retq 1830; 1831; AVX2-FAST-LABEL: PR32160: 1832; AVX2-FAST: # %bb.0: 1833; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9] 1834; AVX2-FAST-NEXT: vzeroupper 1835; AVX2-FAST-NEXT: retq 1836; 1837; AVX512F-LABEL: PR32160: 1838; AVX512F: # %bb.0: 1839; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1840; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 1841; AVX512F-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[2,2,2,3,4,5,6,7] 1842; AVX512F-NEXT: vpbroadcastd %xmm0, %xmm0 1843; AVX512F-NEXT: vzeroupper 1844; AVX512F-NEXT: retq 1845; 1846; AVX512VL-LABEL: PR32160: 1847; AVX512VL: # %bb.0: 1848; AVX512VL-NEXT: vpmovdw %ymm0, %xmm0 1849; AVX512VL-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5] 1850; AVX512VL-NEXT: vzeroupper 1851; AVX512VL-NEXT: retq 1852; 1853; AVX512BW-LABEL: PR32160: 1854; AVX512BW: # %bb.0: 1855; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1856; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 1857; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5] 1858; AVX512BW-NEXT: vzeroupper 1859; AVX512BW-NEXT: retq 1860; 1861; AVX512BWVL-LABEL: PR32160: 1862; AVX512BWVL: # %bb.0: 1863; AVX512BWVL-NEXT: vpmovdw %ymm0, %xmm0 1864; AVX512BWVL-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5] 1865; AVX512BWVL-NEXT: vzeroupper 1866; AVX512BWVL-NEXT: retq 1867 %shuf = trunc <8 x i32> %x to <8 x i16> 1868 %trunc = shufflevector <8 x i16> %shuf, <8 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2> 1869 ret <8 x i16> %trunc 1870} 1871 1872define void @PR34773(i16* %a0, i8* %a1) { 1873; SSE-LABEL: PR34773: 1874; SSE: # %bb.0: 1875; SSE-NEXT: movdqu (%rdi), %xmm0 1876; SSE-NEXT: movdqu 16(%rdi), %xmm1 1877; SSE-NEXT: movdqu 32(%rdi), %xmm2 1878; SSE-NEXT: movdqu 48(%rdi), %xmm3 1879; SSE-NEXT: psrlw $8, %xmm1 1880; SSE-NEXT: psrlw $8, %xmm0 1881; SSE-NEXT: packuswb %xmm1, %xmm0 1882; SSE-NEXT: psrlw $8, %xmm3 1883; SSE-NEXT: psrlw $8, %xmm2 1884; SSE-NEXT: packuswb %xmm3, %xmm2 1885; SSE-NEXT: movdqu %xmm0, (%rsi) 1886; SSE-NEXT: movdqu %xmm2, 16(%rsi) 1887; SSE-NEXT: retq 1888; 1889; AVX1-LABEL: PR34773: 1890; AVX1: # %bb.0: 1891; AVX1-NEXT: vmovdqu (%rdi), %xmm0 1892; AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 1893; AVX1-NEXT: vmovdqu 32(%rdi), %xmm2 1894; AVX1-NEXT: vmovdqu 48(%rdi), %xmm3 1895; AVX1-NEXT: vpsrlw $8, %xmm1, %xmm1 1896; AVX1-NEXT: vpsrlw $8, %xmm0, %xmm0 1897; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1898; AVX1-NEXT: vpsrlw $8, %xmm3, %xmm1 1899; AVX1-NEXT: vpsrlw $8, %xmm2, %xmm2 1900; AVX1-NEXT: vpackuswb %xmm1, %xmm2, %xmm1 1901; AVX1-NEXT: vmovdqu %xmm0, (%rsi) 1902; AVX1-NEXT: vmovdqu %xmm1, 16(%rsi) 1903; AVX1-NEXT: retq 1904; 1905; AVX2-LABEL: PR34773: 1906; AVX2: # %bb.0: 1907; AVX2-NEXT: vmovdqu (%rdi), %ymm0 1908; AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1909; AVX2-NEXT: vpsrlw $8, %ymm0, %ymm0 1910; AVX2-NEXT: vpsrlw $8, %ymm1, %ymm1 1911; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 1912; AVX2-NEXT: vpackuswb %xmm2, %xmm0, %xmm0 1913; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm2 1914; AVX2-NEXT: vpackuswb %xmm2, %xmm1, %xmm1 1915; AVX2-NEXT: vmovdqu %xmm0, (%rsi) 1916; AVX2-NEXT: vmovdqu %xmm1, 16(%rsi) 1917; AVX2-NEXT: vzeroupper 1918; AVX2-NEXT: retq 1919; 1920; AVX512F-LABEL: PR34773: 1921; AVX512F: # %bb.0: 1922; AVX512F-NEXT: vmovdqu (%rdi), %ymm0 1923; AVX512F-NEXT: vmovdqu 32(%rdi), %ymm1 1924; AVX512F-NEXT: vpsrlw $8, %ymm0, %ymm0 1925; AVX512F-NEXT: vpsrlw $8, %ymm1, %ymm1 1926; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1927; AVX512F-NEXT: vpmovdb %zmm0, (%rsi) 1928; AVX512F-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero 1929; AVX512F-NEXT: vpmovdb %zmm0, 16(%rsi) 1930; AVX512F-NEXT: vzeroupper 1931; AVX512F-NEXT: retq 1932; 1933; AVX512VL-LABEL: PR34773: 1934; AVX512VL: # %bb.0: 1935; AVX512VL-NEXT: vmovdqu (%rdi), %ymm0 1936; AVX512VL-NEXT: vmovdqu 32(%rdi), %ymm1 1937; AVX512VL-NEXT: vpsrlw $8, %ymm0, %ymm0 1938; AVX512VL-NEXT: vpsrlw $8, %ymm1, %ymm1 1939; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero 1940; AVX512VL-NEXT: vpmovdb %zmm0, (%rsi) 1941; AVX512VL-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm1[0],zero,ymm1[1],zero,ymm1[2],zero,ymm1[3],zero,ymm1[4],zero,ymm1[5],zero,ymm1[6],zero,ymm1[7],zero,ymm1[8],zero,ymm1[9],zero,ymm1[10],zero,ymm1[11],zero,ymm1[12],zero,ymm1[13],zero,ymm1[14],zero,ymm1[15],zero 1942; AVX512VL-NEXT: vpmovdb %zmm0, 16(%rsi) 1943; AVX512VL-NEXT: vzeroupper 1944; AVX512VL-NEXT: retq 1945; 1946; AVX512BW-LABEL: PR34773: 1947; AVX512BW: # %bb.0: 1948; AVX512BW-NEXT: vmovdqu (%rdi), %ymm0 1949; AVX512BW-NEXT: vmovdqu 32(%rdi), %ymm1 1950; AVX512BW-NEXT: vpsrlw $8, %ymm0, %ymm0 1951; AVX512BW-NEXT: vpsrlw $8, %ymm1, %ymm1 1952; AVX512BW-NEXT: vpmovwb %zmm0, %ymm0 1953; AVX512BW-NEXT: vpmovwb %zmm1, %ymm1 1954; AVX512BW-NEXT: vmovdqu %xmm0, (%rsi) 1955; AVX512BW-NEXT: vmovdqu %xmm1, 16(%rsi) 1956; AVX512BW-NEXT: vzeroupper 1957; AVX512BW-NEXT: retq 1958; 1959; AVX512BWVL-LABEL: PR34773: 1960; AVX512BWVL: # %bb.0: 1961; AVX512BWVL-NEXT: vpsrlw $8, (%rdi), %ymm0 1962; AVX512BWVL-NEXT: vpsrlw $8, 32(%rdi), %ymm1 1963; AVX512BWVL-NEXT: vpmovwb %ymm0, (%rsi) 1964; AVX512BWVL-NEXT: vpmovwb %ymm1, 16(%rsi) 1965; AVX512BWVL-NEXT: vzeroupper 1966; AVX512BWVL-NEXT: retq 1967 %1 = getelementptr i16, i16* %a0, i64 16 1968 %2 = getelementptr i8, i8* %a1, i64 16 1969 %3 = bitcast i16* %a0 to <16 x i16>* 1970 %4 = bitcast i16* %1 to <16 x i16>* 1971 %5 = bitcast i8* %a1 to <16 x i8>* 1972 %6 = bitcast i8* %2 to <16 x i8>* 1973 %7 = load <16 x i16>, <16 x i16>* %3, align 2 1974 %8 = load <16 x i16>, <16 x i16>* %4, align 2 1975 %9 = lshr <16 x i16> %7, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8> 1976 %10 = lshr <16 x i16> %8, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8> 1977 %11 = trunc <16 x i16> %9 to <16 x i8> 1978 %12 = trunc <16 x i16> %10 to <16 x i8> 1979 store <16 x i8> %11, <16 x i8>* %5, align 1 1980 store <16 x i8> %12, <16 x i8>* %6, align 1 1981 ret void 1982} 1983 1984; Store merging must not infinitely fight store splitting. 1985 1986define void @store_merge_split(<8 x i32> %w1, <8 x i32> %w2, i64 %idx, <8 x i16>* %p) align 2 { 1987; SSE2-LABEL: store_merge_split: 1988; SSE2: # %bb.0: 1989; SSE2-NEXT: pslld $16, %xmm1 1990; SSE2-NEXT: psrad $16, %xmm1 1991; SSE2-NEXT: pslld $16, %xmm0 1992; SSE2-NEXT: psrad $16, %xmm0 1993; SSE2-NEXT: packssdw %xmm1, %xmm0 1994; SSE2-NEXT: pslld $16, %xmm3 1995; SSE2-NEXT: psrad $16, %xmm3 1996; SSE2-NEXT: pslld $16, %xmm2 1997; SSE2-NEXT: psrad $16, %xmm2 1998; SSE2-NEXT: packssdw %xmm3, %xmm2 1999; SSE2-NEXT: shlq $4, %rdi 2000; SSE2-NEXT: movdqu %xmm0, (%rsi,%rdi) 2001; SSE2-NEXT: movdqu %xmm2, 16(%rsi,%rdi) 2002; SSE2-NEXT: retq 2003; 2004; SSSE3-LABEL: store_merge_split: 2005; SSSE3: # %bb.0: 2006; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 2007; SSSE3-NEXT: pshufb %xmm4, %xmm1 2008; SSSE3-NEXT: pshufb %xmm4, %xmm0 2009; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 2010; SSSE3-NEXT: pshufb %xmm4, %xmm3 2011; SSSE3-NEXT: pshufb %xmm4, %xmm2 2012; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0] 2013; SSSE3-NEXT: shlq $4, %rdi 2014; SSSE3-NEXT: movdqu %xmm0, (%rsi,%rdi) 2015; SSSE3-NEXT: movdqu %xmm2, 16(%rsi,%rdi) 2016; SSSE3-NEXT: retq 2017; 2018; SSE41-LABEL: store_merge_split: 2019; SSE41: # %bb.0: 2020; SSE41-NEXT: pxor %xmm4, %xmm4 2021; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] 2022; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] 2023; SSE41-NEXT: packusdw %xmm1, %xmm0 2024; SSE41-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] 2025; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] 2026; SSE41-NEXT: packusdw %xmm3, %xmm2 2027; SSE41-NEXT: shlq $4, %rdi 2028; SSE41-NEXT: movdqu %xmm0, (%rsi,%rdi) 2029; SSE41-NEXT: movdqu %xmm2, 16(%rsi,%rdi) 2030; SSE41-NEXT: retq 2031; 2032; AVX1-LABEL: store_merge_split: 2033; AVX1: # %bb.0: 2034; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 2035; AVX1-NEXT: vmovdqa {{.*#+}} xmm3 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 2036; AVX1-NEXT: vpshufb %xmm3, %xmm2, %xmm2 2037; AVX1-NEXT: vpshufb %xmm3, %xmm0, %xmm0 2038; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] 2039; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 2040; AVX1-NEXT: vpshufb %xmm3, %xmm2, %xmm2 2041; AVX1-NEXT: vpshufb %xmm3, %xmm1, %xmm1 2042; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0] 2043; AVX1-NEXT: shlq $4, %rdi 2044; AVX1-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2045; AVX1-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2046; AVX1-NEXT: vzeroupper 2047; AVX1-NEXT: retq 2048; 2049; AVX2-LABEL: store_merge_split: 2050; AVX2: # %bb.0: 2051; AVX2-NEXT: vmovdqa {{.*#+}} ymm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31] 2052; AVX2-NEXT: vpshufb %ymm2, %ymm0, %ymm0 2053; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 2054; AVX2-NEXT: vpshufb %ymm2, %ymm1, %ymm1 2055; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3] 2056; AVX2-NEXT: shlq $4, %rdi 2057; AVX2-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2058; AVX2-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2059; AVX2-NEXT: vzeroupper 2060; AVX2-NEXT: retq 2061; 2062; AVX512F-LABEL: store_merge_split: 2063; AVX512F: # %bb.0: 2064; AVX512F-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 2065; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 2066; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 2067; AVX512F-NEXT: vpmovdw %zmm1, %ymm1 2068; AVX512F-NEXT: shlq $4, %rdi 2069; AVX512F-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2070; AVX512F-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2071; AVX512F-NEXT: vzeroupper 2072; AVX512F-NEXT: retq 2073; 2074; AVX512VL-LABEL: store_merge_split: 2075; AVX512VL: # %bb.0: 2076; AVX512VL-NEXT: shlq $4, %rdi 2077; AVX512VL-NEXT: vpmovdw %ymm0, (%rsi,%rdi) 2078; AVX512VL-NEXT: vpmovdw %ymm1, 16(%rsi,%rdi) 2079; AVX512VL-NEXT: vzeroupper 2080; AVX512VL-NEXT: retq 2081; 2082; AVX512BW-LABEL: store_merge_split: 2083; AVX512BW: # %bb.0: 2084; AVX512BW-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 2085; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 2086; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 2087; AVX512BW-NEXT: vpmovdw %zmm1, %ymm1 2088; AVX512BW-NEXT: shlq $4, %rdi 2089; AVX512BW-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2090; AVX512BW-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2091; AVX512BW-NEXT: vzeroupper 2092; AVX512BW-NEXT: retq 2093; 2094; AVX512BWVL-LABEL: store_merge_split: 2095; AVX512BWVL: # %bb.0: 2096; AVX512BWVL-NEXT: shlq $4, %rdi 2097; AVX512BWVL-NEXT: vpmovdw %ymm0, (%rsi,%rdi) 2098; AVX512BWVL-NEXT: vpmovdw %ymm1, 16(%rsi,%rdi) 2099; AVX512BWVL-NEXT: vzeroupper 2100; AVX512BWVL-NEXT: retq 2101 %t1 = trunc <8 x i32> %w1 to <8 x i16> 2102 %t2 = trunc <8 x i32> %w2 to <8 x i16> 2103 %g1 = getelementptr inbounds <8 x i16>, <8 x i16>* %p, i64 %idx 2104 %g2 = getelementptr inbounds <8 x i16>, <8 x i16>* %g1, i64 1 2105 store <8 x i16> %t1, <8 x i16>* %g1, align 2 2106 store <8 x i16> %t2, <8 x i16>* %g2, align 2 2107 ret void 2108} 2109