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; AVX1-LABEL: var_shuffle_v4i64_v4i64_xxxx_i64:
95; AVX1:       # BB#0:
96; AVX1-NEXT:    pushq %rbp
97; AVX1-NEXT:    movq %rsp, %rbp
98; AVX1-NEXT:    andq $-32, %rsp
99; AVX1-NEXT:    subq $64, %rsp
100; AVX1-NEXT:    andl $3, %edi
101; AVX1-NEXT:    andl $3, %esi
102; AVX1-NEXT:    andl $3, %edx
103; AVX1-NEXT:    andl $3, %ecx
104; AVX1-NEXT:    vmovaps %ymm0, (%rsp)
105; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
106; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
107; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
108; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
109; AVX1-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
110; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
111; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
112; AVX1-NEXT:    movq %rbp, %rsp
113; AVX1-NEXT:    popq %rbp
114; AVX1-NEXT:    retq
115;
116; AVX2-LABEL: var_shuffle_v4i64_v4i64_xxxx_i64:
117; AVX2:       # BB#0:
118; AVX2-NEXT:    pushq %rbp
119; AVX2-NEXT:    movq %rsp, %rbp
120; AVX2-NEXT:    andq $-32, %rsp
121; AVX2-NEXT:    subq $64, %rsp
122; AVX2-NEXT:    andl $3, %edi
123; AVX2-NEXT:    andl $3, %esi
124; AVX2-NEXT:    andl $3, %edx
125; AVX2-NEXT:    andl $3, %ecx
126; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
127; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
128; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
129; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
130; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
131; AVX2-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
132; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
133; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
134; AVX2-NEXT:    movq %rbp, %rsp
135; AVX2-NEXT:    popq %rbp
136; AVX2-NEXT:    retq
137  %x0 = extractelement <4 x i64> %x, i64 %i0
138  %x1 = extractelement <4 x i64> %x, i64 %i1
139  %x2 = extractelement <4 x i64> %x, i64 %i2
140  %x3 = extractelement <4 x i64> %x, i64 %i3
141  %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0
142  %r1 = insertelement <4 x i64>   %r0, i64 %x1, i32 1
143  %r2 = insertelement <4 x i64>   %r1, i64 %x2, i32 2
144  %r3 = insertelement <4 x i64>   %r2, i64 %x3, i32 3
145  ret <4 x i64> %r3
146}
147
148define <4 x i64> @var_shuffle_v4i64_v4i64_xx00_i64(<4 x i64> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind {
149; AVX1-LABEL: var_shuffle_v4i64_v4i64_xx00_i64:
150; AVX1:       # BB#0:
151; AVX1-NEXT:    pushq %rbp
152; AVX1-NEXT:    movq %rsp, %rbp
153; AVX1-NEXT:    andq $-32, %rsp
154; AVX1-NEXT:    subq $64, %rsp
155; AVX1-NEXT:    andl $3, %edi
156; AVX1-NEXT:    andl $3, %esi
157; AVX1-NEXT:    vmovaps %ymm0, (%rsp)
158; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
159; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
160; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
161; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
162; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
163; AVX1-NEXT:    movq %rbp, %rsp
164; AVX1-NEXT:    popq %rbp
165; AVX1-NEXT:    retq
166;
167; AVX2-LABEL: var_shuffle_v4i64_v4i64_xx00_i64:
168; AVX2:       # BB#0:
169; AVX2-NEXT:    pushq %rbp
170; AVX2-NEXT:    movq %rsp, %rbp
171; AVX2-NEXT:    andq $-32, %rsp
172; AVX2-NEXT:    subq $64, %rsp
173; AVX2-NEXT:    andl $3, %edi
174; AVX2-NEXT:    andl $3, %esi
175; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
176; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
177; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
178; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
179; AVX2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
180; AVX2-NEXT:    vinserti128 $1, %xmm1, %ymm0, %ymm0
181; AVX2-NEXT:    movq %rbp, %rsp
182; AVX2-NEXT:    popq %rbp
183; AVX2-NEXT:    retq
184  %x0 = extractelement <4 x i64> %x, i64 %i0
185  %x1 = extractelement <4 x i64> %x, i64 %i1
186  %x2 = extractelement <4 x i64> %x, i64 %i2
187  %x3 = extractelement <4 x i64> %x, i64 %i3
188  %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0
189  %r1 = insertelement <4 x i64>   %r0, i64 %x1, i32 1
190  %r2 = insertelement <4 x i64>   %r1, i64   0, i32 2
191  %r3 = insertelement <4 x i64>   %r2, i64   0, i32 3
192  ret <4 x i64> %r3
193}
194
195define <4 x i64> @var_shuffle_v4i64_v2i64_xxxx_i64(<2 x i64> %x, i64 %i0, i64 %i1, i64 %i2, i64 %i3) nounwind {
196; AVX1-LABEL: var_shuffle_v4i64_v2i64_xxxx_i64:
197; AVX1:       # BB#0:
198; AVX1-NEXT:    andl $1, %edi
199; AVX1-NEXT:    andl $1, %esi
200; AVX1-NEXT:    andl $1, %edx
201; AVX1-NEXT:    andl $1, %ecx
202; AVX1-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
203; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
204; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
205; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
206; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
207; AVX1-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
208; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
209; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
210; AVX1-NEXT:    retq
211;
212; AVX2-LABEL: var_shuffle_v4i64_v2i64_xxxx_i64:
213; AVX2:       # BB#0:
214; AVX2-NEXT:    andl $1, %edi
215; AVX2-NEXT:    andl $1, %esi
216; AVX2-NEXT:    andl $1, %edx
217; AVX2-NEXT:    andl $1, %ecx
218; AVX2-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
219; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
220; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
221; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
222; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
223; AVX2-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
224; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
225; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
226; AVX2-NEXT:    retq
227  %x0 = extractelement <2 x i64> %x, i64 %i0
228  %x1 = extractelement <2 x i64> %x, i64 %i1
229  %x2 = extractelement <2 x i64> %x, i64 %i2
230  %x3 = extractelement <2 x i64> %x, i64 %i3
231  %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0
232  %r1 = insertelement <4 x i64>   %r0, i64 %x1, i32 1
233  %r2 = insertelement <4 x i64>   %r1, i64 %x2, i32 2
234  %r3 = insertelement <4 x i64>   %r2, i64 %x3, i32 3
235  ret <4 x i64> %r3
236}
237
238define <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 {
239; ALL-LABEL: var_shuffle_v8f32_v8f32_xxxxxxxx_i32:
240; ALL:       # BB#0:
241; ALL-NEXT:    pushq %rbp
242; ALL-NEXT:    movq %rsp, %rbp
243; ALL-NEXT:    andq $-32, %rsp
244; ALL-NEXT:    subq $64, %rsp
245; ALL-NEXT:    # kill: %R9D<def> %R9D<kill> %R9<def>
246; ALL-NEXT:    # kill: %R8D<def> %R8D<kill> %R8<def>
247; ALL-NEXT:    # kill: %ECX<def> %ECX<kill> %RCX<def>
248; ALL-NEXT:    # kill: %EDX<def> %EDX<kill> %RDX<def>
249; ALL-NEXT:    # kill: %ESI<def> %ESI<kill> %RSI<def>
250; ALL-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
251; ALL-NEXT:    andl $7, %edi
252; ALL-NEXT:    andl $7, %esi
253; ALL-NEXT:    andl $7, %edx
254; ALL-NEXT:    andl $7, %ecx
255; ALL-NEXT:    andl $7, %r8d
256; ALL-NEXT:    vmovaps %ymm0, (%rsp)
257; ALL-NEXT:    andl $7, %r9d
258; ALL-NEXT:    movl 16(%rbp), %r10d
259; ALL-NEXT:    andl $7, %r10d
260; ALL-NEXT:    movl 24(%rbp), %eax
261; ALL-NEXT:    andl $7, %eax
262; ALL-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
263; ALL-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]
264; ALL-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
265; ALL-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
266; ALL-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
267; ALL-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[2,3]
268; ALL-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,1],mem[0],xmm1[3]
269; ALL-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],mem[0]
270; ALL-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
271; ALL-NEXT:    movq %rbp, %rsp
272; ALL-NEXT:    popq %rbp
273; ALL-NEXT:    retq
274  %x0 = extractelement <8 x float> %x, i32 %i0
275  %x1 = extractelement <8 x float> %x, i32 %i1
276  %x2 = extractelement <8 x float> %x, i32 %i2
277  %x3 = extractelement <8 x float> %x, i32 %i3
278  %x4 = extractelement <8 x float> %x, i32 %i4
279  %x5 = extractelement <8 x float> %x, i32 %i5
280  %x6 = extractelement <8 x float> %x, i32 %i6
281  %x7 = extractelement <8 x float> %x, i32 %i7
282  %r0 = insertelement <8 x float> undef, float %x0, i32 0
283  %r1 = insertelement <8 x float>   %r0, float %x1, i32 1
284  %r2 = insertelement <8 x float>   %r1, float %x2, i32 2
285  %r3 = insertelement <8 x float>   %r2, float %x3, i32 3
286  %r4 = insertelement <8 x float>   %r3, float %x4, i32 4
287  %r5 = insertelement <8 x float>   %r4, float %x5, i32 5
288  %r6 = insertelement <8 x float>   %r5, float %x6, i32 6
289  %r7 = insertelement <8 x float>   %r6, float %x7, i32 7
290  ret <8 x float> %r7
291}
292
293define <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 {
294; ALL-LABEL: var_shuffle_v8f32_v4f32_xxxxxxxx_i32:
295; ALL:       # BB#0:
296; ALL-NEXT:    # kill: %R9D<def> %R9D<kill> %R9<def>
297; ALL-NEXT:    # kill: %R8D<def> %R8D<kill> %R8<def>
298; ALL-NEXT:    # kill: %ECX<def> %ECX<kill> %RCX<def>
299; ALL-NEXT:    # kill: %EDX<def> %EDX<kill> %RDX<def>
300; ALL-NEXT:    # kill: %ESI<def> %ESI<kill> %RSI<def>
301; ALL-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
302; ALL-NEXT:    andl $3, %edi
303; ALL-NEXT:    andl $3, %esi
304; ALL-NEXT:    andl $3, %edx
305; ALL-NEXT:    andl $3, %ecx
306; ALL-NEXT:    andl $3, %r8d
307; ALL-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
308; ALL-NEXT:    andl $3, %r9d
309; ALL-NEXT:    movl {{[0-9]+}}(%rsp), %r10d
310; ALL-NEXT:    andl $3, %r10d
311; ALL-NEXT:    movl {{[0-9]+}}(%rsp), %eax
312; ALL-NEXT:    andl $3, %eax
313; ALL-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
314; ALL-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[2,3]
315; ALL-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]
316; ALL-NEXT:    vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]
317; ALL-NEXT:    vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero
318; ALL-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[2,3]
319; ALL-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,1],mem[0],xmm1[3]
320; ALL-NEXT:    vinsertps {{.*#+}} xmm1 = xmm1[0,1,2],mem[0]
321; ALL-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
322; ALL-NEXT:    retq
323  %x0 = extractelement <4 x float> %x, i32 %i0
324  %x1 = extractelement <4 x float> %x, i32 %i1
325  %x2 = extractelement <4 x float> %x, i32 %i2
326  %x3 = extractelement <4 x float> %x, i32 %i3
327  %x4 = extractelement <4 x float> %x, i32 %i4
328  %x5 = extractelement <4 x float> %x, i32 %i5
329  %x6 = extractelement <4 x float> %x, i32 %i6
330  %x7 = extractelement <4 x float> %x, i32 %i7
331  %r0 = insertelement <8 x float> undef, float %x0, i32 0
332  %r1 = insertelement <8 x float>   %r0, float %x1, i32 1
333  %r2 = insertelement <8 x float>   %r1, float %x2, i32 2
334  %r3 = insertelement <8 x float>   %r2, float %x3, i32 3
335  %r4 = insertelement <8 x float>   %r3, float %x4, i32 4
336  %r5 = insertelement <8 x float>   %r4, float %x5, i32 5
337  %r6 = insertelement <8 x float>   %r5, float %x6, i32 6
338  %r7 = insertelement <8 x float>   %r6, float %x7, i32 7
339  ret <8 x float> %r7
340}
341
342define <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 {
343; AVX1-LABEL: var_shuffle_v16i16_v16i16_xxxxxxxxxxxxxxxx_i16:
344; AVX1:       # BB#0:
345; AVX1-NEXT:    pushq %rbp
346; AVX1-NEXT:    movq %rsp, %rbp
347; AVX1-NEXT:    andq $-32, %rsp
348; AVX1-NEXT:    subq $64, %rsp
349; AVX1-NEXT:    # kill: %R9D<def> %R9D<kill> %R9<def>
350; AVX1-NEXT:    # kill: %R8D<def> %R8D<kill> %R8<def>
351; AVX1-NEXT:    # kill: %ECX<def> %ECX<kill> %RCX<def>
352; AVX1-NEXT:    # kill: %EDX<def> %EDX<kill> %RDX<def>
353; AVX1-NEXT:    # kill: %ESI<def> %ESI<kill> %RSI<def>
354; AVX1-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
355; AVX1-NEXT:    vmovaps %ymm0, (%rsp)
356; AVX1-NEXT:    movl 32(%rbp), %eax
357; AVX1-NEXT:    andl $15, %eax
358; AVX1-NEXT:    movzwl (%rsp,%rax,2), %eax
359; AVX1-NEXT:    vmovd %eax, %xmm0
360; AVX1-NEXT:    movl 40(%rbp), %eax
361; AVX1-NEXT:    andl $15, %eax
362; AVX1-NEXT:    vpinsrw $1, (%rsp,%rax,2), %xmm0, %xmm0
363; AVX1-NEXT:    movl 48(%rbp), %eax
364; AVX1-NEXT:    andl $15, %eax
365; AVX1-NEXT:    vpinsrw $2, (%rsp,%rax,2), %xmm0, %xmm0
366; AVX1-NEXT:    movl 56(%rbp), %eax
367; AVX1-NEXT:    andl $15, %eax
368; AVX1-NEXT:    vpinsrw $3, (%rsp,%rax,2), %xmm0, %xmm0
369; AVX1-NEXT:    movl 64(%rbp), %eax
370; AVX1-NEXT:    andl $15, %eax
371; AVX1-NEXT:    vpinsrw $4, (%rsp,%rax,2), %xmm0, %xmm0
372; AVX1-NEXT:    movl 72(%rbp), %eax
373; AVX1-NEXT:    andl $15, %eax
374; AVX1-NEXT:    vpinsrw $5, (%rsp,%rax,2), %xmm0, %xmm0
375; AVX1-NEXT:    movl 80(%rbp), %eax
376; AVX1-NEXT:    andl $15, %eax
377; AVX1-NEXT:    vpinsrw $6, (%rsp,%rax,2), %xmm0, %xmm0
378; AVX1-NEXT:    movl 88(%rbp), %eax
379; AVX1-NEXT:    andl $15, %eax
380; AVX1-NEXT:    vpinsrw $7, (%rsp,%rax,2), %xmm0, %xmm0
381; AVX1-NEXT:    andl $15, %edi
382; AVX1-NEXT:    movzwl (%rsp,%rdi,2), %eax
383; AVX1-NEXT:    vmovd %eax, %xmm1
384; AVX1-NEXT:    andl $15, %esi
385; AVX1-NEXT:    vpinsrw $1, (%rsp,%rsi,2), %xmm1, %xmm1
386; AVX1-NEXT:    andl $15, %edx
387; AVX1-NEXT:    vpinsrw $2, (%rsp,%rdx,2), %xmm1, %xmm1
388; AVX1-NEXT:    andl $15, %ecx
389; AVX1-NEXT:    vpinsrw $3, (%rsp,%rcx,2), %xmm1, %xmm1
390; AVX1-NEXT:    andl $15, %r8d
391; AVX1-NEXT:    vpinsrw $4, (%rsp,%r8,2), %xmm1, %xmm1
392; AVX1-NEXT:    andl $15, %r9d
393; AVX1-NEXT:    vpinsrw $5, (%rsp,%r9,2), %xmm1, %xmm1
394; AVX1-NEXT:    movl 16(%rbp), %eax
395; AVX1-NEXT:    andl $15, %eax
396; AVX1-NEXT:    vpinsrw $6, (%rsp,%rax,2), %xmm1, %xmm1
397; AVX1-NEXT:    movl 24(%rbp), %eax
398; AVX1-NEXT:    andl $15, %eax
399; AVX1-NEXT:    vpinsrw $7, (%rsp,%rax,2), %xmm1, %xmm1
400; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
401; AVX1-NEXT:    movq %rbp, %rsp
402; AVX1-NEXT:    popq %rbp
403; AVX1-NEXT:    retq
404;
405; AVX2-LABEL: var_shuffle_v16i16_v16i16_xxxxxxxxxxxxxxxx_i16:
406; AVX2:       # BB#0:
407; AVX2-NEXT:    pushq %rbp
408; AVX2-NEXT:    movq %rsp, %rbp
409; AVX2-NEXT:    andq $-32, %rsp
410; AVX2-NEXT:    subq $64, %rsp
411; AVX2-NEXT:    # kill: %R9D<def> %R9D<kill> %R9<def>
412; AVX2-NEXT:    # kill: %R8D<def> %R8D<kill> %R8<def>
413; AVX2-NEXT:    # kill: %ECX<def> %ECX<kill> %RCX<def>
414; AVX2-NEXT:    # kill: %EDX<def> %EDX<kill> %RDX<def>
415; AVX2-NEXT:    # kill: %ESI<def> %ESI<kill> %RSI<def>
416; AVX2-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
417; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
418; AVX2-NEXT:    movl 32(%rbp), %eax
419; AVX2-NEXT:    andl $15, %eax
420; AVX2-NEXT:    movzwl (%rsp,%rax,2), %eax
421; AVX2-NEXT:    vmovd %eax, %xmm0
422; AVX2-NEXT:    movl 40(%rbp), %eax
423; AVX2-NEXT:    andl $15, %eax
424; AVX2-NEXT:    vpinsrw $1, (%rsp,%rax,2), %xmm0, %xmm0
425; AVX2-NEXT:    movl 48(%rbp), %eax
426; AVX2-NEXT:    andl $15, %eax
427; AVX2-NEXT:    vpinsrw $2, (%rsp,%rax,2), %xmm0, %xmm0
428; AVX2-NEXT:    movl 56(%rbp), %eax
429; AVX2-NEXT:    andl $15, %eax
430; AVX2-NEXT:    vpinsrw $3, (%rsp,%rax,2), %xmm0, %xmm0
431; AVX2-NEXT:    movl 64(%rbp), %eax
432; AVX2-NEXT:    andl $15, %eax
433; AVX2-NEXT:    vpinsrw $4, (%rsp,%rax,2), %xmm0, %xmm0
434; AVX2-NEXT:    movl 72(%rbp), %eax
435; AVX2-NEXT:    andl $15, %eax
436; AVX2-NEXT:    vpinsrw $5, (%rsp,%rax,2), %xmm0, %xmm0
437; AVX2-NEXT:    movl 80(%rbp), %eax
438; AVX2-NEXT:    andl $15, %eax
439; AVX2-NEXT:    vpinsrw $6, (%rsp,%rax,2), %xmm0, %xmm0
440; AVX2-NEXT:    movl 88(%rbp), %eax
441; AVX2-NEXT:    andl $15, %eax
442; AVX2-NEXT:    vpinsrw $7, (%rsp,%rax,2), %xmm0, %xmm0
443; AVX2-NEXT:    andl $15, %edi
444; AVX2-NEXT:    movzwl (%rsp,%rdi,2), %eax
445; AVX2-NEXT:    vmovd %eax, %xmm1
446; AVX2-NEXT:    andl $15, %esi
447; AVX2-NEXT:    vpinsrw $1, (%rsp,%rsi,2), %xmm1, %xmm1
448; AVX2-NEXT:    andl $15, %edx
449; AVX2-NEXT:    vpinsrw $2, (%rsp,%rdx,2), %xmm1, %xmm1
450; AVX2-NEXT:    andl $15, %ecx
451; AVX2-NEXT:    vpinsrw $3, (%rsp,%rcx,2), %xmm1, %xmm1
452; AVX2-NEXT:    andl $15, %r8d
453; AVX2-NEXT:    vpinsrw $4, (%rsp,%r8,2), %xmm1, %xmm1
454; AVX2-NEXT:    andl $15, %r9d
455; AVX2-NEXT:    vpinsrw $5, (%rsp,%r9,2), %xmm1, %xmm1
456; AVX2-NEXT:    movl 16(%rbp), %eax
457; AVX2-NEXT:    andl $15, %eax
458; AVX2-NEXT:    vpinsrw $6, (%rsp,%rax,2), %xmm1, %xmm1
459; AVX2-NEXT:    movl 24(%rbp), %eax
460; AVX2-NEXT:    andl $15, %eax
461; AVX2-NEXT:    vpinsrw $7, (%rsp,%rax,2), %xmm1, %xmm1
462; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
463; AVX2-NEXT:    movq %rbp, %rsp
464; AVX2-NEXT:    popq %rbp
465; AVX2-NEXT:    retq
466  %x0  = extractelement <16 x i16> %x, i32 %i0
467  %x1  = extractelement <16 x i16> %x, i32 %i1
468  %x2  = extractelement <16 x i16> %x, i32 %i2
469  %x3  = extractelement <16 x i16> %x, i32 %i3
470  %x4  = extractelement <16 x i16> %x, i32 %i4
471  %x5  = extractelement <16 x i16> %x, i32 %i5
472  %x6  = extractelement <16 x i16> %x, i32 %i6
473  %x7  = extractelement <16 x i16> %x, i32 %i7
474  %x8  = extractelement <16 x i16> %x, i32 %i8
475  %x9  = extractelement <16 x i16> %x, i32 %i9
476  %x10 = extractelement <16 x i16> %x, i32 %i10
477  %x11 = extractelement <16 x i16> %x, i32 %i11
478  %x12 = extractelement <16 x i16> %x, i32 %i12
479  %x13 = extractelement <16 x i16> %x, i32 %i13
480  %x14 = extractelement <16 x i16> %x, i32 %i14
481  %x15 = extractelement <16 x i16> %x, i32 %i15
482  %r0  = insertelement <16 x i16> undef, i16 %x0 , i32 0
483  %r1  = insertelement <16 x i16>  %r0 , i16 %x1 , i32 1
484  %r2  = insertelement <16 x i16>  %r1 , i16 %x2 , i32 2
485  %r3  = insertelement <16 x i16>  %r2 , i16 %x3 , i32 3
486  %r4  = insertelement <16 x i16>  %r3 , i16 %x4 , i32 4
487  %r5  = insertelement <16 x i16>  %r4 , i16 %x5 , i32 5
488  %r6  = insertelement <16 x i16>  %r5 , i16 %x6 , i32 6
489  %r7  = insertelement <16 x i16>  %r6 , i16 %x7 , i32 7
490  %r8  = insertelement <16 x i16>  %r7 , i16 %x8 , i32 8
491  %r9  = insertelement <16 x i16>  %r8 , i16 %x9 , i32 9
492  %r10 = insertelement <16 x i16>  %r9 , i16 %x10, i32 10
493  %r11 = insertelement <16 x i16>  %r10, i16 %x11, i32 11
494  %r12 = insertelement <16 x i16>  %r11, i16 %x12, i32 12
495  %r13 = insertelement <16 x i16>  %r12, i16 %x13, i32 13
496  %r14 = insertelement <16 x i16>  %r13, i16 %x14, i32 14
497  %r15 = insertelement <16 x i16>  %r14, i16 %x15, i32 15
498  ret <16 x i16> %r15
499}
500
501define <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 {
502; AVX1-LABEL: var_shuffle_v16i16_v8i16_xxxxxxxxxxxxxxxx_i16:
503; AVX1:       # BB#0:
504; AVX1-NEXT:    # kill: %R9D<def> %R9D<kill> %R9<def>
505; AVX1-NEXT:    # kill: %R8D<def> %R8D<kill> %R8<def>
506; AVX1-NEXT:    # kill: %ECX<def> %ECX<kill> %RCX<def>
507; AVX1-NEXT:    # kill: %EDX<def> %EDX<kill> %RDX<def>
508; AVX1-NEXT:    # kill: %ESI<def> %ESI<kill> %RSI<def>
509; AVX1-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
510; AVX1-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
511; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
512; AVX1-NEXT:    andl $7, %eax
513; AVX1-NEXT:    movzwl -24(%rsp,%rax,2), %eax
514; AVX1-NEXT:    vmovd %eax, %xmm0
515; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
516; AVX1-NEXT:    andl $7, %eax
517; AVX1-NEXT:    vpinsrw $1, -24(%rsp,%rax,2), %xmm0, %xmm0
518; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
519; AVX1-NEXT:    andl $7, %eax
520; AVX1-NEXT:    vpinsrw $2, -24(%rsp,%rax,2), %xmm0, %xmm0
521; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
522; AVX1-NEXT:    andl $7, %eax
523; AVX1-NEXT:    vpinsrw $3, -24(%rsp,%rax,2), %xmm0, %xmm0
524; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
525; AVX1-NEXT:    andl $7, %eax
526; AVX1-NEXT:    vpinsrw $4, -24(%rsp,%rax,2), %xmm0, %xmm0
527; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
528; AVX1-NEXT:    andl $7, %eax
529; AVX1-NEXT:    vpinsrw $5, -24(%rsp,%rax,2), %xmm0, %xmm0
530; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
531; AVX1-NEXT:    andl $7, %eax
532; AVX1-NEXT:    vpinsrw $6, -24(%rsp,%rax,2), %xmm0, %xmm0
533; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
534; AVX1-NEXT:    andl $7, %eax
535; AVX1-NEXT:    vpinsrw $7, -24(%rsp,%rax,2), %xmm0, %xmm0
536; AVX1-NEXT:    andl $7, %edi
537; AVX1-NEXT:    movzwl -24(%rsp,%rdi,2), %eax
538; AVX1-NEXT:    vmovd %eax, %xmm1
539; AVX1-NEXT:    andl $7, %esi
540; AVX1-NEXT:    vpinsrw $1, -24(%rsp,%rsi,2), %xmm1, %xmm1
541; AVX1-NEXT:    andl $7, %edx
542; AVX1-NEXT:    vpinsrw $2, -24(%rsp,%rdx,2), %xmm1, %xmm1
543; AVX1-NEXT:    andl $7, %ecx
544; AVX1-NEXT:    vpinsrw $3, -24(%rsp,%rcx,2), %xmm1, %xmm1
545; AVX1-NEXT:    andl $7, %r8d
546; AVX1-NEXT:    vpinsrw $4, -24(%rsp,%r8,2), %xmm1, %xmm1
547; AVX1-NEXT:    andl $7, %r9d
548; AVX1-NEXT:    vpinsrw $5, -24(%rsp,%r9,2), %xmm1, %xmm1
549; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
550; AVX1-NEXT:    andl $7, %eax
551; AVX1-NEXT:    vpinsrw $6, -24(%rsp,%rax,2), %xmm1, %xmm1
552; AVX1-NEXT:    movl {{[0-9]+}}(%rsp), %eax
553; AVX1-NEXT:    andl $7, %eax
554; AVX1-NEXT:    vpinsrw $7, -24(%rsp,%rax,2), %xmm1, %xmm1
555; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
556; AVX1-NEXT:    retq
557;
558; AVX2-LABEL: var_shuffle_v16i16_v8i16_xxxxxxxxxxxxxxxx_i16:
559; AVX2:       # BB#0:
560; AVX2-NEXT:    # kill: %R9D<def> %R9D<kill> %R9<def>
561; AVX2-NEXT:    # kill: %R8D<def> %R8D<kill> %R8<def>
562; AVX2-NEXT:    # kill: %ECX<def> %ECX<kill> %RCX<def>
563; AVX2-NEXT:    # kill: %EDX<def> %EDX<kill> %RDX<def>
564; AVX2-NEXT:    # kill: %ESI<def> %ESI<kill> %RSI<def>
565; AVX2-NEXT:    # kill: %EDI<def> %EDI<kill> %RDI<def>
566; AVX2-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
567; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
568; AVX2-NEXT:    andl $7, %eax
569; AVX2-NEXT:    movzwl -24(%rsp,%rax,2), %eax
570; AVX2-NEXT:    vmovd %eax, %xmm0
571; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
572; AVX2-NEXT:    andl $7, %eax
573; AVX2-NEXT:    vpinsrw $1, -24(%rsp,%rax,2), %xmm0, %xmm0
574; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
575; AVX2-NEXT:    andl $7, %eax
576; AVX2-NEXT:    vpinsrw $2, -24(%rsp,%rax,2), %xmm0, %xmm0
577; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
578; AVX2-NEXT:    andl $7, %eax
579; AVX2-NEXT:    vpinsrw $3, -24(%rsp,%rax,2), %xmm0, %xmm0
580; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
581; AVX2-NEXT:    andl $7, %eax
582; AVX2-NEXT:    vpinsrw $4, -24(%rsp,%rax,2), %xmm0, %xmm0
583; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
584; AVX2-NEXT:    andl $7, %eax
585; AVX2-NEXT:    vpinsrw $5, -24(%rsp,%rax,2), %xmm0, %xmm0
586; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
587; AVX2-NEXT:    andl $7, %eax
588; AVX2-NEXT:    vpinsrw $6, -24(%rsp,%rax,2), %xmm0, %xmm0
589; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
590; AVX2-NEXT:    andl $7, %eax
591; AVX2-NEXT:    vpinsrw $7, -24(%rsp,%rax,2), %xmm0, %xmm0
592; AVX2-NEXT:    andl $7, %edi
593; AVX2-NEXT:    movzwl -24(%rsp,%rdi,2), %eax
594; AVX2-NEXT:    vmovd %eax, %xmm1
595; AVX2-NEXT:    andl $7, %esi
596; AVX2-NEXT:    vpinsrw $1, -24(%rsp,%rsi,2), %xmm1, %xmm1
597; AVX2-NEXT:    andl $7, %edx
598; AVX2-NEXT:    vpinsrw $2, -24(%rsp,%rdx,2), %xmm1, %xmm1
599; AVX2-NEXT:    andl $7, %ecx
600; AVX2-NEXT:    vpinsrw $3, -24(%rsp,%rcx,2), %xmm1, %xmm1
601; AVX2-NEXT:    andl $7, %r8d
602; AVX2-NEXT:    vpinsrw $4, -24(%rsp,%r8,2), %xmm1, %xmm1
603; AVX2-NEXT:    andl $7, %r9d
604; AVX2-NEXT:    vpinsrw $5, -24(%rsp,%r9,2), %xmm1, %xmm1
605; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
606; AVX2-NEXT:    andl $7, %eax
607; AVX2-NEXT:    vpinsrw $6, -24(%rsp,%rax,2), %xmm1, %xmm1
608; AVX2-NEXT:    movl {{[0-9]+}}(%rsp), %eax
609; AVX2-NEXT:    andl $7, %eax
610; AVX2-NEXT:    vpinsrw $7, -24(%rsp,%rax,2), %xmm1, %xmm1
611; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
612; AVX2-NEXT:    retq
613  %x0  = extractelement <8 x i16> %x, i32 %i0
614  %x1  = extractelement <8 x i16> %x, i32 %i1
615  %x2  = extractelement <8 x i16> %x, i32 %i2
616  %x3  = extractelement <8 x i16> %x, i32 %i3
617  %x4  = extractelement <8 x i16> %x, i32 %i4
618  %x5  = extractelement <8 x i16> %x, i32 %i5
619  %x6  = extractelement <8 x i16> %x, i32 %i6
620  %x7  = extractelement <8 x i16> %x, i32 %i7
621  %x8  = extractelement <8 x i16> %x, i32 %i8
622  %x9  = extractelement <8 x i16> %x, i32 %i9
623  %x10 = extractelement <8 x i16> %x, i32 %i10
624  %x11 = extractelement <8 x i16> %x, i32 %i11
625  %x12 = extractelement <8 x i16> %x, i32 %i12
626  %x13 = extractelement <8 x i16> %x, i32 %i13
627  %x14 = extractelement <8 x i16> %x, i32 %i14
628  %x15 = extractelement <8 x i16> %x, i32 %i15
629  %r0  = insertelement <16 x i16> undef, i16 %x0 , i32 0
630  %r1  = insertelement <16 x i16>  %r0 , i16 %x1 , i32 1
631  %r2  = insertelement <16 x i16>  %r1 , i16 %x2 , i32 2
632  %r3  = insertelement <16 x i16>  %r2 , i16 %x3 , i32 3
633  %r4  = insertelement <16 x i16>  %r3 , i16 %x4 , i32 4
634  %r5  = insertelement <16 x i16>  %r4 , i16 %x5 , i32 5
635  %r6  = insertelement <16 x i16>  %r5 , i16 %x6 , i32 6
636  %r7  = insertelement <16 x i16>  %r6 , i16 %x7 , i32 7
637  %r8  = insertelement <16 x i16>  %r7 , i16 %x8 , i32 8
638  %r9  = insertelement <16 x i16>  %r8 , i16 %x9 , i32 9
639  %r10 = insertelement <16 x i16>  %r9 , i16 %x10, i32 10
640  %r11 = insertelement <16 x i16>  %r10, i16 %x11, i32 11
641  %r12 = insertelement <16 x i16>  %r11, i16 %x12, i32 12
642  %r13 = insertelement <16 x i16>  %r12, i16 %x13, i32 13
643  %r14 = insertelement <16 x i16>  %r13, i16 %x14, i32 14
644  %r15 = insertelement <16 x i16>  %r14, i16 %x15, i32 15
645  ret <16 x i16> %r15
646}
647
648;
649; Unary shuffle indices from memory
650;
651
652define <4 x i64> @mem_shuffle_v4i64_v4i64_xxxx_i64(<4 x i64> %x, i64* %i) nounwind {
653; AVX1-LABEL: mem_shuffle_v4i64_v4i64_xxxx_i64:
654; AVX1:       # BB#0:
655; AVX1-NEXT:    pushq %rbp
656; AVX1-NEXT:    movq %rsp, %rbp
657; AVX1-NEXT:    andq $-32, %rsp
658; AVX1-NEXT:    subq $64, %rsp
659; AVX1-NEXT:    movq (%rdi), %rax
660; AVX1-NEXT:    movq 8(%rdi), %rcx
661; AVX1-NEXT:    andl $3, %eax
662; AVX1-NEXT:    andl $3, %ecx
663; AVX1-NEXT:    movq 16(%rdi), %rdx
664; AVX1-NEXT:    andl $3, %edx
665; AVX1-NEXT:    movq 24(%rdi), %rsi
666; AVX1-NEXT:    andl $3, %esi
667; AVX1-NEXT:    vmovaps %ymm0, (%rsp)
668; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
669; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
670; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
671; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
672; AVX1-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
673; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
674; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
675; AVX1-NEXT:    movq %rbp, %rsp
676; AVX1-NEXT:    popq %rbp
677; AVX1-NEXT:    retq
678;
679; AVX2-LABEL: mem_shuffle_v4i64_v4i64_xxxx_i64:
680; AVX2:       # BB#0:
681; AVX2-NEXT:    pushq %rbp
682; AVX2-NEXT:    movq %rsp, %rbp
683; AVX2-NEXT:    andq $-32, %rsp
684; AVX2-NEXT:    subq $64, %rsp
685; AVX2-NEXT:    movq (%rdi), %rax
686; AVX2-NEXT:    movq 8(%rdi), %rcx
687; AVX2-NEXT:    andl $3, %eax
688; AVX2-NEXT:    andl $3, %ecx
689; AVX2-NEXT:    movq 16(%rdi), %rdx
690; AVX2-NEXT:    andl $3, %edx
691; AVX2-NEXT:    movq 24(%rdi), %rsi
692; AVX2-NEXT:    andl $3, %esi
693; AVX2-NEXT:    vmovaps %ymm0, (%rsp)
694; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
695; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
696; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
697; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
698; AVX2-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
699; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
700; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
701; AVX2-NEXT:    movq %rbp, %rsp
702; AVX2-NEXT:    popq %rbp
703; AVX2-NEXT:    retq
704  %p0  = getelementptr inbounds i64, i64* %i, i32 0
705  %p1  = getelementptr inbounds i64, i64* %i, i32 1
706  %p2  = getelementptr inbounds i64, i64* %i, i32 2
707  %p3  = getelementptr inbounds i64, i64* %i, i32 3
708  %i0  = load i64, i64* %p0, align 4
709  %i1  = load i64, i64* %p1, align 4
710  %i2  = load i64, i64* %p2, align 4
711  %i3  = load i64, i64* %p3, align 4
712  %x0 = extractelement <4 x i64> %x, i64 %i0
713  %x1 = extractelement <4 x i64> %x, i64 %i1
714  %x2 = extractelement <4 x i64> %x, i64 %i2
715  %x3 = extractelement <4 x i64> %x, i64 %i3
716  %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0
717  %r1 = insertelement <4 x i64>   %r0, i64 %x1, i32 1
718  %r2 = insertelement <4 x i64>   %r1, i64 %x2, i32 2
719  %r3 = insertelement <4 x i64>   %r2, i64 %x3, i32 3
720  ret <4 x i64> %r3
721}
722
723define <4 x i64> @mem_shuffle_v4i64_v2i64_xxxx_i64(<2 x i64> %x, i64* %i) nounwind {
724; AVX1-LABEL: mem_shuffle_v4i64_v2i64_xxxx_i64:
725; AVX1:       # BB#0:
726; AVX1-NEXT:    movq (%rdi), %rax
727; AVX1-NEXT:    movq 8(%rdi), %rcx
728; AVX1-NEXT:    andl $1, %eax
729; AVX1-NEXT:    andl $1, %ecx
730; AVX1-NEXT:    movq 16(%rdi), %rdx
731; AVX1-NEXT:    andl $1, %edx
732; AVX1-NEXT:    movq 24(%rdi), %rsi
733; AVX1-NEXT:    andl $1, %esi
734; AVX1-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
735; AVX1-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
736; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
737; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
738; AVX1-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
739; AVX1-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
740; AVX1-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
741; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
742; AVX1-NEXT:    retq
743;
744; AVX2-LABEL: mem_shuffle_v4i64_v2i64_xxxx_i64:
745; AVX2:       # BB#0:
746; AVX2-NEXT:    movq (%rdi), %rax
747; AVX2-NEXT:    movq 8(%rdi), %rcx
748; AVX2-NEXT:    andl $1, %eax
749; AVX2-NEXT:    andl $1, %ecx
750; AVX2-NEXT:    movq 16(%rdi), %rdx
751; AVX2-NEXT:    andl $1, %edx
752; AVX2-NEXT:    movq 24(%rdi), %rsi
753; AVX2-NEXT:    andl $1, %esi
754; AVX2-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
755; AVX2-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero
756; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
757; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm1[0],xmm0[0]
758; AVX2-NEXT:    vmovq {{.*#+}} xmm1 = mem[0],zero
759; AVX2-NEXT:    vmovq {{.*#+}} xmm2 = mem[0],zero
760; AVX2-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm2[0],xmm1[0]
761; AVX2-NEXT:    vinserti128 $1, %xmm0, %ymm1, %ymm0
762; AVX2-NEXT:    retq
763  %p0  = getelementptr inbounds i64, i64* %i, i32 0
764  %p1  = getelementptr inbounds i64, i64* %i, i32 1
765  %p2  = getelementptr inbounds i64, i64* %i, i32 2
766  %p3  = getelementptr inbounds i64, i64* %i, i32 3
767  %i0  = load i64, i64* %p0, align 4
768  %i1  = load i64, i64* %p1, align 4
769  %i2  = load i64, i64* %p2, align 4
770  %i3  = load i64, i64* %p3, align 4
771  %x0 = extractelement <2 x i64> %x, i64 %i0
772  %x1 = extractelement <2 x i64> %x, i64 %i1
773  %x2 = extractelement <2 x i64> %x, i64 %i2
774  %x3 = extractelement <2 x i64> %x, i64 %i3
775  %r0 = insertelement <4 x i64> undef, i64 %x0, i32 0
776  %r1 = insertelement <4 x i64>   %r0, i64 %x1, i32 1
777  %r2 = insertelement <4 x i64>   %r1, i64 %x2, i32 2
778  %r3 = insertelement <4 x i64>   %r2, i64 %x3, i32 3
779  ret <4 x i64> %r3
780}
781