1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+sse2   | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
3; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
4; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+avx    | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5; RUN: llc < %s -mtriple=x86_64-pc-linux -mattr=+avx2   | FileCheck %s --check-prefix=AVX --check-prefix=AVX2
6
7;
8; ExtractElement - Constant Index
9;
10
11define i8 @extractelement_v16i8_1(<16 x i8> %a) nounwind {
12; SSE2-LABEL: extractelement_v16i8_1:
13; SSE2:       # BB#0:
14; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
15; SSE2-NEXT:    movb -{{[0-9]+}}(%rsp), %al
16; SSE2-NEXT:    retq
17;
18; SSE41-LABEL: extractelement_v16i8_1:
19; SSE41:       # BB#0:
20; SSE41-NEXT:    pextrb $1, %xmm0, %eax
21; SSE41-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
22; SSE41-NEXT:    retq
23;
24; AVX-LABEL: extractelement_v16i8_1:
25; AVX:       # BB#0:
26; AVX-NEXT:    vpextrb $1, %xmm0, %eax
27; AVX-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
28; AVX-NEXT:    retq
29  %b = extractelement <16 x i8> %a, i256 1
30  ret i8 %b
31}
32
33define i8 @extractelement_v16i8_11(<16 x i8> %a) nounwind {
34; SSE2-LABEL: extractelement_v16i8_11:
35; SSE2:       # BB#0:
36; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
37; SSE2-NEXT:    movb -{{[0-9]+}}(%rsp), %al
38; SSE2-NEXT:    retq
39;
40; SSE41-LABEL: extractelement_v16i8_11:
41; SSE41:       # BB#0:
42; SSE41-NEXT:    pextrb $11, %xmm0, %eax
43; SSE41-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
44; SSE41-NEXT:    retq
45;
46; AVX-LABEL: extractelement_v16i8_11:
47; AVX:       # BB#0:
48; AVX-NEXT:    vpextrb $11, %xmm0, %eax
49; AVX-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
50; AVX-NEXT:    retq
51  %b = extractelement <16 x i8> %a, i256 11
52  ret i8 %b
53}
54
55define i8 @extractelement_v16i8_14(<16 x i8> %a) nounwind {
56; SSE2-LABEL: extractelement_v16i8_14:
57; SSE2:       # BB#0:
58; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
59; SSE2-NEXT:    movb -{{[0-9]+}}(%rsp), %al
60; SSE2-NEXT:    retq
61;
62; SSE41-LABEL: extractelement_v16i8_14:
63; SSE41:       # BB#0:
64; SSE41-NEXT:    pextrb $14, %xmm0, %eax
65; SSE41-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
66; SSE41-NEXT:    retq
67;
68; AVX-LABEL: extractelement_v16i8_14:
69; AVX:       # BB#0:
70; AVX-NEXT:    vpextrb $14, %xmm0, %eax
71; AVX-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
72; AVX-NEXT:    retq
73  %b = extractelement <16 x i8> %a, i256 14
74  ret i8 %b
75}
76
77define i8 @extractelement_v32i8_1(<32 x i8> %a) nounwind {
78; SSE2-LABEL: extractelement_v32i8_1:
79; SSE2:       # BB#0:
80; SSE2-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
81; SSE2-NEXT:    movb -{{[0-9]+}}(%rsp), %al
82; SSE2-NEXT:    retq
83;
84; SSE41-LABEL: extractelement_v32i8_1:
85; SSE41:       # BB#0:
86; SSE41-NEXT:    pextrb $1, %xmm0, %eax
87; SSE41-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
88; SSE41-NEXT:    retq
89;
90; AVX-LABEL: extractelement_v32i8_1:
91; AVX:       # BB#0:
92; AVX-NEXT:    vpextrb $1, %xmm0, %eax
93; AVX-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
94; AVX-NEXT:    vzeroupper
95; AVX-NEXT:    retq
96  %b = extractelement <32 x i8> %a, i256 1
97  ret i8 %b
98}
99
100define i8 @extractelement_v32i8_17(<32 x i8> %a) nounwind {
101; SSE2-LABEL: extractelement_v32i8_17:
102; SSE2:       # BB#0:
103; SSE2-NEXT:    movaps %xmm1, -{{[0-9]+}}(%rsp)
104; SSE2-NEXT:    movb -{{[0-9]+}}(%rsp), %al
105; SSE2-NEXT:    retq
106;
107; SSE41-LABEL: extractelement_v32i8_17:
108; SSE41:       # BB#0:
109; SSE41-NEXT:    pextrb $1, %xmm1, %eax
110; SSE41-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
111; SSE41-NEXT:    retq
112;
113; AVX1-LABEL: extractelement_v32i8_17:
114; AVX1:       # BB#0:
115; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
116; AVX1-NEXT:    vpextrb $1, %xmm0, %eax
117; AVX1-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
118; AVX1-NEXT:    vzeroupper
119; AVX1-NEXT:    retq
120;
121; AVX2-LABEL: extractelement_v32i8_17:
122; AVX2:       # BB#0:
123; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm0
124; AVX2-NEXT:    vpextrb $1, %xmm0, %eax
125; AVX2-NEXT:    # kill: %AL<def> %AL<kill> %EAX<kill>
126; AVX2-NEXT:    vzeroupper
127; AVX2-NEXT:    retq
128  %b = extractelement <32 x i8> %a, i256 17
129  ret i8 %b
130}
131
132define i16 @extractelement_v8i16_0(<8 x i16> %a, i256 %i) nounwind {
133; SSE-LABEL: extractelement_v8i16_0:
134; SSE:       # BB#0:
135; SSE-NEXT:    movd %xmm0, %eax
136; SSE-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
137; SSE-NEXT:    retq
138;
139; AVX-LABEL: extractelement_v8i16_0:
140; AVX:       # BB#0:
141; AVX-NEXT:    vmovd %xmm0, %eax
142; AVX-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
143; AVX-NEXT:    retq
144  %b = extractelement <8 x i16> %a, i256 0
145  ret i16 %b
146}
147
148define i16 @extractelement_v8i16_3(<8 x i16> %a, i256 %i) nounwind {
149; SSE-LABEL: extractelement_v8i16_3:
150; SSE:       # BB#0:
151; SSE-NEXT:    pextrw $3, %xmm0, %eax
152; SSE-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
153; SSE-NEXT:    retq
154;
155; AVX-LABEL: extractelement_v8i16_3:
156; AVX:       # BB#0:
157; AVX-NEXT:    vpextrw $3, %xmm0, %eax
158; AVX-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
159; AVX-NEXT:    retq
160  %b = extractelement <8 x i16> %a, i256 3
161  ret i16 %b
162}
163
164define i16 @extractelement_v16i16_0(<16 x i16> %a, i256 %i) nounwind {
165; SSE-LABEL: extractelement_v16i16_0:
166; SSE:       # BB#0:
167; SSE-NEXT:    movd %xmm0, %eax
168; SSE-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
169; SSE-NEXT:    retq
170;
171; AVX-LABEL: extractelement_v16i16_0:
172; AVX:       # BB#0:
173; AVX-NEXT:    vmovd %xmm0, %eax
174; AVX-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
175; AVX-NEXT:    vzeroupper
176; AVX-NEXT:    retq
177  %b = extractelement <16 x i16> %a, i256 0
178  ret i16 %b
179}
180
181define i16 @extractelement_v16i16_13(<16 x i16> %a, i256 %i) nounwind {
182; SSE-LABEL: extractelement_v16i16_13:
183; SSE:       # BB#0:
184; SSE-NEXT:    pextrw $5, %xmm1, %eax
185; SSE-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
186; SSE-NEXT:    retq
187;
188; AVX1-LABEL: extractelement_v16i16_13:
189; AVX1:       # BB#0:
190; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
191; AVX1-NEXT:    vpextrw $5, %xmm0, %eax
192; AVX1-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
193; AVX1-NEXT:    vzeroupper
194; AVX1-NEXT:    retq
195;
196; AVX2-LABEL: extractelement_v16i16_13:
197; AVX2:       # BB#0:
198; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm0
199; AVX2-NEXT:    vpextrw $5, %xmm0, %eax
200; AVX2-NEXT:    # kill: %AX<def> %AX<kill> %EAX<kill>
201; AVX2-NEXT:    vzeroupper
202; AVX2-NEXT:    retq
203  %b = extractelement <16 x i16> %a, i256 13
204  ret i16 %b
205}
206
207define i32 @extractelement_v4i32_0(<4 x i32> %a) nounwind {
208; SSE-LABEL: extractelement_v4i32_0:
209; SSE:       # BB#0:
210; SSE-NEXT:    movd %xmm0, %eax
211; SSE-NEXT:    retq
212;
213; AVX-LABEL: extractelement_v4i32_0:
214; AVX:       # BB#0:
215; AVX-NEXT:    vmovd %xmm0, %eax
216; AVX-NEXT:    retq
217  %b = extractelement <4 x i32> %a, i256 0
218  ret i32 %b
219}
220
221define i32 @extractelement_v4i32_3(<4 x i32> %a) nounwind {
222; SSE2-LABEL: extractelement_v4i32_3:
223; SSE2:       # BB#0:
224; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3]
225; SSE2-NEXT:    movd %xmm0, %eax
226; SSE2-NEXT:    retq
227;
228; SSE41-LABEL: extractelement_v4i32_3:
229; SSE41:       # BB#0:
230; SSE41-NEXT:    pextrd $3, %xmm0, %eax
231; SSE41-NEXT:    retq
232;
233; AVX-LABEL: extractelement_v4i32_3:
234; AVX:       # BB#0:
235; AVX-NEXT:    vpextrd $3, %xmm0, %eax
236; AVX-NEXT:    retq
237  %b = extractelement <4 x i32> %a, i256 3
238  ret i32 %b
239}
240
241define i32 @extractelement_v8i32_0(<8 x i32> %a) nounwind {
242; SSE-LABEL: extractelement_v8i32_0:
243; SSE:       # BB#0:
244; SSE-NEXT:    movd %xmm1, %eax
245; SSE-NEXT:    retq
246;
247; AVX1-LABEL: extractelement_v8i32_0:
248; AVX1:       # BB#0:
249; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
250; AVX1-NEXT:    vmovd %xmm0, %eax
251; AVX1-NEXT:    vzeroupper
252; AVX1-NEXT:    retq
253;
254; AVX2-LABEL: extractelement_v8i32_0:
255; AVX2:       # BB#0:
256; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm0
257; AVX2-NEXT:    vmovd %xmm0, %eax
258; AVX2-NEXT:    vzeroupper
259; AVX2-NEXT:    retq
260  %b = extractelement <8 x i32> %a, i256 4
261  ret i32 %b
262}
263
264define i32 @extractelement_v8i32_4(<8 x i32> %a) nounwind {
265; SSE-LABEL: extractelement_v8i32_4:
266; SSE:       # BB#0:
267; SSE-NEXT:    movd %xmm1, %eax
268; SSE-NEXT:    retq
269;
270; AVX1-LABEL: extractelement_v8i32_4:
271; AVX1:       # BB#0:
272; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
273; AVX1-NEXT:    vmovd %xmm0, %eax
274; AVX1-NEXT:    vzeroupper
275; AVX1-NEXT:    retq
276;
277; AVX2-LABEL: extractelement_v8i32_4:
278; AVX2:       # BB#0:
279; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm0
280; AVX2-NEXT:    vmovd %xmm0, %eax
281; AVX2-NEXT:    vzeroupper
282; AVX2-NEXT:    retq
283  %b = extractelement <8 x i32> %a, i256 4
284  ret i32 %b
285}
286
287define i32 @extractelement_v8i32_7(<8 x i32> %a) nounwind {
288; SSE2-LABEL: extractelement_v8i32_7:
289; SSE2:       # BB#0:
290; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[3,1,2,3]
291; SSE2-NEXT:    movd %xmm0, %eax
292; SSE2-NEXT:    retq
293;
294; SSE41-LABEL: extractelement_v8i32_7:
295; SSE41:       # BB#0:
296; SSE41-NEXT:    pextrd $3, %xmm1, %eax
297; SSE41-NEXT:    retq
298;
299; AVX1-LABEL: extractelement_v8i32_7:
300; AVX1:       # BB#0:
301; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
302; AVX1-NEXT:    vpextrd $3, %xmm0, %eax
303; AVX1-NEXT:    vzeroupper
304; AVX1-NEXT:    retq
305;
306; AVX2-LABEL: extractelement_v8i32_7:
307; AVX2:       # BB#0:
308; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm0
309; AVX2-NEXT:    vpextrd $3, %xmm0, %eax
310; AVX2-NEXT:    vzeroupper
311; AVX2-NEXT:    retq
312  %b = extractelement <8 x i32> %a, i64 7
313  ret i32 %b
314}
315
316define i64 @extractelement_v2i64_0(<2 x i64> %a, i256 %i) nounwind {
317; SSE-LABEL: extractelement_v2i64_0:
318; SSE:       # BB#0:
319; SSE-NEXT:    movd %xmm0, %rax
320; SSE-NEXT:    retq
321;
322; AVX-LABEL: extractelement_v2i64_0:
323; AVX:       # BB#0:
324; AVX-NEXT:    vmovq %xmm0, %rax
325; AVX-NEXT:    retq
326  %b = extractelement <2 x i64> %a, i256 0
327  ret i64 %b
328}
329
330define i64 @extractelement_v2i64_1(<2 x i64> %a, i256 %i) nounwind {
331; SSE2-LABEL: extractelement_v2i64_1:
332; SSE2:       # BB#0:
333; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
334; SSE2-NEXT:    movd %xmm0, %rax
335; SSE2-NEXT:    retq
336;
337; SSE41-LABEL: extractelement_v2i64_1:
338; SSE41:       # BB#0:
339; SSE41-NEXT:    pextrq $1, %xmm0, %rax
340; SSE41-NEXT:    retq
341;
342; AVX-LABEL: extractelement_v2i64_1:
343; AVX:       # BB#0:
344; AVX-NEXT:    vpextrq $1, %xmm0, %rax
345; AVX-NEXT:    retq
346  %b = extractelement <2 x i64> %a, i256 1
347  ret i64 %b
348}
349
350define i64 @extractelement_v4i64_1(<4 x i64> %a, i256 %i) nounwind {
351; SSE2-LABEL: extractelement_v4i64_1:
352; SSE2:       # BB#0:
353; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
354; SSE2-NEXT:    movd %xmm0, %rax
355; SSE2-NEXT:    retq
356;
357; SSE41-LABEL: extractelement_v4i64_1:
358; SSE41:       # BB#0:
359; SSE41-NEXT:    pextrq $1, %xmm0, %rax
360; SSE41-NEXT:    retq
361;
362; AVX-LABEL: extractelement_v4i64_1:
363; AVX:       # BB#0:
364; AVX-NEXT:    vpextrq $1, %xmm0, %rax
365; AVX-NEXT:    vzeroupper
366; AVX-NEXT:    retq
367  %b = extractelement <4 x i64> %a, i256 1
368  ret i64 %b
369}
370
371define i64 @extractelement_v4i64_3(<4 x i64> %a, i256 %i) nounwind {
372; SSE2-LABEL: extractelement_v4i64_3:
373; SSE2:       # BB#0:
374; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm1[2,3,0,1]
375; SSE2-NEXT:    movd %xmm0, %rax
376; SSE2-NEXT:    retq
377;
378; SSE41-LABEL: extractelement_v4i64_3:
379; SSE41:       # BB#0:
380; SSE41-NEXT:    pextrq $1, %xmm1, %rax
381; SSE41-NEXT:    retq
382;
383; AVX1-LABEL: extractelement_v4i64_3:
384; AVX1:       # BB#0:
385; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
386; AVX1-NEXT:    vpextrq $1, %xmm0, %rax
387; AVX1-NEXT:    vzeroupper
388; AVX1-NEXT:    retq
389;
390; AVX2-LABEL: extractelement_v4i64_3:
391; AVX2:       # BB#0:
392; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm0
393; AVX2-NEXT:    vpextrq $1, %xmm0, %rax
394; AVX2-NEXT:    vzeroupper
395; AVX2-NEXT:    retq
396  %b = extractelement <4 x i64> %a, i256 3
397  ret i64 %b
398}
399
400;
401; ExtractElement - Variable Index
402;
403
404define i8 @extractelement_v16i8_var(<16 x i8> %a, i256 %i) nounwind {
405; SSE-LABEL: extractelement_v16i8_var:
406; SSE:       # BB#0:
407; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
408; SSE-NEXT:    leaq -{{[0-9]+}}(%rsp), %rax
409; SSE-NEXT:    movb (%rdi,%rax), %al
410; SSE-NEXT:    retq
411;
412; AVX-LABEL: extractelement_v16i8_var:
413; AVX:       # BB#0:
414; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
415; AVX-NEXT:    leaq -{{[0-9]+}}(%rsp), %rax
416; AVX-NEXT:    movb (%rdi,%rax), %al
417; AVX-NEXT:    retq
418  %b = extractelement <16 x i8> %a, i256 %i
419  ret i8 %b
420}
421
422define i8 @extractelement_v32i8_var(<32 x i8> %a, i256 %i) nounwind {
423; SSE-LABEL: extractelement_v32i8_var:
424; SSE:       # BB#0:
425; SSE-NEXT:    pushq %rbp
426; SSE-NEXT:    movq %rsp, %rbp
427; SSE-NEXT:    andq $-32, %rsp
428; SSE-NEXT:    subq $64, %rsp
429; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
430; SSE-NEXT:    movaps %xmm0, (%rsp)
431; SSE-NEXT:    movq %rsp, %rax
432; SSE-NEXT:    movb (%rdi,%rax), %al
433; SSE-NEXT:    movq %rbp, %rsp
434; SSE-NEXT:    popq %rbp
435; SSE-NEXT:    retq
436;
437; AVX-LABEL: extractelement_v32i8_var:
438; AVX:       # BB#0:
439; AVX-NEXT:    pushq %rbp
440; AVX-NEXT:    movq %rsp, %rbp
441; AVX-NEXT:    andq $-32, %rsp
442; AVX-NEXT:    subq $64, %rsp
443; AVX-NEXT:    vmovaps %ymm0, (%rsp)
444; AVX-NEXT:    movq %rsp, %rax
445; AVX-NEXT:    movb (%rdi,%rax), %al
446; AVX-NEXT:    movq %rbp, %rsp
447; AVX-NEXT:    popq %rbp
448; AVX-NEXT:    vzeroupper
449; AVX-NEXT:    retq
450  %b = extractelement <32 x i8> %a, i256 %i
451  ret i8 %b
452}
453
454define i16 @extractelement_v8i16_var(<8 x i16> %a, i256 %i) nounwind {
455; SSE-LABEL: extractelement_v8i16_var:
456; SSE:       # BB#0:
457; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
458; SSE-NEXT:    movzwl -24(%rsp,%rdi,2), %eax
459; SSE-NEXT:    retq
460;
461; AVX-LABEL: extractelement_v8i16_var:
462; AVX:       # BB#0:
463; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
464; AVX-NEXT:    movzwl -24(%rsp,%rdi,2), %eax
465; AVX-NEXT:    retq
466  %b = extractelement <8 x i16> %a, i256 %i
467  ret i16 %b
468}
469
470define i16 @extractelement_v16i16_var(<16 x i16> %a, i256 %i) nounwind {
471; SSE-LABEL: extractelement_v16i16_var:
472; SSE:       # BB#0:
473; SSE-NEXT:    pushq %rbp
474; SSE-NEXT:    movq %rsp, %rbp
475; SSE-NEXT:    andq $-32, %rsp
476; SSE-NEXT:    subq $64, %rsp
477; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
478; SSE-NEXT:    movaps %xmm0, (%rsp)
479; SSE-NEXT:    movzwl (%rsp,%rdi,2), %eax
480; SSE-NEXT:    movq %rbp, %rsp
481; SSE-NEXT:    popq %rbp
482; SSE-NEXT:    retq
483;
484; AVX-LABEL: extractelement_v16i16_var:
485; AVX:       # BB#0:
486; AVX-NEXT:    pushq %rbp
487; AVX-NEXT:    movq %rsp, %rbp
488; AVX-NEXT:    andq $-32, %rsp
489; AVX-NEXT:    subq $64, %rsp
490; AVX-NEXT:    vmovaps %ymm0, (%rsp)
491; AVX-NEXT:    movzwl (%rsp,%rdi,2), %eax
492; AVX-NEXT:    movq %rbp, %rsp
493; AVX-NEXT:    popq %rbp
494; AVX-NEXT:    vzeroupper
495; AVX-NEXT:    retq
496  %b = extractelement <16 x i16> %a, i256 %i
497  ret i16 %b
498}
499
500define i32 @extractelement_v4i32_var(<4 x i32> %a, i256 %i) nounwind {
501; SSE-LABEL: extractelement_v4i32_var:
502; SSE:       # BB#0:
503; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
504; SSE-NEXT:    movl -24(%rsp,%rdi,4), %eax
505; SSE-NEXT:    retq
506;
507; AVX-LABEL: extractelement_v4i32_var:
508; AVX:       # BB#0:
509; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
510; AVX-NEXT:    movl -24(%rsp,%rdi,4), %eax
511; AVX-NEXT:    retq
512  %b = extractelement <4 x i32> %a, i256 %i
513  ret i32 %b
514}
515
516define i32 @extractelement_v8i32_var(<8 x i32> %a, i256 %i) nounwind {
517; SSE-LABEL: extractelement_v8i32_var:
518; SSE:       # BB#0:
519; SSE-NEXT:    pushq %rbp
520; SSE-NEXT:    movq %rsp, %rbp
521; SSE-NEXT:    andq $-32, %rsp
522; SSE-NEXT:    subq $64, %rsp
523; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
524; SSE-NEXT:    movaps %xmm0, (%rsp)
525; SSE-NEXT:    movl (%rsp,%rdi,4), %eax
526; SSE-NEXT:    movq %rbp, %rsp
527; SSE-NEXT:    popq %rbp
528; SSE-NEXT:    retq
529;
530; AVX1-LABEL: extractelement_v8i32_var:
531; AVX1:       # BB#0:
532; AVX1-NEXT:    pushq %rbp
533; AVX1-NEXT:    movq %rsp, %rbp
534; AVX1-NEXT:    andq $-32, %rsp
535; AVX1-NEXT:    subq $64, %rsp
536; AVX1-NEXT:    vmovaps %ymm0, (%rsp)
537; AVX1-NEXT:    movl (%rsp,%rdi,4), %eax
538; AVX1-NEXT:    movq %rbp, %rsp
539; AVX1-NEXT:    popq %rbp
540; AVX1-NEXT:    vzeroupper
541; AVX1-NEXT:    retq
542;
543; AVX2-LABEL: extractelement_v8i32_var:
544; AVX2:       # BB#0:
545; AVX2-NEXT:    vmovd %edi, %xmm1
546; AVX2-NEXT:    vpermd %ymm0, %ymm1, %ymm0
547; AVX2-NEXT:    vmovd %xmm0, %eax
548; AVX2-NEXT:    vzeroupper
549; AVX2-NEXT:    retq
550  %b = extractelement <8 x i32> %a, i256 %i
551  ret i32 %b
552}
553
554define i64 @extractelement_v2i64_var(<2 x i64> %a, i256 %i) nounwind {
555; SSE-LABEL: extractelement_v2i64_var:
556; SSE:       # BB#0:
557; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
558; SSE-NEXT:    movq -24(%rsp,%rdi,8), %rax
559; SSE-NEXT:    retq
560;
561; AVX-LABEL: extractelement_v2i64_var:
562; AVX:       # BB#0:
563; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
564; AVX-NEXT:    movq -24(%rsp,%rdi,8), %rax
565; AVX-NEXT:    retq
566  %b = extractelement <2 x i64> %a, i256 %i
567  ret i64 %b
568}
569
570define i64 @extractelement_v4i64_var(<4 x i64> %a, i256 %i) nounwind {
571; SSE-LABEL: extractelement_v4i64_var:
572; SSE:       # BB#0:
573; SSE-NEXT:    pushq %rbp
574; SSE-NEXT:    movq %rsp, %rbp
575; SSE-NEXT:    andq $-32, %rsp
576; SSE-NEXT:    subq $64, %rsp
577; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
578; SSE-NEXT:    movaps %xmm0, (%rsp)
579; SSE-NEXT:    movq (%rsp,%rdi,8), %rax
580; SSE-NEXT:    movq %rbp, %rsp
581; SSE-NEXT:    popq %rbp
582; SSE-NEXT:    retq
583;
584; AVX-LABEL: extractelement_v4i64_var:
585; AVX:       # BB#0:
586; AVX-NEXT:    pushq %rbp
587; AVX-NEXT:    movq %rsp, %rbp
588; AVX-NEXT:    andq $-32, %rsp
589; AVX-NEXT:    subq $64, %rsp
590; AVX-NEXT:    vmovaps %ymm0, (%rsp)
591; AVX-NEXT:    movq (%rsp,%rdi,8), %rax
592; AVX-NEXT:    movq %rbp, %rsp
593; AVX-NEXT:    popq %rbp
594; AVX-NEXT:    vzeroupper
595; AVX-NEXT:    retq
596  %b = extractelement <4 x i64> %a, i256 %i
597  ret i64 %b
598}
599
600;
601; ExtractElement - Constant (Out Of Range) Index
602;
603
604define i8 @extractelement_32i8_m1(<32 x i8> %a) nounwind {
605; SSE-LABEL: extractelement_32i8_m1:
606; SSE:       # BB#0:
607; SSE-NEXT:    retq
608;
609; AVX-LABEL: extractelement_32i8_m1:
610; AVX:       # BB#0:
611; AVX-NEXT:    retq
612  %b = extractelement <32 x i8> %a, i256 -1
613  ret i8 %b
614}
615
616define i16 @extractelement_v16i16_m4(<16 x i16> %a, i256 %i) nounwind {
617; SSE-LABEL: extractelement_v16i16_m4:
618; SSE:       # BB#0:
619; SSE-NEXT:    retq
620;
621; AVX-LABEL: extractelement_v16i16_m4:
622; AVX:       # BB#0:
623; AVX-NEXT:    retq
624  %b = extractelement <16 x i16> %a, i256 -4
625  ret i16 %b
626}
627
628define i32 @extractelement_v8i32_15(<8 x i32> %a) nounwind {
629; SSE-LABEL: extractelement_v8i32_15:
630; SSE:       # BB#0:
631; SSE-NEXT:    retq
632;
633; AVX-LABEL: extractelement_v8i32_15:
634; AVX:       # BB#0:
635; AVX-NEXT:    retq
636  %b = extractelement <8 x i32> %a, i64 15
637  ret i32 %b
638}
639
640define i64 @extractelement_v4i64_4(<4 x i64> %a, i256 %i) nounwind {
641; SSE-LABEL: extractelement_v4i64_4:
642; SSE:       # BB#0:
643; SSE-NEXT:    retq
644;
645; AVX-LABEL: extractelement_v4i64_4:
646; AVX:       # BB#0:
647; AVX-NEXT:    retq
648  %b = extractelement <4 x i64> %a, i256 4
649  ret i64 %b
650}
651