[x86] Teach the 128-bit vector shuffle lowering routines to take
[oota-llvm.git] / test / CodeGen / X86 / vector-trunc.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=SSE --check-prefix=SSSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=SSE --check-prefix=SSE41
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=AVX --check-prefix=AVX1
5
6 define <4 x i32> @trunc2x2i64(<2 x i64> %a, <2 x i64> %b) {
7 ; SSE2-LABEL: trunc2x2i64:
8 ; SSE2:       # BB#0: # %entry
9 ; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
10 ; SSE2-NEXT:    retq
11 ;
12 ; SSSE3-LABEL: trunc2x2i64:
13 ; SSSE3:       # BB#0: # %entry
14 ; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]
15 ; SSSE3-NEXT:    retq
16 ;
17 ; SSE41-LABEL: trunc2x2i64:
18 ; SSE41:       # BB#0: # %entry
19 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,1,0,2]
20 ; SSE41-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
21 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
22 ; SSE41-NEXT:    retq
23 ;
24 ; AVX-LABEL: trunc2x2i64:
25 ; AVX:       # BB#0: # %entry
26 ; AVX-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[0,1,0,2]
27 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
28 ; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
29 ; AVX-NEXT:    retq
30
31
32 entry:
33   %0 = trunc <2 x i64> %a to <2 x i32>
34   %1 = trunc <2 x i64> %b to <2 x i32>
35   %2 = shufflevector <2 x i32> %0, <2 x i32> %1, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
36   ret <4 x i32> %2
37 }
38
39 define i64 @trunc2i64(<2 x i64> %inval) {
40 ; SSE-LABEL: trunc2i64:
41 ; SSE:       # BB#0: # %entry
42 ; SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
43 ; SSE-NEXT:    movd %xmm0, %rax
44 ; SSE-NEXT:    retq
45 ;
46 ; AVX-LABEL: trunc2i64:
47 ; AVX:       # BB#0: # %entry
48 ; AVX-NEXT:    vpshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
49 ; AVX-NEXT:    vmovq %xmm0, %rax
50 ; AVX-NEXT:    retq
51
52
53 entry:
54   %0 = trunc <2 x i64> %inval to <2 x i32>
55   %1 = bitcast <2 x i32> %0 to i64
56   ret i64 %1
57 }
58
59 define <8 x i16> @trunc2x4i32(<4 x i32> %a, <4 x i32> %b) {
60 ; SSE2-LABEL: trunc2x4i32:
61 ; SSE2:       # BB#0: # %entry
62 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm1 = xmm1[0,2,2,3,4,5,6,7]
63 ; SSE2-NEXT:    pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7]
64 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
65 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
66 ; SSE2-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7]
67 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
68 ; SSE2-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
69 ; SSE2-NEXT:    retq
70 ;
71 ; SSSE3-LABEL: trunc2x4i32:
72 ; SSSE3:       # BB#0: # %entry
73 ; SSSE3-NEXT:    movdqa {{.*#+}} xmm2 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
74 ; SSSE3-NEXT:    pshufb %xmm2, %xmm1
75 ; SSSE3-NEXT:    pshufb %xmm2, %xmm0
76 ; SSSE3-NEXT:    punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]
77 ; SSSE3-NEXT:    retq
78 ;
79 ; SSE41-LABEL: trunc2x4i32:
80 ; SSE41:       # BB#0: # %entry
81 ; SSE41-NEXT:    pshufb {{.*#+}} xmm1 = xmm1[0,1,4,5,4,5,6,7,0,1,4,5,8,9,12,13]
82 ; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
83 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
84 ; SSE41-NEXT:    retq
85 ;
86 ; AVX-LABEL: trunc2x4i32:
87 ; AVX:       # BB#0: # %entry
88 ; AVX-NEXT:    vpshufb {{.*#+}} xmm1 = xmm1[0,1,4,5,4,5,6,7,0,1,4,5,8,9,12,13]
89 ; AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
90 ; AVX-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
91 ; AVX-NEXT:    retq
92
93
94
95
96 entry:
97   %0 = trunc <4 x i32> %a to <4 x i16>
98   %1 = trunc <4 x i32> %b to <4 x i16>
99   %2 = shufflevector <4 x i16> %0, <4 x i16> %1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
100   ret <8 x i16> %2
101 }
102
103 ; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524
104 define i64 @trunc4i32(<4 x i32> %inval) {
105 ; SSE2-LABEL: trunc4i32:
106 ; SSE2:       # BB#0: # %entry
107 ; SSE2-NEXT:    pshuflw {{.*#+}} xmm0 = xmm0[0,2,2,3,4,5,6,7]
108 ; SSE2-NEXT:    pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7]
109 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
110 ; SSE2-NEXT:    movd %xmm0, %rax
111 ; SSE2-NEXT:    retq
112 ;
113 ; SSSE3-LABEL: trunc4i32:
114 ; SSSE3:       # BB#0: # %entry
115 ; SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
116 ; SSSE3-NEXT:    movd %xmm0, %rax
117 ; SSSE3-NEXT:    retq
118 ;
119 ; SSE41-LABEL: trunc4i32:
120 ; SSE41:       # BB#0: # %entry
121 ; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
122 ; SSE41-NEXT:    movd %xmm0, %rax
123 ; SSE41-NEXT:    retq
124 ;
125 ; AVX-LABEL: trunc4i32:
126 ; AVX:       # BB#0: # %entry
127 ; AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15]
128 ; AVX-NEXT:    vmovq %xmm0, %rax
129 ; AVX-NEXT:    retq
130
131
132
133
134 entry:
135   %0 = trunc <4 x i32> %inval to <4 x i16>
136   %1 = bitcast <4 x i16> %0 to i64
137   ret i64 %1
138 }
139
140 define <16 x i8> @trunc2x8i16(<8 x i16> %a, <8 x i16> %b) {
141 ; SSE2-LABEL: trunc2x8i16:
142 ; SSE2:       # BB#0: # %entry
143 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [255,255,255,255,255,255,255,255]
144 ; SSE2-NEXT:    pand %xmm2, %xmm1
145 ; SSE2-NEXT:    pand %xmm2, %xmm0
146 ; SSE2-NEXT:    packuswb %xmm1, %xmm0
147 ; SSE2-NEXT:    retq
148 ;
149 ; SSSE3-LABEL: trunc2x8i16:
150 ; SSSE3:       # BB#0: # %entry
151 ; SSSE3-NEXT:    pshufb {{.*#+}} xmm1 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,2,4,6,8,10,12,14]
152 ; SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
153 ; SSSE3-NEXT:    por %xmm1, %xmm0
154 ; SSSE3-NEXT:    retq
155 ;
156 ; SSE41-LABEL: trunc2x8i16:
157 ; SSE41:       # BB#0: # %entry
158 ; SSE41-NEXT:    pshufb {{.*#+}} xmm1 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,2,4,6,8,10,12,14]
159 ; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
160 ; SSE41-NEXT:    por %xmm1, %xmm0
161 ; SSE41-NEXT:    retq
162 ;
163 ; AVX-LABEL: trunc2x8i16:
164 ; AVX:       # BB#0: # %entry
165 ; AVX-NEXT:    vpshufb {{.*#+}} xmm1 = zero,zero,zero,zero,zero,zero,zero,zero,xmm1[0,2,4,6,8,10,12,14]
166 ; AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14],zero,zero,zero,zero,zero,zero,zero,zero
167 ; AVX-NEXT:    vpor %xmm1, %xmm0, %xmm0
168 ; AVX-NEXT:    retq
169
170
171
172
173 entry:
174   %0 = trunc <8 x i16> %a to <8 x i8>
175   %1 = trunc <8 x i16> %b to <8 x i8>
176   %2 = shufflevector <8 x i8> %0, <8 x i8> %1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
177   ret <16 x i8> %2
178 }
179
180 ; PR15524 http://llvm.org/bugs/show_bug.cgi?id=15524
181 define i64 @trunc8i16(<8 x i16> %inval) {
182 ; SSE2-LABEL: trunc8i16:
183 ; SSE2:       # BB#0: # %entry
184 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
185 ; SSE2-NEXT:    packuswb %xmm0, %xmm0
186 ; SSE2-NEXT:    movd %xmm0, %rax
187 ; SSE2-NEXT:    retq
188 ;
189 ; SSSE3-LABEL: trunc8i16:
190 ; SSSE3:       # BB#0: # %entry
191 ; SSSE3-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
192 ; SSSE3-NEXT:    movd %xmm0, %rax
193 ; SSSE3-NEXT:    retq
194 ;
195 ; SSE41-LABEL: trunc8i16:
196 ; SSE41:       # BB#0: # %entry
197 ; SSE41-NEXT:    pshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
198 ; SSE41-NEXT:    movd %xmm0, %rax
199 ; SSE41-NEXT:    retq
200 ;
201 ; AVX-LABEL: trunc8i16:
202 ; AVX:       # BB#0: # %entry
203 ; AVX-NEXT:    vpshufb {{.*#+}} xmm0 = xmm0[0,2,4,6,8,10,12,14,u,u,u,u,u,u,u,u]
204 ; AVX-NEXT:    vmovq %xmm0, %rax
205 ; AVX-NEXT:    retq
206
207
208
209
210 entry:
211   %0 = trunc <8 x i16> %inval to <8 x i8>
212   %1 = bitcast <8 x i8> %0 to i64
213   ret i64 %1
214 }