[DAGCombine] Slightly improve lowering of BUILD_VECTOR into a shuffle.
[oota-llvm.git] / test / CodeGen / X86 / vec_extract-avx.ll
1 target triple = "x86_64-unknown-unknown"\r
2 \r
3 ; RUN: llc < %s -march=x86-64 -mattr=+avx | FileCheck %s\r
4 \r
5 ; When extracting multiple consecutive elements from a larger\r
6 ; vector into a smaller one, do it efficiently. We should use\r
7 ; an EXTRACT_SUBVECTOR node internally rather than a bunch of\r
8 ; single element extractions. \r
9 \r
10 ; Extracting the low elements only requires using the right kind of store.\r
11 define void @low_v8f32_to_v4f32(<8 x float> %v, <4 x float>* %ptr) {\r
12   %ext0 = extractelement <8 x float> %v, i32 0\r
13   %ext1 = extractelement <8 x float> %v, i32 1\r
14   %ext2 = extractelement <8 x float> %v, i32 2\r
15   %ext3 = extractelement <8 x float> %v, i32 3\r
16   %ins0 = insertelement <4 x float> undef, float %ext0, i32 0\r
17   %ins1 = insertelement <4 x float> %ins0, float %ext1, i32 1\r
18   %ins2 = insertelement <4 x float> %ins1, float %ext2, i32 2\r
19   %ins3 = insertelement <4 x float> %ins2, float %ext3, i32 3\r
20   store <4 x float> %ins3, <4 x float>* %ptr, align 16\r
21   ret void\r
22 \r
23 ; CHECK-LABEL: low_v8f32_to_v4f32\r
24 ; CHECK: vmovaps\r
25 ; CHECK-NEXT: vzeroupper\r
26 ; CHECK-NEXT: retq\r
27 }\r
28 \r
29 ; Extracting the high elements requires just one AVX instruction. \r
30 define void @high_v8f32_to_v4f32(<8 x float> %v, <4 x float>* %ptr) {\r
31   %ext0 = extractelement <8 x float> %v, i32 4\r
32   %ext1 = extractelement <8 x float> %v, i32 5\r
33   %ext2 = extractelement <8 x float> %v, i32 6\r
34   %ext3 = extractelement <8 x float> %v, i32 7\r
35   %ins0 = insertelement <4 x float> undef, float %ext0, i32 0\r
36   %ins1 = insertelement <4 x float> %ins0, float %ext1, i32 1\r
37   %ins2 = insertelement <4 x float> %ins1, float %ext2, i32 2\r
38   %ins3 = insertelement <4 x float> %ins2, float %ext3, i32 3\r
39   store <4 x float> %ins3, <4 x float>* %ptr, align 16\r
40   ret void\r
41 \r
42 ; CHECK-LABEL: high_v8f32_to_v4f32\r
43 ; CHECK: vextractf128\r
44 ; CHECK-NEXT: vzeroupper\r
45 ; CHECK-NEXT: retq\r
46 }\r
47 \r
48 ; Make sure element type doesn't alter the codegen. Note that\r
49 ; if we were actually using the vector in this function and\r
50 ; have AVX2, we should generate vextracti128 (the int version).\r
51 define void @high_v8i32_to_v4i32(<8 x i32> %v, <4 x i32>* %ptr) {\r
52   %ext0 = extractelement <8 x i32> %v, i32 4\r
53   %ext1 = extractelement <8 x i32> %v, i32 5\r
54   %ext2 = extractelement <8 x i32> %v, i32 6\r
55   %ext3 = extractelement <8 x i32> %v, i32 7\r
56   %ins0 = insertelement <4 x i32> undef, i32 %ext0, i32 0\r
57   %ins1 = insertelement <4 x i32> %ins0, i32 %ext1, i32 1\r
58   %ins2 = insertelement <4 x i32> %ins1, i32 %ext2, i32 2\r
59   %ins3 = insertelement <4 x i32> %ins2, i32 %ext3, i32 3\r
60   store <4 x i32> %ins3, <4 x i32>* %ptr, align 16\r
61   ret void\r
62 \r
63 ; CHECK-LABEL: high_v8i32_to_v4i32\r
64 ; CHECK: vextractf128\r
65 ; CHECK-NEXT: vzeroupper\r
66 ; CHECK-NEXT: retq\r
67 }\r
68 \r
69 ; Make sure that element size doesn't alter the codegen.\r
70 define void @high_v4f64_to_v2f64(<4 x double> %v, <2 x double>* %ptr) {\r
71   %ext0 = extractelement <4 x double> %v, i32 2\r
72   %ext1 = extractelement <4 x double> %v, i32 3\r
73   %ins0 = insertelement <2 x double> undef, double %ext0, i32 0\r
74   %ins1 = insertelement <2 x double> %ins0, double %ext1, i32 1\r
75   store <2 x double> %ins1, <2 x double>* %ptr, align 16\r
76   ret void\r
77 \r
78 ; CHECK-LABEL: high_v4f64_to_v2f64\r
79 ; CHECK: vextractf128\r
80 ; CHECK-NEXT: vzeroupper\r
81 ; CHECK-NEXT: retq\r
82 }\r