1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX2 4 5; 6; Unary shuffle indices from registers 7; 8 9define <4 x double> @var_shuffle_v4f64_v4f64_xxxx_i64(<4 x double> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind { 10; ALL-LABEL: var_shuffle_v4f64_v4f64_xxxx_i64: 11; ALL: # BB#0: 12; ALL-NEXT: pushq %rbp 13; ALL-NEXT: movq %rsp, %rbp 14; ALL-NEXT: andq $-32, %rsp 15; ALL-NEXT: subq $64, %rsp 16; ALL-NEXT: andl $3, %esi 17; ALL-NEXT: andl $3, %edi 18; ALL-NEXT: andl $3, %ecx 19; ALL-NEXT: andl $3, %edx 20; ALL-NEXT: vmovaps %ymm0, (%rsp) 21; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 22; ALL-NEXT: vmovhpd {{.*#+}} xmm0 = xmm0[0],mem[0] 23; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 24; ALL-NEXT: vmovhpd {{.*#+}} xmm1 = xmm1[0],mem[0] 25; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 26; ALL-NEXT: movq %rbp, %rsp 27; ALL-NEXT: popq %rbp 28; ALL-NEXT: retq 29 %x0 = extractelement <4 x double> %x, i64 %i0 30 %x1 = extractelement <4 x double> %x, i64 %i1 31 %x2 = extractelement <4 x double> %x, i64 %i2 32 %x3 = extractelement <4 x double> %x, i64 %i3 33 %r0 = insertelement <4 x double> undef, double %x0, i32 0 34 %r1 = insertelement <4 x double> %r0, double %x1, i32 1 35 %r2 = insertelement <4 x double> %r1, double %x2, i32 2 36 %r3 = insertelement <4 x double> %r2, double %x3, i32 3 37 ret <4 x double> %r3 38} 39 40define <4 x double> @var_shuffle_v4f64_v4f64_uxx0_i64(<4 x double> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind { 41; ALL-LABEL: var_shuffle_v4f64_v4f64_uxx0_i64: 42; ALL: # BB#0: 43; ALL-NEXT: pushq %rbp 44; ALL-NEXT: movq %rsp, %rbp 45; ALL-NEXT: andq $-32, %rsp 46; ALL-NEXT: subq $64, %rsp 47; ALL-NEXT: andl $3, %edx 48; ALL-NEXT: andl $3, %esi 49; ALL-NEXT: vmovaps %ymm0, (%rsp) 50; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 51; ALL-NEXT: vmovddup {{.*#+}} xmm0 = xmm0[0,0] 52; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 53; ALL-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 54; ALL-NEXT: movq %rbp, %rsp 55; ALL-NEXT: popq %rbp 56; ALL-NEXT: retq 57 %x0 = extractelement <4 x double> %x, i64 %i0 58 %x1 = extractelement <4 x double> %x, i64 %i1 59 %x2 = extractelement <4 x double> %x, i64 %i2 60 %x3 = extractelement <4 x double> %x, i64 %i3 61 %r0 = insertelement <4 x double> undef, double undef, i32 0 62 %r1 = insertelement <4 x double> %r0, double %x1, i32 1 63 %r2 = insertelement <4 x double> %r1, double %x2, i32 2 64 %r3 = insertelement <4 x double> %r2, double 0.0, i32 3 65 ret <4 x double> %r3 66} 67 68define <4 x double> @var_shuffle_v4f64_v2f64_xxxx_i64(<2 x double> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind { 69; ALL-LABEL: var_shuffle_v4f64_v2f64_xxxx_i64: 70; ALL: # BB#0: 71; ALL-NEXT: andl $1, %esi 72; ALL-NEXT: andl $1, %edi 73; ALL-NEXT: andl $1, %ecx 74; ALL-NEXT: andl $1, %edx 75; ALL-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) 76; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 77; ALL-NEXT: vmovhpd {{.*#+}} xmm0 = xmm0[0],mem[0] 78; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 79; ALL-NEXT: vmovhpd {{.*#+}} xmm1 = xmm1[0],mem[0] 80; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 81; ALL-NEXT: retq 82 %x0 = extractelement <2 x double> %x, i64 %i0 83 %x1 = extractelement <2 x double> %x, i64 %i1 84 %x2 = extractelement <2 x double> %x, i64 %i2 85 %x3 = extractelement <2 x double> %x, i64 %i3 86 %r0 = insertelement <4 x double> undef, double %x0, i32 0 87 %r1 = insertelement <4 x double> %r0, double %x1, i32 1 88 %r2 = insertelement <4 x double> %r1, double %x2, i32 2 89 %r3 = insertelement <4 x double> %r2, double %x3, i32 3 90 ret <4 x double> %r3 91} 92 93define <4 x i64> @var_shuffle_v4i64_v4i64_xxxx_i64(<4 x i64> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind { 94; ALL-LABEL: var_shuffle_v4i64_v4i64_xxxx_i64: 95; ALL: # BB#0: 96; ALL-NEXT: pushq %rbp 97; ALL-NEXT: movq %rsp, %rbp 98; ALL-NEXT: andq $-32, %rsp 99; ALL-NEXT: subq $64, %rsp 100; ALL-NEXT: andl $3, %edi 101; ALL-NEXT: andl $3, %esi 102; ALL-NEXT: andl $3, %edx 103; ALL-NEXT: andl $3, %ecx 104; ALL-NEXT: vmovaps %ymm0, (%rsp) 105; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 106; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 107; ALL-NEXT: vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0] 108; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 109; ALL-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero 110; ALL-NEXT: vmovlhps {{.*#+}} xmm1 = xmm2[0],xmm1[0] 111; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 112; ALL-NEXT: movq %rbp, %rsp 113; ALL-NEXT: popq %rbp 114; ALL-NEXT: retq 115 %x0 = extractelement <4 x i64> %x, i64 %i0 116 %x1 = extractelement <4 x i64> %x, i64 %i1 117 %x2 = extractelement <4 x i64> %x, i64 %i2 118 %x3 = extractelement <4 x i64> %x, i64 %i3 119 %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0 120 %r1 = insertelement <4 x i64> %r0, i64 %x1, i32 1 121 %r2 = insertelement <4 x i64> %r1, i64 %x2, i32 2 122 %r3 = insertelement <4 x i64> %r2, i64 %x3, i32 3 123 ret <4 x i64> %r3 124} 125 126define <4 x i64> @var_shuffle_v4i64_v4i64_xx00_i64(<4 x i64> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind { 127; ALL-LABEL: var_shuffle_v4i64_v4i64_xx00_i64: 128; ALL: # BB#0: 129; ALL-NEXT: pushq %rbp 130; ALL-NEXT: movq %rsp, %rbp 131; ALL-NEXT: andq $-32, %rsp 132; ALL-NEXT: subq $64, %rsp 133; ALL-NEXT: andl $3, %edi 134; ALL-NEXT: andl $3, %esi 135; ALL-NEXT: vmovaps %ymm0, (%rsp) 136; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 137; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 138; ALL-NEXT: vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0] 139; ALL-NEXT: vmovaps %xmm0, %xmm0 140; ALL-NEXT: movq %rbp, %rsp 141; ALL-NEXT: popq %rbp 142; ALL-NEXT: retq 143 %x0 = extractelement <4 x i64> %x, i64 %i0 144 %x1 = extractelement <4 x i64> %x, i64 %i1 145 %x2 = extractelement <4 x i64> %x, i64 %i2 146 %x3 = extractelement <4 x i64> %x, i64 %i3 147 %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0 148 %r1 = insertelement <4 x i64> %r0, i64 %x1, i32 1 149 %r2 = insertelement <4 x i64> %r1, i64 0, i32 2 150 %r3 = insertelement <4 x i64> %r2, i64 0, i32 3 151 ret <4 x i64> %r3 152} 153 154define <4 x i64> @var_shuffle_v4i64_v2i64_xxxx_i64(<2 x i64> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind { 155; ALL-LABEL: var_shuffle_v4i64_v2i64_xxxx_i64: 156; ALL: # BB#0: 157; ALL-NEXT: andl $1, %edi 158; ALL-NEXT: andl $1, %esi 159; ALL-NEXT: andl $1, %edx 160; ALL-NEXT: andl $1, %ecx 161; ALL-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) 162; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 163; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 164; ALL-NEXT: vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0] 165; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 166; ALL-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero 167; ALL-NEXT: vmovlhps {{.*#+}} xmm1 = xmm2[0],xmm1[0] 168; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 169; ALL-NEXT: retq 170 %x0 = extractelement <2 x i64> %x, i64 %i0 171 %x1 = extractelement <2 x i64> %x, i64 %i1 172 %x2 = extractelement <2 x i64> %x, i64 %i2 173 %x3 = extractelement <2 x i64> %x, i64 %i3 174 %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0 175 %r1 = insertelement <4 x i64> %r0, i64 %x1, i32 1 176 %r2 = insertelement <4 x i64> %r1, i64 %x2, i32 2 177 %r3 = insertelement <4 x i64> %r2, i64 %x3, i32 3 178 ret <4 x i64> %r3 179} 180 181define <8 x float> @var_shuffle_v8f32_v8f32_xxxxxxxx_i32(<8 x float> %x, i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7) nounwind { 182; ALL-LABEL: var_shuffle_v8f32_v8f32_xxxxxxxx_i32: 183; ALL: # BB#0: 184; ALL-NEXT: pushq %rbp 185; ALL-NEXT: movq %rsp, %rbp 186; ALL-NEXT: andq $-32, %rsp 187; ALL-NEXT: subq $64, %rsp 188; ALL-NEXT: # kill: %R9D<def> %R9D<kill> %R9<def> 189; ALL-NEXT: # kill: %R8D<def> %R8D<kill> %R8<def> 190; ALL-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<def> 191; ALL-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def> 192; ALL-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 193; ALL-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 194; ALL-NEXT: andl $7, %edi 195; ALL-NEXT: andl $7, %esi 196; ALL-NEXT: andl $7, %edx 197; ALL-NEXT: andl $7, %ecx 198; ALL-NEXT: andl $7, %r8d 199; ALL-NEXT: vmovaps %ymm0, (%rsp) 200; ALL-NEXT: andl $7, %r9d 201; ALL-NEXT: movl 16(%rbp), %r10d 202; ALL-NEXT: andl $7, %r10d 203; ALL-NEXT: movl 24(%rbp), %eax 204; ALL-NEXT: andl $7, %eax 205; ALL-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 206; ALL-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3] 207; ALL-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3] 208; ALL-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0] 209; ALL-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero 210; ALL-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[2,3] 211; ALL-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],mem[0],xmm1[3] 212; ALL-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],mem[0] 213; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 214; ALL-NEXT: movq %rbp, %rsp 215; ALL-NEXT: popq %rbp 216; ALL-NEXT: retq 217 %x0 = extractelement <8 x float> %x, i32 %i0 218 %x1 = extractelement <8 x float> %x, i32 %i1 219 %x2 = extractelement <8 x float> %x, i32 %i2 220 %x3 = extractelement <8 x float> %x, i32 %i3 221 %x4 = extractelement <8 x float> %x, i32 %i4 222 %x5 = extractelement <8 x float> %x, i32 %i5 223 %x6 = extractelement <8 x float> %x, i32 %i6 224 %x7 = extractelement <8 x float> %x, i32 %i7 225 %r0 = insertelement <8 x float> undef, float %x0, i32 0 226 %r1 = insertelement <8 x float> %r0, float %x1, i32 1 227 %r2 = insertelement <8 x float> %r1, float %x2, i32 2 228 %r3 = insertelement <8 x float> %r2, float %x3, i32 3 229 %r4 = insertelement <8 x float> %r3, float %x4, i32 4 230 %r5 = insertelement <8 x float> %r4, float %x5, i32 5 231 %r6 = insertelement <8 x float> %r5, float %x6, i32 6 232 %r7 = insertelement <8 x float> %r6, float %x7, i32 7 233 ret <8 x float> %r7 234} 235 236define <8 x float> @var_shuffle_v8f32_v4f32_xxxxxxxx_i32(<4 x float> %x, i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7) nounwind { 237; ALL-LABEL: var_shuffle_v8f32_v4f32_xxxxxxxx_i32: 238; ALL: # BB#0: 239; ALL-NEXT: # kill: %R9D<def> %R9D<kill> %R9<def> 240; ALL-NEXT: # kill: %R8D<def> %R8D<kill> %R8<def> 241; ALL-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<def> 242; ALL-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def> 243; ALL-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 244; ALL-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 245; ALL-NEXT: andl $3, %edi 246; ALL-NEXT: andl $3, %esi 247; ALL-NEXT: andl $3, %edx 248; ALL-NEXT: andl $3, %ecx 249; ALL-NEXT: andl $3, %r8d 250; ALL-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) 251; ALL-NEXT: andl $3, %r9d 252; ALL-NEXT: movl {{[0-9]+}}(%rsp), %r10d 253; ALL-NEXT: andl $3, %r10d 254; ALL-NEXT: movl {{[0-9]+}}(%rsp), %eax 255; ALL-NEXT: andl $3, %eax 256; ALL-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero 257; ALL-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3] 258; ALL-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3] 259; ALL-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0] 260; ALL-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero 261; ALL-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[2,3] 262; ALL-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1],mem[0],xmm1[3] 263; ALL-NEXT: vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],mem[0] 264; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 265; ALL-NEXT: retq 266 %x0 = extractelement <4 x float> %x, i32 %i0 267 %x1 = extractelement <4 x float> %x, i32 %i1 268 %x2 = extractelement <4 x float> %x, i32 %i2 269 %x3 = extractelement <4 x float> %x, i32 %i3 270 %x4 = extractelement <4 x float> %x, i32 %i4 271 %x5 = extractelement <4 x float> %x, i32 %i5 272 %x6 = extractelement <4 x float> %x, i32 %i6 273 %x7 = extractelement <4 x float> %x, i32 %i7 274 %r0 = insertelement <8 x float> undef, float %x0, i32 0 275 %r1 = insertelement <8 x float> %r0, float %x1, i32 1 276 %r2 = insertelement <8 x float> %r1, float %x2, i32 2 277 %r3 = insertelement <8 x float> %r2, float %x3, i32 3 278 %r4 = insertelement <8 x float> %r3, float %x4, i32 4 279 %r5 = insertelement <8 x float> %r4, float %x5, i32 5 280 %r6 = insertelement <8 x float> %r5, float %x6, i32 6 281 %r7 = insertelement <8 x float> %r6, float %x7, i32 7 282 ret <8 x float> %r7 283} 284 285define <16 x i16> @var_shuffle_v16i16_v16i16_xxxxxxxxxxxxxxxx_i16(<16 x i16> %x, i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, i32 %i11, i32 %i12, i32 %i13, i32 %i14, i32 %i15) nounwind { 286; AVX1-LABEL: var_shuffle_v16i16_v16i16_xxxxxxxxxxxxxxxx_i16: 287; AVX1: # BB#0: 288; AVX1-NEXT: pushq %rbp 289; AVX1-NEXT: movq %rsp, %rbp 290; AVX1-NEXT: andq $-32, %rsp 291; AVX1-NEXT: subq $64, %rsp 292; AVX1-NEXT: # kill: %R9D<def> %R9D<kill> %R9<def> 293; AVX1-NEXT: # kill: %R8D<def> %R8D<kill> %R8<def> 294; AVX1-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<def> 295; AVX1-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def> 296; AVX1-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 297; AVX1-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 298; AVX1-NEXT: andl $15, %edi 299; AVX1-NEXT: vmovaps %ymm0, (%rsp) 300; AVX1-NEXT: movzwl (%rsp,%rdi,2), %eax 301; AVX1-NEXT: vmovd %eax, %xmm0 302; AVX1-NEXT: andl $15, %esi 303; AVX1-NEXT: vpinsrw $1, (%rsp,%rsi,2), %xmm0, %xmm0 304; AVX1-NEXT: andl $15, %edx 305; AVX1-NEXT: vpinsrw $2, (%rsp,%rdx,2), %xmm0, %xmm0 306; AVX1-NEXT: andl $15, %ecx 307; AVX1-NEXT: vpinsrw $3, (%rsp,%rcx,2), %xmm0, %xmm0 308; AVX1-NEXT: andl $15, %r8d 309; AVX1-NEXT: vpinsrw $4, (%rsp,%r8,2), %xmm0, %xmm0 310; AVX1-NEXT: andl $15, %r9d 311; AVX1-NEXT: vpinsrw $5, (%rsp,%r9,2), %xmm0, %xmm0 312; AVX1-NEXT: movl 16(%rbp), %eax 313; AVX1-NEXT: andl $15, %eax 314; AVX1-NEXT: vpinsrw $6, (%rsp,%rax,2), %xmm0, %xmm0 315; AVX1-NEXT: movl 24(%rbp), %eax 316; AVX1-NEXT: andl $15, %eax 317; AVX1-NEXT: vpinsrw $7, (%rsp,%rax,2), %xmm0, %xmm0 318; AVX1-NEXT: movl 32(%rbp), %eax 319; AVX1-NEXT: andl $15, %eax 320; AVX1-NEXT: movzwl (%rsp,%rax,2), %eax 321; AVX1-NEXT: vmovd %eax, %xmm1 322; AVX1-NEXT: movl 40(%rbp), %eax 323; AVX1-NEXT: andl $15, %eax 324; AVX1-NEXT: vpinsrw $1, (%rsp,%rax,2), %xmm1, %xmm1 325; AVX1-NEXT: movl 48(%rbp), %eax 326; AVX1-NEXT: andl $15, %eax 327; AVX1-NEXT: vpinsrw $2, (%rsp,%rax,2), %xmm1, %xmm1 328; AVX1-NEXT: movl 56(%rbp), %eax 329; AVX1-NEXT: andl $15, %eax 330; AVX1-NEXT: vpinsrw $3, (%rsp,%rax,2), %xmm1, %xmm1 331; AVX1-NEXT: movl 64(%rbp), %eax 332; AVX1-NEXT: andl $15, %eax 333; AVX1-NEXT: vpinsrw $4, (%rsp,%rax,2), %xmm1, %xmm1 334; AVX1-NEXT: movl 72(%rbp), %eax 335; AVX1-NEXT: andl $15, %eax 336; AVX1-NEXT: vpinsrw $5, (%rsp,%rax,2), %xmm1, %xmm1 337; AVX1-NEXT: movl 80(%rbp), %eax 338; AVX1-NEXT: andl $15, %eax 339; AVX1-NEXT: vpinsrw $6, (%rsp,%rax,2), %xmm1, %xmm1 340; AVX1-NEXT: movl 88(%rbp), %eax 341; AVX1-NEXT: andl $15, %eax 342; AVX1-NEXT: vpinsrw $7, (%rsp,%rax,2), %xmm1, %xmm1 343; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 344; AVX1-NEXT: movq %rbp, %rsp 345; AVX1-NEXT: popq %rbp 346; AVX1-NEXT: retq 347; 348; AVX2-LABEL: var_shuffle_v16i16_v16i16_xxxxxxxxxxxxxxxx_i16: 349; AVX2: # BB#0: 350; AVX2-NEXT: pushq %rbp 351; AVX2-NEXT: movq %rsp, %rbp 352; AVX2-NEXT: andq $-32, %rsp 353; AVX2-NEXT: subq $64, %rsp 354; AVX2-NEXT: # kill: %R9D<def> %R9D<kill> %R9<def> 355; AVX2-NEXT: # kill: %R8D<def> %R8D<kill> %R8<def> 356; AVX2-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<def> 357; AVX2-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def> 358; AVX2-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 359; AVX2-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 360; AVX2-NEXT: andl $15, %edi 361; AVX2-NEXT: vmovaps %ymm0, (%rsp) 362; AVX2-NEXT: movzwl (%rsp,%rdi,2), %eax 363; AVX2-NEXT: vmovd %eax, %xmm0 364; AVX2-NEXT: andl $15, %esi 365; AVX2-NEXT: vpinsrw $1, (%rsp,%rsi,2), %xmm0, %xmm0 366; AVX2-NEXT: andl $15, %edx 367; AVX2-NEXT: vpinsrw $2, (%rsp,%rdx,2), %xmm0, %xmm0 368; AVX2-NEXT: andl $15, %ecx 369; AVX2-NEXT: vpinsrw $3, (%rsp,%rcx,2), %xmm0, %xmm0 370; AVX2-NEXT: andl $15, %r8d 371; AVX2-NEXT: vpinsrw $4, (%rsp,%r8,2), %xmm0, %xmm0 372; AVX2-NEXT: andl $15, %r9d 373; AVX2-NEXT: vpinsrw $5, (%rsp,%r9,2), %xmm0, %xmm0 374; AVX2-NEXT: movl 16(%rbp), %eax 375; AVX2-NEXT: andl $15, %eax 376; AVX2-NEXT: vpinsrw $6, (%rsp,%rax,2), %xmm0, %xmm0 377; AVX2-NEXT: movl 24(%rbp), %eax 378; AVX2-NEXT: andl $15, %eax 379; AVX2-NEXT: vpinsrw $7, (%rsp,%rax,2), %xmm0, %xmm0 380; AVX2-NEXT: movl 32(%rbp), %eax 381; AVX2-NEXT: andl $15, %eax 382; AVX2-NEXT: movzwl (%rsp,%rax,2), %eax 383; AVX2-NEXT: vmovd %eax, %xmm1 384; AVX2-NEXT: movl 40(%rbp), %eax 385; AVX2-NEXT: andl $15, %eax 386; AVX2-NEXT: vpinsrw $1, (%rsp,%rax,2), %xmm1, %xmm1 387; AVX2-NEXT: movl 48(%rbp), %eax 388; AVX2-NEXT: andl $15, %eax 389; AVX2-NEXT: vpinsrw $2, (%rsp,%rax,2), %xmm1, %xmm1 390; AVX2-NEXT: movl 56(%rbp), %eax 391; AVX2-NEXT: andl $15, %eax 392; AVX2-NEXT: vpinsrw $3, (%rsp,%rax,2), %xmm1, %xmm1 393; AVX2-NEXT: movl 64(%rbp), %eax 394; AVX2-NEXT: andl $15, %eax 395; AVX2-NEXT: vpinsrw $4, (%rsp,%rax,2), %xmm1, %xmm1 396; AVX2-NEXT: movl 72(%rbp), %eax 397; AVX2-NEXT: andl $15, %eax 398; AVX2-NEXT: vpinsrw $5, (%rsp,%rax,2), %xmm1, %xmm1 399; AVX2-NEXT: movl 80(%rbp), %eax 400; AVX2-NEXT: andl $15, %eax 401; AVX2-NEXT: vpinsrw $6, (%rsp,%rax,2), %xmm1, %xmm1 402; AVX2-NEXT: movl 88(%rbp), %eax 403; AVX2-NEXT: andl $15, %eax 404; AVX2-NEXT: vpinsrw $7, (%rsp,%rax,2), %xmm1, %xmm1 405; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 406; AVX2-NEXT: movq %rbp, %rsp 407; AVX2-NEXT: popq %rbp 408; AVX2-NEXT: retq 409 %x0 = extractelement <16 x i16> %x, i32 %i0 410 %x1 = extractelement <16 x i16> %x, i32 %i1 411 %x2 = extractelement <16 x i16> %x, i32 %i2 412 %x3 = extractelement <16 x i16> %x, i32 %i3 413 %x4 = extractelement <16 x i16> %x, i32 %i4 414 %x5 = extractelement <16 x i16> %x, i32 %i5 415 %x6 = extractelement <16 x i16> %x, i32 %i6 416 %x7 = extractelement <16 x i16> %x, i32 %i7 417 %x8 = extractelement <16 x i16> %x, i32 %i8 418 %x9 = extractelement <16 x i16> %x, i32 %i9 419 %x10 = extractelement <16 x i16> %x, i32 %i10 420 %x11 = extractelement <16 x i16> %x, i32 %i11 421 %x12 = extractelement <16 x i16> %x, i32 %i12 422 %x13 = extractelement <16 x i16> %x, i32 %i13 423 %x14 = extractelement <16 x i16> %x, i32 %i14 424 %x15 = extractelement <16 x i16> %x, i32 %i15 425 %r0 = insertelement <16 x i16> undef, i16 %x0 , i32 0 426 %r1 = insertelement <16 x i16> %r0 , i16 %x1 , i32 1 427 %r2 = insertelement <16 x i16> %r1 , i16 %x2 , i32 2 428 %r3 = insertelement <16 x i16> %r2 , i16 %x3 , i32 3 429 %r4 = insertelement <16 x i16> %r3 , i16 %x4 , i32 4 430 %r5 = insertelement <16 x i16> %r4 , i16 %x5 , i32 5 431 %r6 = insertelement <16 x i16> %r5 , i16 %x6 , i32 6 432 %r7 = insertelement <16 x i16> %r6 , i16 %x7 , i32 7 433 %r8 = insertelement <16 x i16> %r7 , i16 %x8 , i32 8 434 %r9 = insertelement <16 x i16> %r8 , i16 %x9 , i32 9 435 %r10 = insertelement <16 x i16> %r9 , i16 %x10, i32 10 436 %r11 = insertelement <16 x i16> %r10, i16 %x11, i32 11 437 %r12 = insertelement <16 x i16> %r11, i16 %x12, i32 12 438 %r13 = insertelement <16 x i16> %r12, i16 %x13, i32 13 439 %r14 = insertelement <16 x i16> %r13, i16 %x14, i32 14 440 %r15 = insertelement <16 x i16> %r14, i16 %x15, i32 15 441 ret <16 x i16> %r15 442} 443 444define <16 x i16> @var_shuffle_v16i16_v8i16_xxxxxxxxxxxxxxxx_i16(<8 x i16> %x, i32 %i0, i32 %i1, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i32 %i10, i32 %i11, i32 %i12, i32 %i13, i32 %i14, i32 %i15) nounwind { 445; AVX1-LABEL: var_shuffle_v16i16_v8i16_xxxxxxxxxxxxxxxx_i16: 446; AVX1: # BB#0: 447; AVX1-NEXT: # kill: %R9D<def> %R9D<kill> %R9<def> 448; AVX1-NEXT: # kill: %R8D<def> %R8D<kill> %R8<def> 449; AVX1-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<def> 450; AVX1-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def> 451; AVX1-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 452; AVX1-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 453; AVX1-NEXT: andl $7, %edi 454; AVX1-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) 455; AVX1-NEXT: movzwl -24(%rsp,%rdi,2), %eax 456; AVX1-NEXT: vmovd %eax, %xmm0 457; AVX1-NEXT: andl $7, %esi 458; AVX1-NEXT: vpinsrw $1, -24(%rsp,%rsi,2), %xmm0, %xmm0 459; AVX1-NEXT: andl $7, %edx 460; AVX1-NEXT: vpinsrw $2, -24(%rsp,%rdx,2), %xmm0, %xmm0 461; AVX1-NEXT: andl $7, %ecx 462; AVX1-NEXT: vpinsrw $3, -24(%rsp,%rcx,2), %xmm0, %xmm0 463; AVX1-NEXT: andl $7, %r8d 464; AVX1-NEXT: vpinsrw $4, -24(%rsp,%r8,2), %xmm0, %xmm0 465; AVX1-NEXT: andl $7, %r9d 466; AVX1-NEXT: vpinsrw $5, -24(%rsp,%r9,2), %xmm0, %xmm0 467; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 468; AVX1-NEXT: andl $7, %eax 469; AVX1-NEXT: vpinsrw $6, -24(%rsp,%rax,2), %xmm0, %xmm0 470; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 471; AVX1-NEXT: andl $7, %eax 472; AVX1-NEXT: vpinsrw $7, -24(%rsp,%rax,2), %xmm0, %xmm0 473; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 474; AVX1-NEXT: andl $7, %eax 475; AVX1-NEXT: movzwl -24(%rsp,%rax,2), %eax 476; AVX1-NEXT: vmovd %eax, %xmm1 477; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 478; AVX1-NEXT: andl $7, %eax 479; AVX1-NEXT: vpinsrw $1, -24(%rsp,%rax,2), %xmm1, %xmm1 480; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 481; AVX1-NEXT: andl $7, %eax 482; AVX1-NEXT: vpinsrw $2, -24(%rsp,%rax,2), %xmm1, %xmm1 483; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 484; AVX1-NEXT: andl $7, %eax 485; AVX1-NEXT: vpinsrw $3, -24(%rsp,%rax,2), %xmm1, %xmm1 486; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 487; AVX1-NEXT: andl $7, %eax 488; AVX1-NEXT: vpinsrw $4, -24(%rsp,%rax,2), %xmm1, %xmm1 489; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 490; AVX1-NEXT: andl $7, %eax 491; AVX1-NEXT: vpinsrw $5, -24(%rsp,%rax,2), %xmm1, %xmm1 492; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 493; AVX1-NEXT: andl $7, %eax 494; AVX1-NEXT: vpinsrw $6, -24(%rsp,%rax,2), %xmm1, %xmm1 495; AVX1-NEXT: movl {{[0-9]+}}(%rsp), %eax 496; AVX1-NEXT: andl $7, %eax 497; AVX1-NEXT: vpinsrw $7, -24(%rsp,%rax,2), %xmm1, %xmm1 498; AVX1-NEXT: vinsertf128 $1, %xmm1, %ymm0, %ymm0 499; AVX1-NEXT: retq 500; 501; AVX2-LABEL: var_shuffle_v16i16_v8i16_xxxxxxxxxxxxxxxx_i16: 502; AVX2: # BB#0: 503; AVX2-NEXT: # kill: %R9D<def> %R9D<kill> %R9<def> 504; AVX2-NEXT: # kill: %R8D<def> %R8D<kill> %R8<def> 505; AVX2-NEXT: # kill: %ECX<def> %ECX<kill> %RCX<def> 506; AVX2-NEXT: # kill: %EDX<def> %EDX<kill> %RDX<def> 507; AVX2-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 508; AVX2-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 509; AVX2-NEXT: andl $7, %edi 510; AVX2-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) 511; AVX2-NEXT: movzwl -24(%rsp,%rdi,2), %eax 512; AVX2-NEXT: vmovd %eax, %xmm0 513; AVX2-NEXT: andl $7, %esi 514; AVX2-NEXT: vpinsrw $1, -24(%rsp,%rsi,2), %xmm0, %xmm0 515; AVX2-NEXT: andl $7, %edx 516; AVX2-NEXT: vpinsrw $2, -24(%rsp,%rdx,2), %xmm0, %xmm0 517; AVX2-NEXT: andl $7, %ecx 518; AVX2-NEXT: vpinsrw $3, -24(%rsp,%rcx,2), %xmm0, %xmm0 519; AVX2-NEXT: andl $7, %r8d 520; AVX2-NEXT: vpinsrw $4, -24(%rsp,%r8,2), %xmm0, %xmm0 521; AVX2-NEXT: andl $7, %r9d 522; AVX2-NEXT: vpinsrw $5, -24(%rsp,%r9,2), %xmm0, %xmm0 523; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 524; AVX2-NEXT: andl $7, %eax 525; AVX2-NEXT: vpinsrw $6, -24(%rsp,%rax,2), %xmm0, %xmm0 526; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 527; AVX2-NEXT: andl $7, %eax 528; AVX2-NEXT: vpinsrw $7, -24(%rsp,%rax,2), %xmm0, %xmm0 529; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 530; AVX2-NEXT: andl $7, %eax 531; AVX2-NEXT: movzwl -24(%rsp,%rax,2), %eax 532; AVX2-NEXT: vmovd %eax, %xmm1 533; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 534; AVX2-NEXT: andl $7, %eax 535; AVX2-NEXT: vpinsrw $1, -24(%rsp,%rax,2), %xmm1, %xmm1 536; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 537; AVX2-NEXT: andl $7, %eax 538; AVX2-NEXT: vpinsrw $2, -24(%rsp,%rax,2), %xmm1, %xmm1 539; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 540; AVX2-NEXT: andl $7, %eax 541; AVX2-NEXT: vpinsrw $3, -24(%rsp,%rax,2), %xmm1, %xmm1 542; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 543; AVX2-NEXT: andl $7, %eax 544; AVX2-NEXT: vpinsrw $4, -24(%rsp,%rax,2), %xmm1, %xmm1 545; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 546; AVX2-NEXT: andl $7, %eax 547; AVX2-NEXT: vpinsrw $5, -24(%rsp,%rax,2), %xmm1, %xmm1 548; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 549; AVX2-NEXT: andl $7, %eax 550; AVX2-NEXT: vpinsrw $6, -24(%rsp,%rax,2), %xmm1, %xmm1 551; AVX2-NEXT: movl {{[0-9]+}}(%rsp), %eax 552; AVX2-NEXT: andl $7, %eax 553; AVX2-NEXT: vpinsrw $7, -24(%rsp,%rax,2), %xmm1, %xmm1 554; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 555; AVX2-NEXT: retq 556 %x0 = extractelement <8 x i16> %x, i32 %i0 557 %x1 = extractelement <8 x i16> %x, i32 %i1 558 %x2 = extractelement <8 x i16> %x, i32 %i2 559 %x3 = extractelement <8 x i16> %x, i32 %i3 560 %x4 = extractelement <8 x i16> %x, i32 %i4 561 %x5 = extractelement <8 x i16> %x, i32 %i5 562 %x6 = extractelement <8 x i16> %x, i32 %i6 563 %x7 = extractelement <8 x i16> %x, i32 %i7 564 %x8 = extractelement <8 x i16> %x, i32 %i8 565 %x9 = extractelement <8 x i16> %x, i32 %i9 566 %x10 = extractelement <8 x i16> %x, i32 %i10 567 %x11 = extractelement <8 x i16> %x, i32 %i11 568 %x12 = extractelement <8 x i16> %x, i32 %i12 569 %x13 = extractelement <8 x i16> %x, i32 %i13 570 %x14 = extractelement <8 x i16> %x, i32 %i14 571 %x15 = extractelement <8 x i16> %x, i32 %i15 572 %r0 = insertelement <16 x i16> undef, i16 %x0 , i32 0 573 %r1 = insertelement <16 x i16> %r0 , i16 %x1 , i32 1 574 %r2 = insertelement <16 x i16> %r1 , i16 %x2 , i32 2 575 %r3 = insertelement <16 x i16> %r2 , i16 %x3 , i32 3 576 %r4 = insertelement <16 x i16> %r3 , i16 %x4 , i32 4 577 %r5 = insertelement <16 x i16> %r4 , i16 %x5 , i32 5 578 %r6 = insertelement <16 x i16> %r5 , i16 %x6 , i32 6 579 %r7 = insertelement <16 x i16> %r6 , i16 %x7 , i32 7 580 %r8 = insertelement <16 x i16> %r7 , i16 %x8 , i32 8 581 %r9 = insertelement <16 x i16> %r8 , i16 %x9 , i32 9 582 %r10 = insertelement <16 x i16> %r9 , i16 %x10, i32 10 583 %r11 = insertelement <16 x i16> %r10, i16 %x11, i32 11 584 %r12 = insertelement <16 x i16> %r11, i16 %x12, i32 12 585 %r13 = insertelement <16 x i16> %r12, i16 %x13, i32 13 586 %r14 = insertelement <16 x i16> %r13, i16 %x14, i32 14 587 %r15 = insertelement <16 x i16> %r14, i16 %x15, i32 15 588 ret <16 x i16> %r15 589} 590 591; 592; Unary shuffle indices from memory 593; 594 595define <4 x i64> @mem_shuffle_v4i64_v4i64_xxxx_i64(<4 x i64> %x, i64* %i) nounwind { 596; ALL-LABEL: mem_shuffle_v4i64_v4i64_xxxx_i64: 597; ALL: # BB#0: 598; ALL-NEXT: pushq %rbp 599; ALL-NEXT: movq %rsp, %rbp 600; ALL-NEXT: andq $-32, %rsp 601; ALL-NEXT: subq $64, %rsp 602; ALL-NEXT: movq (%rdi), %rax 603; ALL-NEXT: movq 8(%rdi), %rcx 604; ALL-NEXT: andl $3, %eax 605; ALL-NEXT: andl $3, %ecx 606; ALL-NEXT: movq 16(%rdi), %rdx 607; ALL-NEXT: andl $3, %edx 608; ALL-NEXT: movq 24(%rdi), %rsi 609; ALL-NEXT: andl $3, %esi 610; ALL-NEXT: vmovaps %ymm0, (%rsp) 611; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 612; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 613; ALL-NEXT: vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0] 614; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 615; ALL-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero 616; ALL-NEXT: vmovlhps {{.*#+}} xmm1 = xmm2[0],xmm1[0] 617; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 618; ALL-NEXT: movq %rbp, %rsp 619; ALL-NEXT: popq %rbp 620; ALL-NEXT: retq 621 %p0 = getelementptr inbounds i64, i64* %i, i32 0 622 %p1 = getelementptr inbounds i64, i64* %i, i32 1 623 %p2 = getelementptr inbounds i64, i64* %i, i32 2 624 %p3 = getelementptr inbounds i64, i64* %i, i32 3 625 %i0 = load i64, i64* %p0, align 4 626 %i1 = load i64, i64* %p1, align 4 627 %i2 = load i64, i64* %p2, align 4 628 %i3 = load i64, i64* %p3, align 4 629 %x0 = extractelement <4 x i64> %x, i64 %i0 630 %x1 = extractelement <4 x i64> %x, i64 %i1 631 %x2 = extractelement <4 x i64> %x, i64 %i2 632 %x3 = extractelement <4 x i64> %x, i64 %i3 633 %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0 634 %r1 = insertelement <4 x i64> %r0, i64 %x1, i32 1 635 %r2 = insertelement <4 x i64> %r1, i64 %x2, i32 2 636 %r3 = insertelement <4 x i64> %r2, i64 %x3, i32 3 637 ret <4 x i64> %r3 638} 639 640define <4 x i64> @mem_shuffle_v4i64_v2i64_xxxx_i64(<2 x i64> %x, i64* %i) nounwind { 641; ALL-LABEL: mem_shuffle_v4i64_v2i64_xxxx_i64: 642; ALL: # BB#0: 643; ALL-NEXT: movq (%rdi), %rax 644; ALL-NEXT: movq 8(%rdi), %rcx 645; ALL-NEXT: andl $1, %eax 646; ALL-NEXT: andl $1, %ecx 647; ALL-NEXT: movq 16(%rdi), %rdx 648; ALL-NEXT: andl $1, %edx 649; ALL-NEXT: movq 24(%rdi), %rsi 650; ALL-NEXT: andl $1, %esi 651; ALL-NEXT: vmovaps %xmm0, -{{[0-9]+}}(%rsp) 652; ALL-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero 653; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 654; ALL-NEXT: vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0] 655; ALL-NEXT: vmovsd {{.*#+}} xmm1 = mem[0],zero 656; ALL-NEXT: vmovsd {{.*#+}} xmm2 = mem[0],zero 657; ALL-NEXT: vmovlhps {{.*#+}} xmm1 = xmm2[0],xmm1[0] 658; ALL-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0 659; ALL-NEXT: retq 660 %p0 = getelementptr inbounds i64, i64* %i, i32 0 661 %p1 = getelementptr inbounds i64, i64* %i, i32 1 662 %p2 = getelementptr inbounds i64, i64* %i, i32 2 663 %p3 = getelementptr inbounds i64, i64* %i, i32 3 664 %i0 = load i64, i64* %p0, align 4 665 %i1 = load i64, i64* %p1, align 4 666 %i2 = load i64, i64* %p2, align 4 667 %i3 = load i64, i64* %p3, align 4 668 %x0 = extractelement <2 x i64> %x, i64 %i0 669 %x1 = extractelement <2 x i64> %x, i64 %i1 670 %x2 = extractelement <2 x i64> %x, i64 %i2 671 %x3 = extractelement <2 x i64> %x, i64 %i3 672 %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0 673 %r1 = insertelement <4 x i64> %r0, i64 %x1, i32 1 674 %r2 = insertelement <4 x i64> %r1, i64 %x2, i32 2 675 %r3 = insertelement <4 x i64> %r2, i64 %x3, i32 3 676 ret <4 x i64> %r3 677} 678