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