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,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31] 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,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31] 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,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31] 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,255,255] 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: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] 931; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 932; AVX2-NEXT: vpacksswb %xmm1, %xmm0, %xmm0 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: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] 1008; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm1 1009; AVX2-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 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,8,9,12,13,12,13,14,15] 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,8,9,12,13,12,13,14,15] 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,8,9,12,13,12,13,14,15] 1645; AVX-NEXT: vmovq %xmm0, %rax 1646; AVX-NEXT: retq 1647; 1648; AVX512-LABEL: trunc4i32_i64: 1649; AVX512: # %bb.0: # %entry 1650; AVX512-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 1651; AVX512-NEXT: vmovq %xmm0, %rax 1652; AVX512-NEXT: retq 1653entry: 1654 %0 = trunc <4 x i32> %inval to <4 x i16> 1655 %1 = bitcast <4 x i16> %0 to i64 1656 ret i64 %1 1657} 1658 1659define <16 x i8> @trunc2x8i16_16i8(<8 x i16> %a, <8 x i16> %b) { 1660; SSE-LABEL: trunc2x8i16_16i8: 1661; SSE: # %bb.0: # %entry 1662; SSE-NEXT: movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1663; SSE-NEXT: pand %xmm2, %xmm1 1664; SSE-NEXT: pand %xmm2, %xmm0 1665; SSE-NEXT: packuswb %xmm1, %xmm0 1666; SSE-NEXT: retq 1667; 1668; AVX-LABEL: trunc2x8i16_16i8: 1669; AVX: # %bb.0: # %entry 1670; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1671; AVX-NEXT: vpand %xmm2, %xmm1, %xmm1 1672; AVX-NEXT: vpand %xmm2, %xmm0, %xmm0 1673; AVX-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1674; AVX-NEXT: retq 1675; 1676; AVX512F-LABEL: trunc2x8i16_16i8: 1677; AVX512F: # %bb.0: # %entry 1678; AVX512F-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1679; AVX512F-NEXT: vpand %xmm2, %xmm1, %xmm1 1680; AVX512F-NEXT: vpand %xmm2, %xmm0, %xmm0 1681; AVX512F-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1682; AVX512F-NEXT: retq 1683; 1684; AVX512VL-LABEL: trunc2x8i16_16i8: 1685; AVX512VL: # %bb.0: # %entry 1686; AVX512VL-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1687; AVX512VL-NEXT: vpand %xmm2, %xmm1, %xmm1 1688; AVX512VL-NEXT: vpand %xmm2, %xmm0, %xmm0 1689; AVX512VL-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1690; AVX512VL-NEXT: retq 1691; 1692; AVX512BW-LABEL: trunc2x8i16_16i8: 1693; AVX512BW: # %bb.0: # %entry 1694; AVX512BW-NEXT: vmovdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255] 1695; AVX512BW-NEXT: vpand %xmm2, %xmm1, %xmm1 1696; AVX512BW-NEXT: vpand %xmm2, %xmm0, %xmm0 1697; AVX512BW-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1698; AVX512BW-NEXT: retq 1699; 1700; AVX512BWVL-LABEL: trunc2x8i16_16i8: 1701; AVX512BWVL: # %bb.0: # %entry 1702; AVX512BWVL-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 1703; AVX512BWVL-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 1704; AVX512BWVL-NEXT: vpmovwb %ymm0, %xmm0 1705; AVX512BWVL-NEXT: vzeroupper 1706; AVX512BWVL-NEXT: retq 1707entry: 1708 %0 = trunc <8 x i16> %a to <8 x i8> 1709 %1 = trunc <8 x i16> %b to <8 x i8> 1710 %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> 1711 ret <16 x i8> %2 1712} 1713 1714; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524 1715define i64 @trunc8i16_i64(<8 x i16> %inval) { 1716; SSE2-LABEL: trunc8i16_i64: 1717; SSE2: # %bb.0: # %entry 1718; SSE2-NEXT: pand {{.*}}(%rip), %xmm0 1719; SSE2-NEXT: packuswb %xmm0, %xmm0 1720; SSE2-NEXT: movq %xmm0, %rax 1721; SSE2-NEXT: retq 1722; 1723; SSSE3-LABEL: trunc8i16_i64: 1724; SSSE3: # %bb.0: # %entry 1725; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1726; SSSE3-NEXT: movq %xmm0, %rax 1727; SSSE3-NEXT: retq 1728; 1729; SSE41-LABEL: trunc8i16_i64: 1730; SSE41: # %bb.0: # %entry 1731; SSE41-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1732; SSE41-NEXT: movq %xmm0, %rax 1733; SSE41-NEXT: retq 1734; 1735; AVX-LABEL: trunc8i16_i64: 1736; AVX: # %bb.0: # %entry 1737; AVX-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1738; AVX-NEXT: vmovq %xmm0, %rax 1739; AVX-NEXT: retq 1740; 1741; AVX512F-LABEL: trunc8i16_i64: 1742; AVX512F: # %bb.0: # %entry 1743; AVX512F-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1744; AVX512F-NEXT: vmovq %xmm0, %rax 1745; AVX512F-NEXT: retq 1746; 1747; AVX512VL-LABEL: trunc8i16_i64: 1748; AVX512VL: # %bb.0: # %entry 1749; AVX512VL-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1750; AVX512VL-NEXT: vmovq %xmm0, %rax 1751; AVX512VL-NEXT: retq 1752; 1753; AVX512BW-LABEL: trunc8i16_i64: 1754; AVX512BW: # %bb.0: # %entry 1755; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u] 1756; AVX512BW-NEXT: vmovq %xmm0, %rax 1757; AVX512BW-NEXT: retq 1758; 1759; AVX512BWVL-LABEL: trunc8i16_i64: 1760; AVX512BWVL: # %bb.0: # %entry 1761; AVX512BWVL-NEXT: vpmovwb %xmm0, %xmm0 1762; AVX512BWVL-NEXT: vmovq %xmm0, %rax 1763; AVX512BWVL-NEXT: retq 1764entry: 1765 %0 = trunc <8 x i16> %inval to <8 x i8> 1766 %1 = bitcast <8 x i8> %0 to i64 1767 ret i64 %1 1768} 1769 1770define <16 x i8> @trunc16i64_16i8_const() { 1771; SSE-LABEL: trunc16i64_16i8_const: 1772; SSE: # %bb.0: # %entry 1773; SSE-NEXT: xorps %xmm0, %xmm0 1774; SSE-NEXT: retq 1775; 1776; AVX-LABEL: trunc16i64_16i8_const: 1777; AVX: # %bb.0: # %entry 1778; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 1779; AVX-NEXT: retq 1780; 1781; AVX512-LABEL: trunc16i64_16i8_const: 1782; AVX512: # %bb.0: # %entry 1783; AVX512-NEXT: vxorps %xmm0, %xmm0, %xmm0 1784; AVX512-NEXT: retq 1785 1786entry: 1787 %0 = trunc <16 x i64> zeroinitializer to <16 x i8> 1788 %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> 1789 ret <16 x i8> %1 1790} 1791 1792define <8 x i16> @PR32160(<8 x i32> %x) { 1793; SSE-LABEL: PR32160: 1794; SSE: # %bb.0: 1795; SSE-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,4,6,7] 1796; SSE-NEXT: pshufd {{.*#+}} xmm0 = xmm0[2,2,2,2] 1797; SSE-NEXT: retq 1798; 1799; AVX1-LABEL: PR32160: 1800; AVX1: # %bb.0: 1801; AVX1-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9] 1802; AVX1-NEXT: vzeroupper 1803; AVX1-NEXT: retq 1804; 1805; AVX2-SLOW-LABEL: PR32160: 1806; AVX2-SLOW: # %bb.0: 1807; AVX2-SLOW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 1808; AVX2-SLOW-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[2,2,2,3,4,5,6,7] 1809; AVX2-SLOW-NEXT: vpbroadcastd %xmm0, %xmm0 1810; AVX2-SLOW-NEXT: vzeroupper 1811; AVX2-SLOW-NEXT: retq 1812; 1813; AVX2-FAST-LABEL: PR32160: 1814; AVX2-FAST: # %bb.0: 1815; AVX2-FAST-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[8,9,8,9,8,9,8,9,8,9,8,9,8,9,8,9] 1816; AVX2-FAST-NEXT: vzeroupper 1817; AVX2-FAST-NEXT: retq 1818; 1819; AVX512F-LABEL: PR32160: 1820; AVX512F: # %bb.0: 1821; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1822; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 1823; AVX512F-NEXT: vpshuflw {{.*#+}} xmm0 = xmm0[2,2,2,3,4,5,6,7] 1824; AVX512F-NEXT: vpbroadcastd %xmm0, %xmm0 1825; AVX512F-NEXT: vzeroupper 1826; AVX512F-NEXT: retq 1827; 1828; AVX512VL-LABEL: PR32160: 1829; AVX512VL: # %bb.0: 1830; AVX512VL-NEXT: vpmovdw %ymm0, %xmm0 1831; AVX512VL-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5] 1832; AVX512VL-NEXT: vzeroupper 1833; AVX512VL-NEXT: retq 1834; 1835; AVX512BW-LABEL: PR32160: 1836; AVX512BW: # %bb.0: 1837; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 1838; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 1839; AVX512BW-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5] 1840; AVX512BW-NEXT: vzeroupper 1841; AVX512BW-NEXT: retq 1842; 1843; AVX512BWVL-LABEL: PR32160: 1844; AVX512BWVL: # %bb.0: 1845; AVX512BWVL-NEXT: vpmovdw %ymm0, %xmm0 1846; AVX512BWVL-NEXT: vpshufb {{.*#+}} xmm0 = xmm0[4,5,4,5,4,5,4,5,4,5,4,5,4,5,4,5] 1847; AVX512BWVL-NEXT: vzeroupper 1848; AVX512BWVL-NEXT: retq 1849 %shuf = trunc <8 x i32> %x to <8 x i16> 1850 %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> 1851 ret <8 x i16> %trunc 1852} 1853 1854define void @PR34773(i16* %a0, i8* %a1) { 1855; SSE-LABEL: PR34773: 1856; SSE: # %bb.0: 1857; SSE-NEXT: movdqu (%rdi), %xmm0 1858; SSE-NEXT: movdqu 16(%rdi), %xmm1 1859; SSE-NEXT: movdqu 32(%rdi), %xmm2 1860; SSE-NEXT: movdqu 48(%rdi), %xmm3 1861; SSE-NEXT: psrlw $8, %xmm1 1862; SSE-NEXT: psrlw $8, %xmm0 1863; SSE-NEXT: packuswb %xmm1, %xmm0 1864; SSE-NEXT: psrlw $8, %xmm3 1865; SSE-NEXT: psrlw $8, %xmm2 1866; SSE-NEXT: packuswb %xmm3, %xmm2 1867; SSE-NEXT: movdqu %xmm0, (%rsi) 1868; SSE-NEXT: movdqu %xmm2, 16(%rsi) 1869; SSE-NEXT: retq 1870; 1871; AVX1-LABEL: PR34773: 1872; AVX1: # %bb.0: 1873; AVX1-NEXT: vmovdqu (%rdi), %xmm0 1874; AVX1-NEXT: vmovdqu 16(%rdi), %xmm1 1875; AVX1-NEXT: vmovdqu 32(%rdi), %xmm2 1876; AVX1-NEXT: vmovdqu 48(%rdi), %xmm3 1877; AVX1-NEXT: vpsrlw $8, %xmm1, %xmm1 1878; AVX1-NEXT: vpsrlw $8, %xmm0, %xmm0 1879; AVX1-NEXT: vpackuswb %xmm1, %xmm0, %xmm0 1880; AVX1-NEXT: vpsrlw $8, %xmm3, %xmm1 1881; AVX1-NEXT: vpsrlw $8, %xmm2, %xmm2 1882; AVX1-NEXT: vpackuswb %xmm1, %xmm2, %xmm1 1883; AVX1-NEXT: vmovdqu %xmm0, (%rsi) 1884; AVX1-NEXT: vmovdqu %xmm1, 16(%rsi) 1885; AVX1-NEXT: retq 1886; 1887; AVX2-LABEL: PR34773: 1888; AVX2: # %bb.0: 1889; AVX2-NEXT: vmovdqu (%rdi), %ymm0 1890; AVX2-NEXT: vmovdqu 32(%rdi), %ymm1 1891; AVX2-NEXT: vpsrlw $8, %ymm0, %ymm0 1892; AVX2-NEXT: vpsrlw $8, %ymm1, %ymm1 1893; AVX2-NEXT: vextracti128 $1, %ymm0, %xmm2 1894; AVX2-NEXT: vpackuswb %xmm2, %xmm0, %xmm0 1895; AVX2-NEXT: vextracti128 $1, %ymm1, %xmm2 1896; AVX2-NEXT: vpackuswb %xmm2, %xmm1, %xmm1 1897; AVX2-NEXT: vmovdqu %xmm0, (%rsi) 1898; AVX2-NEXT: vmovdqu %xmm1, 16(%rsi) 1899; AVX2-NEXT: vzeroupper 1900; AVX2-NEXT: retq 1901; 1902; AVX512F-LABEL: PR34773: 1903; AVX512F: # %bb.0: 1904; AVX512F-NEXT: vmovdqu (%rdi), %ymm0 1905; AVX512F-NEXT: vmovdqu 32(%rdi), %ymm1 1906; AVX512F-NEXT: vpsrlw $8, %ymm0, %ymm0 1907; AVX512F-NEXT: vpsrlw $8, %ymm1, %ymm1 1908; 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 1909; AVX512F-NEXT: vpmovdb %zmm0, (%rsi) 1910; 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 1911; AVX512F-NEXT: vpmovdb %zmm0, 16(%rsi) 1912; AVX512F-NEXT: vzeroupper 1913; AVX512F-NEXT: retq 1914; 1915; AVX512VL-LABEL: PR34773: 1916; AVX512VL: # %bb.0: 1917; AVX512VL-NEXT: vmovdqu (%rdi), %ymm0 1918; AVX512VL-NEXT: vmovdqu 32(%rdi), %ymm1 1919; AVX512VL-NEXT: vpsrlw $8, %ymm0, %ymm0 1920; AVX512VL-NEXT: vpsrlw $8, %ymm1, %ymm1 1921; 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 1922; AVX512VL-NEXT: vpmovdb %zmm0, (%rsi) 1923; 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 1924; AVX512VL-NEXT: vpmovdb %zmm0, 16(%rsi) 1925; AVX512VL-NEXT: vzeroupper 1926; AVX512VL-NEXT: retq 1927; 1928; AVX512BW-LABEL: PR34773: 1929; AVX512BW: # %bb.0: 1930; AVX512BW-NEXT: vmovdqu (%rdi), %ymm0 1931; AVX512BW-NEXT: vmovdqu 32(%rdi), %ymm1 1932; AVX512BW-NEXT: vpsrlw $8, %ymm0, %ymm0 1933; AVX512BW-NEXT: vpsrlw $8, %ymm1, %ymm1 1934; AVX512BW-NEXT: vpmovwb %zmm0, %ymm0 1935; AVX512BW-NEXT: vpmovwb %zmm1, %ymm1 1936; AVX512BW-NEXT: vmovdqu %xmm0, (%rsi) 1937; AVX512BW-NEXT: vmovdqu %xmm1, 16(%rsi) 1938; AVX512BW-NEXT: vzeroupper 1939; AVX512BW-NEXT: retq 1940; 1941; AVX512BWVL-LABEL: PR34773: 1942; AVX512BWVL: # %bb.0: 1943; AVX512BWVL-NEXT: vpsrlw $8, (%rdi), %ymm0 1944; AVX512BWVL-NEXT: vpsrlw $8, 32(%rdi), %ymm1 1945; AVX512BWVL-NEXT: vpmovwb %ymm0, (%rsi) 1946; AVX512BWVL-NEXT: vpmovwb %ymm1, 16(%rsi) 1947; AVX512BWVL-NEXT: vzeroupper 1948; AVX512BWVL-NEXT: retq 1949 %1 = getelementptr i16, i16* %a0, i64 16 1950 %2 = getelementptr i8, i8* %a1, i64 16 1951 %3 = bitcast i16* %a0 to <16 x i16>* 1952 %4 = bitcast i16* %1 to <16 x i16>* 1953 %5 = bitcast i8* %a1 to <16 x i8>* 1954 %6 = bitcast i8* %2 to <16 x i8>* 1955 %7 = load <16 x i16>, <16 x i16>* %3, align 2 1956 %8 = load <16 x i16>, <16 x i16>* %4, align 2 1957 %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> 1958 %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> 1959 %11 = trunc <16 x i16> %9 to <16 x i8> 1960 %12 = trunc <16 x i16> %10 to <16 x i8> 1961 store <16 x i8> %11, <16 x i8>* %5, align 1 1962 store <16 x i8> %12, <16 x i8>* %6, align 1 1963 ret void 1964} 1965 1966; Store merging must not infinitely fight store splitting. 1967 1968define void @store_merge_split(<8 x i32> %w1, <8 x i32> %w2, i64 %idx, <8 x i16>* %p) align 2 { 1969; SSE2-LABEL: store_merge_split: 1970; SSE2: # %bb.0: 1971; SSE2-NEXT: pslld $16, %xmm1 1972; SSE2-NEXT: psrad $16, %xmm1 1973; SSE2-NEXT: pslld $16, %xmm0 1974; SSE2-NEXT: psrad $16, %xmm0 1975; SSE2-NEXT: packssdw %xmm1, %xmm0 1976; SSE2-NEXT: pslld $16, %xmm3 1977; SSE2-NEXT: psrad $16, %xmm3 1978; SSE2-NEXT: pslld $16, %xmm2 1979; SSE2-NEXT: psrad $16, %xmm2 1980; SSE2-NEXT: packssdw %xmm3, %xmm2 1981; SSE2-NEXT: shlq $4, %rdi 1982; SSE2-NEXT: movdqu %xmm0, (%rsi,%rdi) 1983; SSE2-NEXT: movdqu %xmm2, 16(%rsi,%rdi) 1984; SSE2-NEXT: retq 1985; 1986; SSSE3-LABEL: store_merge_split: 1987; SSSE3: # %bb.0: 1988; SSSE3-NEXT: movdqa {{.*#+}} xmm4 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 1989; SSSE3-NEXT: pshufb %xmm4, %xmm1 1990; SSSE3-NEXT: pshufb %xmm4, %xmm0 1991; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] 1992; SSSE3-NEXT: pshufb %xmm4, %xmm3 1993; SSSE3-NEXT: pshufb %xmm4, %xmm2 1994; SSSE3-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0] 1995; SSSE3-NEXT: shlq $4, %rdi 1996; SSSE3-NEXT: movdqu %xmm0, (%rsi,%rdi) 1997; SSSE3-NEXT: movdqu %xmm2, 16(%rsi,%rdi) 1998; SSSE3-NEXT: retq 1999; 2000; SSE41-LABEL: store_merge_split: 2001; SSE41: # %bb.0: 2002; SSE41-NEXT: pxor %xmm4, %xmm4 2003; SSE41-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0],xmm4[1],xmm1[2],xmm4[3],xmm1[4],xmm4[5],xmm1[6],xmm4[7] 2004; SSE41-NEXT: pblendw {{.*#+}} xmm0 = xmm0[0],xmm4[1],xmm0[2],xmm4[3],xmm0[4],xmm4[5],xmm0[6],xmm4[7] 2005; SSE41-NEXT: packusdw %xmm1, %xmm0 2006; SSE41-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0],xmm4[1],xmm3[2],xmm4[3],xmm3[4],xmm4[5],xmm3[6],xmm4[7] 2007; SSE41-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0],xmm4[1],xmm2[2],xmm4[3],xmm2[4],xmm4[5],xmm2[6],xmm4[7] 2008; SSE41-NEXT: packusdw %xmm3, %xmm2 2009; SSE41-NEXT: shlq $4, %rdi 2010; SSE41-NEXT: movdqu %xmm0, (%rsi,%rdi) 2011; SSE41-NEXT: movdqu %xmm2, 16(%rsi,%rdi) 2012; SSE41-NEXT: retq 2013; 2014; AVX1-LABEL: store_merge_split: 2015; AVX1: # %bb.0: 2016; AVX1-NEXT: vextractf128 $1, %ymm0, %xmm2 2017; AVX1-NEXT: vmovdqa {{.*#+}} xmm3 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15] 2018; AVX1-NEXT: vpshufb %xmm3, %xmm2, %xmm2 2019; AVX1-NEXT: vpshufb %xmm3, %xmm0, %xmm0 2020; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm2[0] 2021; AVX1-NEXT: vextractf128 $1, %ymm1, %xmm2 2022; AVX1-NEXT: vpshufb %xmm3, %xmm2, %xmm2 2023; AVX1-NEXT: vpshufb %xmm3, %xmm1, %xmm1 2024; AVX1-NEXT: vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0] 2025; AVX1-NEXT: shlq $4, %rdi 2026; AVX1-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2027; AVX1-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2028; AVX1-NEXT: vzeroupper 2029; AVX1-NEXT: retq 2030; 2031; AVX2-LABEL: store_merge_split: 2032; AVX2: # %bb.0: 2033; 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] 2034; AVX2-NEXT: vpshufb %ymm2, %ymm0, %ymm0 2035; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3] 2036; AVX2-NEXT: vpshufb %ymm2, %ymm1, %ymm1 2037; AVX2-NEXT: vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3] 2038; AVX2-NEXT: shlq $4, %rdi 2039; AVX2-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2040; AVX2-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2041; AVX2-NEXT: vzeroupper 2042; AVX2-NEXT: retq 2043; 2044; AVX512F-LABEL: store_merge_split: 2045; AVX512F: # %bb.0: 2046; AVX512F-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 2047; AVX512F-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 2048; AVX512F-NEXT: vpmovdw %zmm0, %ymm0 2049; AVX512F-NEXT: vpmovdw %zmm1, %ymm1 2050; AVX512F-NEXT: shlq $4, %rdi 2051; AVX512F-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2052; AVX512F-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2053; AVX512F-NEXT: vzeroupper 2054; AVX512F-NEXT: retq 2055; 2056; AVX512VL-LABEL: store_merge_split: 2057; AVX512VL: # %bb.0: 2058; AVX512VL-NEXT: shlq $4, %rdi 2059; AVX512VL-NEXT: vpmovdw %ymm0, (%rsi,%rdi) 2060; AVX512VL-NEXT: vpmovdw %ymm1, 16(%rsi,%rdi) 2061; AVX512VL-NEXT: vzeroupper 2062; AVX512VL-NEXT: retq 2063; 2064; AVX512BW-LABEL: store_merge_split: 2065; AVX512BW: # %bb.0: 2066; AVX512BW-NEXT: # kill: def $ymm1 killed $ymm1 def $zmm1 2067; AVX512BW-NEXT: # kill: def $ymm0 killed $ymm0 def $zmm0 2068; AVX512BW-NEXT: vpmovdw %zmm0, %ymm0 2069; AVX512BW-NEXT: vpmovdw %zmm1, %ymm1 2070; AVX512BW-NEXT: shlq $4, %rdi 2071; AVX512BW-NEXT: vmovdqu %xmm0, (%rsi,%rdi) 2072; AVX512BW-NEXT: vmovdqu %xmm1, 16(%rsi,%rdi) 2073; AVX512BW-NEXT: vzeroupper 2074; AVX512BW-NEXT: retq 2075; 2076; AVX512BWVL-LABEL: store_merge_split: 2077; AVX512BWVL: # %bb.0: 2078; AVX512BWVL-NEXT: shlq $4, %rdi 2079; AVX512BWVL-NEXT: vpmovdw %ymm0, (%rsi,%rdi) 2080; AVX512BWVL-NEXT: vpmovdw %ymm1, 16(%rsi,%rdi) 2081; AVX512BWVL-NEXT: vzeroupper 2082; AVX512BWVL-NEXT: retq 2083 %t1 = trunc <8 x i32> %w1 to <8 x i16> 2084 %t2 = trunc <8 x i32> %w2 to <8 x i16> 2085 %g1 = getelementptr inbounds <8 x i16>, <8 x i16>* %p, i64 %idx 2086 %g2 = getelementptr inbounds <8 x i16>, <8 x i16>* %g1, i64 1 2087 store <8 x i16> %t1, <8 x i16>* %g1, align 2 2088 store <8 x i16> %t2, <8 x i16>* %g2, align 2 2089 ret void 2090} 2091