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:    andl $15, %edi
408; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
409; SSE-NEXT:    leaq -{{[0-9]+}}(%rsp), %rax
410; SSE-NEXT:    movb (%rdi,%rax), %al
411; SSE-NEXT:    retq
412;
413; AVX-LABEL: extractelement_v16i8_var:
414; AVX:       # BB#0:
415; AVX-NEXT:    andl $15, %edi
416; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
417; AVX-NEXT:    leaq -{{[0-9]+}}(%rsp), %rax
418; AVX-NEXT:    movb (%rdi,%rax), %al
419; AVX-NEXT:    retq
420  %b = extractelement <16 x i8> %a, i256 %i
421  ret i8 %b
422}
423
424define i8 @extractelement_v32i8_var(<32 x i8> %a, i256 %i) nounwind {
425; SSE-LABEL: extractelement_v32i8_var:
426; SSE:       # BB#0:
427; SSE-NEXT:    pushq %rbp
428; SSE-NEXT:    movq %rsp, %rbp
429; SSE-NEXT:    andq $-32, %rsp
430; SSE-NEXT:    subq $64, %rsp
431; SSE-NEXT:    andl $31, %edi
432; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
433; SSE-NEXT:    movaps %xmm0, (%rsp)
434; SSE-NEXT:    movq %rsp, %rax
435; SSE-NEXT:    movb (%rdi,%rax), %al
436; SSE-NEXT:    movq %rbp, %rsp
437; SSE-NEXT:    popq %rbp
438; SSE-NEXT:    retq
439;
440; AVX-LABEL: extractelement_v32i8_var:
441; AVX:       # BB#0:
442; AVX-NEXT:    pushq %rbp
443; AVX-NEXT:    movq %rsp, %rbp
444; AVX-NEXT:    andq $-32, %rsp
445; AVX-NEXT:    subq $64, %rsp
446; AVX-NEXT:    andl $31, %edi
447; AVX-NEXT:    vmovaps %ymm0, (%rsp)
448; AVX-NEXT:    movq %rsp, %rax
449; AVX-NEXT:    movb (%rdi,%rax), %al
450; AVX-NEXT:    movq %rbp, %rsp
451; AVX-NEXT:    popq %rbp
452; AVX-NEXT:    vzeroupper
453; AVX-NEXT:    retq
454  %b = extractelement <32 x i8> %a, i256 %i
455  ret i8 %b
456}
457
458define i16 @extractelement_v8i16_var(<8 x i16> %a, i256 %i) nounwind {
459; SSE-LABEL: extractelement_v8i16_var:
460; SSE:       # BB#0:
461; SSE-NEXT:    andl $7, %edi
462; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
463; SSE-NEXT:    movzwl -24(%rsp,%rdi,2), %eax
464; SSE-NEXT:    retq
465;
466; AVX-LABEL: extractelement_v8i16_var:
467; AVX:       # BB#0:
468; AVX-NEXT:    andl $7, %edi
469; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
470; AVX-NEXT:    movzwl -24(%rsp,%rdi,2), %eax
471; AVX-NEXT:    retq
472  %b = extractelement <8 x i16> %a, i256 %i
473  ret i16 %b
474}
475
476define i16 @extractelement_v16i16_var(<16 x i16> %a, i256 %i) nounwind {
477; SSE-LABEL: extractelement_v16i16_var:
478; SSE:       # BB#0:
479; SSE-NEXT:    pushq %rbp
480; SSE-NEXT:    movq %rsp, %rbp
481; SSE-NEXT:    andq $-32, %rsp
482; SSE-NEXT:    subq $64, %rsp
483; SSE-NEXT:    andl $15, %edi
484; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
485; SSE-NEXT:    movaps %xmm0, (%rsp)
486; SSE-NEXT:    movzwl (%rsp,%rdi,2), %eax
487; SSE-NEXT:    movq %rbp, %rsp
488; SSE-NEXT:    popq %rbp
489; SSE-NEXT:    retq
490;
491; AVX-LABEL: extractelement_v16i16_var:
492; AVX:       # BB#0:
493; AVX-NEXT:    pushq %rbp
494; AVX-NEXT:    movq %rsp, %rbp
495; AVX-NEXT:    andq $-32, %rsp
496; AVX-NEXT:    subq $64, %rsp
497; AVX-NEXT:    andl $15, %edi
498; AVX-NEXT:    vmovaps %ymm0, (%rsp)
499; AVX-NEXT:    movzwl (%rsp,%rdi,2), %eax
500; AVX-NEXT:    movq %rbp, %rsp
501; AVX-NEXT:    popq %rbp
502; AVX-NEXT:    vzeroupper
503; AVX-NEXT:    retq
504  %b = extractelement <16 x i16> %a, i256 %i
505  ret i16 %b
506}
507
508define i32 @extractelement_v4i32_var(<4 x i32> %a, i256 %i) nounwind {
509; SSE-LABEL: extractelement_v4i32_var:
510; SSE:       # BB#0:
511; SSE-NEXT:    andl $3, %edi
512; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
513; SSE-NEXT:    movl -24(%rsp,%rdi,4), %eax
514; SSE-NEXT:    retq
515;
516; AVX-LABEL: extractelement_v4i32_var:
517; AVX:       # BB#0:
518; AVX-NEXT:    andl $3, %edi
519; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
520; AVX-NEXT:    movl -24(%rsp,%rdi,4), %eax
521; AVX-NEXT:    retq
522  %b = extractelement <4 x i32> %a, i256 %i
523  ret i32 %b
524}
525
526define i32 @extractelement_v8i32_var(<8 x i32> %a, i256 %i) nounwind {
527; SSE-LABEL: extractelement_v8i32_var:
528; SSE:       # BB#0:
529; SSE-NEXT:    pushq %rbp
530; SSE-NEXT:    movq %rsp, %rbp
531; SSE-NEXT:    andq $-32, %rsp
532; SSE-NEXT:    subq $64, %rsp
533; SSE-NEXT:    andl $7, %edi
534; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
535; SSE-NEXT:    movaps %xmm0, (%rsp)
536; SSE-NEXT:    movl (%rsp,%rdi,4), %eax
537; SSE-NEXT:    movq %rbp, %rsp
538; SSE-NEXT:    popq %rbp
539; SSE-NEXT:    retq
540;
541; AVX1-LABEL: extractelement_v8i32_var:
542; AVX1:       # BB#0:
543; AVX1-NEXT:    pushq %rbp
544; AVX1-NEXT:    movq %rsp, %rbp
545; AVX1-NEXT:    andq $-32, %rsp
546; AVX1-NEXT:    subq $64, %rsp
547; AVX1-NEXT:    andl $7, %edi
548; AVX1-NEXT:    vmovaps %ymm0, (%rsp)
549; AVX1-NEXT:    movl (%rsp,%rdi,4), %eax
550; AVX1-NEXT:    movq %rbp, %rsp
551; AVX1-NEXT:    popq %rbp
552; AVX1-NEXT:    vzeroupper
553; AVX1-NEXT:    retq
554;
555; AVX2-LABEL: extractelement_v8i32_var:
556; AVX2:       # BB#0:
557; AVX2-NEXT:    vmovd %edi, %xmm1
558; AVX2-NEXT:    vpermd %ymm0, %ymm1, %ymm0
559; AVX2-NEXT:    vmovd %xmm0, %eax
560; AVX2-NEXT:    vzeroupper
561; AVX2-NEXT:    retq
562  %b = extractelement <8 x i32> %a, i256 %i
563  ret i32 %b
564}
565
566define i64 @extractelement_v2i64_var(<2 x i64> %a, i256 %i) nounwind {
567; SSE-LABEL: extractelement_v2i64_var:
568; SSE:       # BB#0:
569; SSE-NEXT:    andl $1, %edi
570; SSE-NEXT:    movaps %xmm0, -{{[0-9]+}}(%rsp)
571; SSE-NEXT:    movq -24(%rsp,%rdi,8), %rax
572; SSE-NEXT:    retq
573;
574; AVX-LABEL: extractelement_v2i64_var:
575; AVX:       # BB#0:
576; AVX-NEXT:    andl $1, %edi
577; AVX-NEXT:    vmovaps %xmm0, -{{[0-9]+}}(%rsp)
578; AVX-NEXT:    movq -24(%rsp,%rdi,8), %rax
579; AVX-NEXT:    retq
580  %b = extractelement <2 x i64> %a, i256 %i
581  ret i64 %b
582}
583
584define i64 @extractelement_v4i64_var(<4 x i64> %a, i256 %i) nounwind {
585; SSE-LABEL: extractelement_v4i64_var:
586; SSE:       # BB#0:
587; SSE-NEXT:    pushq %rbp
588; SSE-NEXT:    movq %rsp, %rbp
589; SSE-NEXT:    andq $-32, %rsp
590; SSE-NEXT:    subq $64, %rsp
591; SSE-NEXT:    andl $3, %edi
592; SSE-NEXT:    movaps %xmm1, {{[0-9]+}}(%rsp)
593; SSE-NEXT:    movaps %xmm0, (%rsp)
594; SSE-NEXT:    movq (%rsp,%rdi,8), %rax
595; SSE-NEXT:    movq %rbp, %rsp
596; SSE-NEXT:    popq %rbp
597; SSE-NEXT:    retq
598;
599; AVX-LABEL: extractelement_v4i64_var:
600; AVX:       # BB#0:
601; AVX-NEXT:    pushq %rbp
602; AVX-NEXT:    movq %rsp, %rbp
603; AVX-NEXT:    andq $-32, %rsp
604; AVX-NEXT:    subq $64, %rsp
605; AVX-NEXT:    andl $3, %edi
606; AVX-NEXT:    vmovaps %ymm0, (%rsp)
607; AVX-NEXT:    movq (%rsp,%rdi,8), %rax
608; AVX-NEXT:    movq %rbp, %rsp
609; AVX-NEXT:    popq %rbp
610; AVX-NEXT:    vzeroupper
611; AVX-NEXT:    retq
612  %b = extractelement <4 x i64> %a, i256 %i
613  ret i64 %b
614}
615
616;
617; ExtractElement - Constant (Out Of Range) Index
618;
619
620define i8 @extractelement_32i8_m1(<32 x i8> %a) nounwind {
621; SSE-LABEL: extractelement_32i8_m1:
622; SSE:       # BB#0:
623; SSE-NEXT:    retq
624;
625; AVX-LABEL: extractelement_32i8_m1:
626; AVX:       # BB#0:
627; AVX-NEXT:    retq
628  %b = extractelement <32 x i8> %a, i256 -1
629  ret i8 %b
630}
631
632define i16 @extractelement_v16i16_m4(<16 x i16> %a, i256 %i) nounwind {
633; SSE-LABEL: extractelement_v16i16_m4:
634; SSE:       # BB#0:
635; SSE-NEXT:    retq
636;
637; AVX-LABEL: extractelement_v16i16_m4:
638; AVX:       # BB#0:
639; AVX-NEXT:    retq
640  %b = extractelement <16 x i16> %a, i256 -4
641  ret i16 %b
642}
643
644define i32 @extractelement_v8i32_15(<8 x i32> %a) nounwind {
645; SSE-LABEL: extractelement_v8i32_15:
646; SSE:       # BB#0:
647; SSE-NEXT:    retq
648;
649; AVX-LABEL: extractelement_v8i32_15:
650; AVX:       # BB#0:
651; AVX-NEXT:    retq
652  %b = extractelement <8 x i32> %a, i64 15
653  ret i32 %b
654}
655
656define i64 @extractelement_v4i64_4(<4 x i64> %a, i256 %i) nounwind {
657; SSE-LABEL: extractelement_v4i64_4:
658; SSE:       # BB#0:
659; SSE-NEXT:    retq
660;
661; AVX-LABEL: extractelement_v4i64_4:
662; AVX:       # BB#0:
663; AVX-NEXT:    retq
664  %b = extractelement <4 x i64> %a, i256 4
665  ret i64 %b
666}
667