]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/X86/vector-rotate-128.ll
Vendor import of llvm trunk r321414:
[FreeBSD/FreeBSD.git] / test / CodeGen / X86 / vector-rotate-128.ll
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE2
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE41
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX2
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512bw | FileCheck %s --check-prefix=ALL --check-prefix=AVX512 --check-prefix=AVX512BW
7 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f,+avx512bw,+avx512vl | FileCheck %s --check-prefix=ALL --check-prefix=AVX512 --check-prefix=AVX512VL
8 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xop,+avx | FileCheck %s --check-prefix=ALL --check-prefix=XOP --check-prefix=XOPAVX1
9 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+xop,+avx2 | FileCheck %s --check-prefix=ALL --check-prefix=XOP --check-prefix=XOPAVX2
10
11 ; Just one 32-bit run to make sure we do reasonable things for i64 rotates.
12 ; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=ALL --check-prefix=X32-SSE --check-prefix=X32-SSE2
13
14 ;
15 ; Variable Rotates
16 ;
17
18 define <2 x i64> @var_rotate_v2i64(<2 x i64> %a, <2 x i64> %b) nounwind {
19 ; SSE2-LABEL: var_rotate_v2i64:
20 ; SSE2:       # %bb.0:
21 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [64,64]
22 ; SSE2-NEXT:    psubq %xmm1, %xmm2
23 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
24 ; SSE2-NEXT:    psllq %xmm1, %xmm3
25 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
26 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
27 ; SSE2-NEXT:    psllq %xmm1, %xmm4
28 ; SSE2-NEXT:    movsd {{.*#+}} xmm4 = xmm3[0],xmm4[1]
29 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
30 ; SSE2-NEXT:    psrlq %xmm2, %xmm1
31 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
32 ; SSE2-NEXT:    psrlq %xmm2, %xmm0
33 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
34 ; SSE2-NEXT:    orpd %xmm4, %xmm0
35 ; SSE2-NEXT:    retq
36 ;
37 ; SSE41-LABEL: var_rotate_v2i64:
38 ; SSE41:       # %bb.0:
39 ; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [64,64]
40 ; SSE41-NEXT:    psubq %xmm1, %xmm2
41 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
42 ; SSE41-NEXT:    psllq %xmm1, %xmm3
43 ; SSE41-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
44 ; SSE41-NEXT:    movdqa %xmm0, %xmm4
45 ; SSE41-NEXT:    psllq %xmm1, %xmm4
46 ; SSE41-NEXT:    pblendw {{.*#+}} xmm4 = xmm3[0,1,2,3],xmm4[4,5,6,7]
47 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
48 ; SSE41-NEXT:    psrlq %xmm2, %xmm1
49 ; SSE41-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
50 ; SSE41-NEXT:    psrlq %xmm2, %xmm0
51 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm1[0,1,2,3],xmm0[4,5,6,7]
52 ; SSE41-NEXT:    por %xmm4, %xmm0
53 ; SSE41-NEXT:    retq
54 ;
55 ; AVX1-LABEL: var_rotate_v2i64:
56 ; AVX1:       # %bb.0:
57 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [64,64]
58 ; AVX1-NEXT:    vpsubq %xmm1, %xmm2, %xmm2
59 ; AVX1-NEXT:    vpsllq %xmm1, %xmm0, %xmm3
60 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
61 ; AVX1-NEXT:    vpsllq %xmm1, %xmm0, %xmm1
62 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm3[0,1,2,3],xmm1[4,5,6,7]
63 ; AVX1-NEXT:    vpsrlq %xmm2, %xmm0, %xmm3
64 ; AVX1-NEXT:    vpshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
65 ; AVX1-NEXT:    vpsrlq %xmm2, %xmm0, %xmm0
66 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm3[0,1,2,3],xmm0[4,5,6,7]
67 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
68 ; AVX1-NEXT:    retq
69 ;
70 ; AVX2-LABEL: var_rotate_v2i64:
71 ; AVX2:       # %bb.0:
72 ; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [64,64]
73 ; AVX2-NEXT:    vpsubq %xmm1, %xmm2, %xmm2
74 ; AVX2-NEXT:    vpsllvq %xmm1, %xmm0, %xmm1
75 ; AVX2-NEXT:    vpsrlvq %xmm2, %xmm0, %xmm0
76 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
77 ; AVX2-NEXT:    retq
78 ;
79 ; AVX512BW-LABEL: var_rotate_v2i64:
80 ; AVX512BW:       # %bb.0:
81 ; AVX512BW-NEXT:    # kill: def %xmm1 killed %xmm1 def %zmm1
82 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
83 ; AVX512BW-NEXT:    vprolvq %zmm1, %zmm0, %zmm0
84 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 killed %zmm0
85 ; AVX512BW-NEXT:    vzeroupper
86 ; AVX512BW-NEXT:    retq
87 ;
88 ; AVX512VL-LABEL: var_rotate_v2i64:
89 ; AVX512VL:       # %bb.0:
90 ; AVX512VL-NEXT:    vprolvq %xmm1, %xmm0, %xmm0
91 ; AVX512VL-NEXT:    retq
92 ;
93 ; XOP-LABEL: var_rotate_v2i64:
94 ; XOP:       # %bb.0:
95 ; XOP-NEXT:    vprotq %xmm1, %xmm0, %xmm0
96 ; XOP-NEXT:    retq
97 ;
98 ; X32-SSE-LABEL: var_rotate_v2i64:
99 ; X32-SSE:       # %bb.0:
100 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm2 = [64,0,64,0]
101 ; X32-SSE-NEXT:    psubq %xmm1, %xmm2
102 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm3
103 ; X32-SSE-NEXT:    psllq %xmm1, %xmm3
104 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[2,3,0,1]
105 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm4
106 ; X32-SSE-NEXT:    psllq %xmm1, %xmm4
107 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm4 = xmm3[0],xmm4[1]
108 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
109 ; X32-SSE-NEXT:    psrlq %xmm2, %xmm1
110 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[2,3,0,1]
111 ; X32-SSE-NEXT:    psrlq %xmm2, %xmm0
112 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
113 ; X32-SSE-NEXT:    orpd %xmm4, %xmm0
114 ; X32-SSE-NEXT:    retl
115   %b64 = sub <2 x i64> <i64 64, i64 64>, %b
116   %shl = shl <2 x i64> %a, %b
117   %lshr = lshr <2 x i64> %a, %b64
118   %or = or <2 x i64> %shl, %lshr
119   ret <2 x i64> %or
120 }
121
122 define <4 x i32> @var_rotate_v4i32(<4 x i32> %a, <4 x i32> %b) nounwind {
123 ; SSE2-LABEL: var_rotate_v4i32:
124 ; SSE2:       # %bb.0:
125 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [32,32,32,32]
126 ; SSE2-NEXT:    psubd %xmm1, %xmm2
127 ; SSE2-NEXT:    pslld $23, %xmm1
128 ; SSE2-NEXT:    paddd {{.*}}(%rip), %xmm1
129 ; SSE2-NEXT:    cvttps2dq %xmm1, %xmm1
130 ; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[1,1,3,3]
131 ; SSE2-NEXT:    pmuludq %xmm0, %xmm1
132 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
133 ; SSE2-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
134 ; SSE2-NEXT:    pmuludq %xmm3, %xmm4
135 ; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[0,2,2,3]
136 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
137 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
138 ; SSE2-NEXT:    psrlq $32, %xmm3
139 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
140 ; SSE2-NEXT:    psrld %xmm3, %xmm4
141 ; SSE2-NEXT:    movdqa %xmm2, %xmm3
142 ; SSE2-NEXT:    psrldq {{.*#+}} xmm3 = xmm3[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
143 ; SSE2-NEXT:    movdqa %xmm0, %xmm5
144 ; SSE2-NEXT:    psrld %xmm3, %xmm5
145 ; SSE2-NEXT:    movsd {{.*#+}} xmm5 = xmm4[0],xmm5[1]
146 ; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm5[1,3,2,3]
147 ; SSE2-NEXT:    pxor %xmm4, %xmm4
148 ; SSE2-NEXT:    movdqa %xmm2, %xmm5
149 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1]
150 ; SSE2-NEXT:    movdqa %xmm0, %xmm6
151 ; SSE2-NEXT:    psrld %xmm5, %xmm6
152 ; SSE2-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm4[2],xmm2[3],xmm4[3]
153 ; SSE2-NEXT:    psrld %xmm2, %xmm0
154 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm6[0],xmm0[1]
155 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
156 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
157 ; SSE2-NEXT:    por %xmm1, %xmm0
158 ; SSE2-NEXT:    retq
159 ;
160 ; SSE41-LABEL: var_rotate_v4i32:
161 ; SSE41:       # %bb.0:
162 ; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [32,32,32,32]
163 ; SSE41-NEXT:    psubd %xmm1, %xmm2
164 ; SSE41-NEXT:    pslld $23, %xmm1
165 ; SSE41-NEXT:    paddd {{.*}}(%rip), %xmm1
166 ; SSE41-NEXT:    cvttps2dq %xmm1, %xmm1
167 ; SSE41-NEXT:    pmulld %xmm0, %xmm1
168 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
169 ; SSE41-NEXT:    psrldq {{.*#+}} xmm3 = xmm3[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
170 ; SSE41-NEXT:    movdqa %xmm0, %xmm4
171 ; SSE41-NEXT:    psrld %xmm3, %xmm4
172 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
173 ; SSE41-NEXT:    psrlq $32, %xmm3
174 ; SSE41-NEXT:    movdqa %xmm0, %xmm5
175 ; SSE41-NEXT:    psrld %xmm3, %xmm5
176 ; SSE41-NEXT:    pblendw {{.*#+}} xmm5 = xmm5[0,1,2,3],xmm4[4,5,6,7]
177 ; SSE41-NEXT:    pxor %xmm3, %xmm3
178 ; SSE41-NEXT:    pmovzxdq {{.*#+}} xmm4 = xmm2[0],zero,xmm2[1],zero
179 ; SSE41-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm3[2],xmm2[3],xmm3[3]
180 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
181 ; SSE41-NEXT:    psrld %xmm2, %xmm3
182 ; SSE41-NEXT:    psrld %xmm4, %xmm0
183 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm3[4,5,6,7]
184 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm5[2,3],xmm0[4,5],xmm5[6,7]
185 ; SSE41-NEXT:    por %xmm1, %xmm0
186 ; SSE41-NEXT:    retq
187 ;
188 ; AVX1-LABEL: var_rotate_v4i32:
189 ; AVX1:       # %bb.0:
190 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [32,32,32,32]
191 ; AVX1-NEXT:    vpsubd %xmm1, %xmm2, %xmm2
192 ; AVX1-NEXT:    vpslld $23, %xmm1, %xmm1
193 ; AVX1-NEXT:    vpaddd {{.*}}(%rip), %xmm1, %xmm1
194 ; AVX1-NEXT:    vcvttps2dq %xmm1, %xmm1
195 ; AVX1-NEXT:    vpmulld %xmm0, %xmm1, %xmm1
196 ; AVX1-NEXT:    vpsrldq {{.*#+}} xmm3 = xmm2[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
197 ; AVX1-NEXT:    vpsrld %xmm3, %xmm0, %xmm3
198 ; AVX1-NEXT:    vpsrlq $32, %xmm2, %xmm4
199 ; AVX1-NEXT:    vpsrld %xmm4, %xmm0, %xmm4
200 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm3 = xmm4[0,1,2,3],xmm3[4,5,6,7]
201 ; AVX1-NEXT:    vpxor %xmm4, %xmm4, %xmm4
202 ; AVX1-NEXT:    vpunpckhdq {{.*#+}} xmm4 = xmm2[2],xmm4[2],xmm2[3],xmm4[3]
203 ; AVX1-NEXT:    vpsrld %xmm4, %xmm0, %xmm4
204 ; AVX1-NEXT:    vpmovzxdq {{.*#+}} xmm2 = xmm2[0],zero,xmm2[1],zero
205 ; AVX1-NEXT:    vpsrld %xmm2, %xmm0, %xmm0
206 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm4[4,5,6,7]
207 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7]
208 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
209 ; AVX1-NEXT:    retq
210 ;
211 ; AVX2-LABEL: var_rotate_v4i32:
212 ; AVX2:       # %bb.0:
213 ; AVX2-NEXT:    vpbroadcastd {{.*#+}} xmm2 = [32,32,32,32]
214 ; AVX2-NEXT:    vpsubd %xmm1, %xmm2, %xmm2
215 ; AVX2-NEXT:    vpsllvd %xmm1, %xmm0, %xmm1
216 ; AVX2-NEXT:    vpsrlvd %xmm2, %xmm0, %xmm0
217 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
218 ; AVX2-NEXT:    retq
219 ;
220 ; AVX512BW-LABEL: var_rotate_v4i32:
221 ; AVX512BW:       # %bb.0:
222 ; AVX512BW-NEXT:    # kill: def %xmm1 killed %xmm1 def %zmm1
223 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
224 ; AVX512BW-NEXT:    vprolvd %zmm1, %zmm0, %zmm0
225 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 killed %zmm0
226 ; AVX512BW-NEXT:    vzeroupper
227 ; AVX512BW-NEXT:    retq
228 ;
229 ; AVX512VL-LABEL: var_rotate_v4i32:
230 ; AVX512VL:       # %bb.0:
231 ; AVX512VL-NEXT:    vprolvd %xmm1, %xmm0, %xmm0
232 ; AVX512VL-NEXT:    retq
233 ;
234 ; XOP-LABEL: var_rotate_v4i32:
235 ; XOP:       # %bb.0:
236 ; XOP-NEXT:    vprotd %xmm1, %xmm0, %xmm0
237 ; XOP-NEXT:    retq
238 ;
239 ; X32-SSE-LABEL: var_rotate_v4i32:
240 ; X32-SSE:       # %bb.0:
241 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm2 = [32,32,32,32]
242 ; X32-SSE-NEXT:    psubd %xmm1, %xmm2
243 ; X32-SSE-NEXT:    pslld $23, %xmm1
244 ; X32-SSE-NEXT:    paddd {{\.LCPI.*}}, %xmm1
245 ; X32-SSE-NEXT:    cvttps2dq %xmm1, %xmm1
246 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm1[1,1,3,3]
247 ; X32-SSE-NEXT:    pmuludq %xmm0, %xmm1
248 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3]
249 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm4 = xmm0[1,1,3,3]
250 ; X32-SSE-NEXT:    pmuludq %xmm3, %xmm4
251 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm4[0,2,2,3]
252 ; X32-SSE-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1]
253 ; X32-SSE-NEXT:    movdqa %xmm2, %xmm3
254 ; X32-SSE-NEXT:    psrlq $32, %xmm3
255 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm4
256 ; X32-SSE-NEXT:    psrld %xmm3, %xmm4
257 ; X32-SSE-NEXT:    movdqa %xmm2, %xmm3
258 ; X32-SSE-NEXT:    psrldq {{.*#+}} xmm3 = xmm3[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
259 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm5
260 ; X32-SSE-NEXT:    psrld %xmm3, %xmm5
261 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm5 = xmm4[0],xmm5[1]
262 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm5[1,3,2,3]
263 ; X32-SSE-NEXT:    pxor %xmm4, %xmm4
264 ; X32-SSE-NEXT:    movdqa %xmm2, %xmm5
265 ; X32-SSE-NEXT:    punpckldq {{.*#+}} xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1]
266 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm6
267 ; X32-SSE-NEXT:    psrld %xmm5, %xmm6
268 ; X32-SSE-NEXT:    punpckhdq {{.*#+}} xmm2 = xmm2[2],xmm4[2],xmm2[3],xmm4[3]
269 ; X32-SSE-NEXT:    psrld %xmm2, %xmm0
270 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm6[0],xmm0[1]
271 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
272 ; X32-SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm3[0],xmm0[1],xmm3[1]
273 ; X32-SSE-NEXT:    por %xmm1, %xmm0
274 ; X32-SSE-NEXT:    retl
275   %b32 = sub <4 x i32> <i32 32, i32 32, i32 32, i32 32>, %b
276   %shl = shl <4 x i32> %a, %b
277   %lshr = lshr <4 x i32> %a, %b32
278   %or = or <4 x i32> %shl, %lshr
279   ret <4 x i32> %or
280 }
281
282 define <8 x i16> @var_rotate_v8i16(<8 x i16> %a, <8 x i16> %b) nounwind {
283 ; SSE2-LABEL: var_rotate_v8i16:
284 ; SSE2:       # %bb.0:
285 ; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [16,16,16,16,16,16,16,16]
286 ; SSE2-NEXT:    psubw %xmm1, %xmm3
287 ; SSE2-NEXT:    psllw $12, %xmm1
288 ; SSE2-NEXT:    movdqa %xmm1, %xmm2
289 ; SSE2-NEXT:    psraw $15, %xmm2
290 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
291 ; SSE2-NEXT:    psllw $8, %xmm4
292 ; SSE2-NEXT:    pand %xmm2, %xmm4
293 ; SSE2-NEXT:    pandn %xmm0, %xmm2
294 ; SSE2-NEXT:    por %xmm4, %xmm2
295 ; SSE2-NEXT:    paddw %xmm1, %xmm1
296 ; SSE2-NEXT:    movdqa %xmm1, %xmm4
297 ; SSE2-NEXT:    psraw $15, %xmm4
298 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
299 ; SSE2-NEXT:    pandn %xmm2, %xmm5
300 ; SSE2-NEXT:    psllw $4, %xmm2
301 ; SSE2-NEXT:    pand %xmm4, %xmm2
302 ; SSE2-NEXT:    por %xmm5, %xmm2
303 ; SSE2-NEXT:    paddw %xmm1, %xmm1
304 ; SSE2-NEXT:    movdqa %xmm1, %xmm4
305 ; SSE2-NEXT:    psraw $15, %xmm4
306 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
307 ; SSE2-NEXT:    pandn %xmm2, %xmm5
308 ; SSE2-NEXT:    psllw $2, %xmm2
309 ; SSE2-NEXT:    pand %xmm4, %xmm2
310 ; SSE2-NEXT:    por %xmm5, %xmm2
311 ; SSE2-NEXT:    paddw %xmm1, %xmm1
312 ; SSE2-NEXT:    psraw $15, %xmm1
313 ; SSE2-NEXT:    movdqa %xmm1, %xmm4
314 ; SSE2-NEXT:    pandn %xmm2, %xmm4
315 ; SSE2-NEXT:    psllw $1, %xmm2
316 ; SSE2-NEXT:    pand %xmm1, %xmm2
317 ; SSE2-NEXT:    psllw $12, %xmm3
318 ; SSE2-NEXT:    movdqa %xmm3, %xmm1
319 ; SSE2-NEXT:    psraw $15, %xmm1
320 ; SSE2-NEXT:    movdqa %xmm1, %xmm5
321 ; SSE2-NEXT:    pandn %xmm0, %xmm5
322 ; SSE2-NEXT:    psrlw $8, %xmm0
323 ; SSE2-NEXT:    pand %xmm1, %xmm0
324 ; SSE2-NEXT:    por %xmm5, %xmm0
325 ; SSE2-NEXT:    paddw %xmm3, %xmm3
326 ; SSE2-NEXT:    movdqa %xmm3, %xmm1
327 ; SSE2-NEXT:    psraw $15, %xmm1
328 ; SSE2-NEXT:    movdqa %xmm1, %xmm5
329 ; SSE2-NEXT:    pandn %xmm0, %xmm5
330 ; SSE2-NEXT:    psrlw $4, %xmm0
331 ; SSE2-NEXT:    pand %xmm1, %xmm0
332 ; SSE2-NEXT:    por %xmm5, %xmm0
333 ; SSE2-NEXT:    paddw %xmm3, %xmm3
334 ; SSE2-NEXT:    movdqa %xmm3, %xmm1
335 ; SSE2-NEXT:    psraw $15, %xmm1
336 ; SSE2-NEXT:    movdqa %xmm1, %xmm5
337 ; SSE2-NEXT:    pandn %xmm0, %xmm5
338 ; SSE2-NEXT:    psrlw $2, %xmm0
339 ; SSE2-NEXT:    pand %xmm1, %xmm0
340 ; SSE2-NEXT:    por %xmm5, %xmm0
341 ; SSE2-NEXT:    paddw %xmm3, %xmm3
342 ; SSE2-NEXT:    psraw $15, %xmm3
343 ; SSE2-NEXT:    movdqa %xmm3, %xmm1
344 ; SSE2-NEXT:    pandn %xmm0, %xmm1
345 ; SSE2-NEXT:    psrlw $1, %xmm0
346 ; SSE2-NEXT:    pand %xmm3, %xmm0
347 ; SSE2-NEXT:    por %xmm1, %xmm0
348 ; SSE2-NEXT:    por %xmm4, %xmm0
349 ; SSE2-NEXT:    por %xmm2, %xmm0
350 ; SSE2-NEXT:    retq
351 ;
352 ; SSE41-LABEL: var_rotate_v8i16:
353 ; SSE41:       # %bb.0:
354 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
355 ; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [16,16,16,16,16,16,16,16]
356 ; SSE41-NEXT:    psubw %xmm1, %xmm2
357 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
358 ; SSE41-NEXT:    psllw $12, %xmm0
359 ; SSE41-NEXT:    psllw $4, %xmm1
360 ; SSE41-NEXT:    por %xmm0, %xmm1
361 ; SSE41-NEXT:    movdqa %xmm1, %xmm4
362 ; SSE41-NEXT:    paddw %xmm4, %xmm4
363 ; SSE41-NEXT:    movdqa %xmm3, %xmm6
364 ; SSE41-NEXT:    psllw $8, %xmm6
365 ; SSE41-NEXT:    movdqa %xmm3, %xmm5
366 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
367 ; SSE41-NEXT:    pblendvb %xmm0, %xmm6, %xmm5
368 ; SSE41-NEXT:    movdqa %xmm5, %xmm1
369 ; SSE41-NEXT:    psllw $4, %xmm1
370 ; SSE41-NEXT:    movdqa %xmm4, %xmm0
371 ; SSE41-NEXT:    pblendvb %xmm0, %xmm1, %xmm5
372 ; SSE41-NEXT:    movdqa %xmm5, %xmm1
373 ; SSE41-NEXT:    psllw $2, %xmm1
374 ; SSE41-NEXT:    paddw %xmm4, %xmm4
375 ; SSE41-NEXT:    movdqa %xmm4, %xmm0
376 ; SSE41-NEXT:    pblendvb %xmm0, %xmm1, %xmm5
377 ; SSE41-NEXT:    movdqa %xmm5, %xmm1
378 ; SSE41-NEXT:    psllw $1, %xmm1
379 ; SSE41-NEXT:    paddw %xmm4, %xmm4
380 ; SSE41-NEXT:    movdqa %xmm4, %xmm0
381 ; SSE41-NEXT:    pblendvb %xmm0, %xmm1, %xmm5
382 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
383 ; SSE41-NEXT:    psllw $12, %xmm0
384 ; SSE41-NEXT:    psllw $4, %xmm2
385 ; SSE41-NEXT:    por %xmm0, %xmm2
386 ; SSE41-NEXT:    movdqa %xmm2, %xmm1
387 ; SSE41-NEXT:    paddw %xmm1, %xmm1
388 ; SSE41-NEXT:    movdqa %xmm3, %xmm4
389 ; SSE41-NEXT:    psrlw $8, %xmm4
390 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
391 ; SSE41-NEXT:    pblendvb %xmm0, %xmm4, %xmm3
392 ; SSE41-NEXT:    movdqa %xmm3, %xmm2
393 ; SSE41-NEXT:    psrlw $4, %xmm2
394 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
395 ; SSE41-NEXT:    pblendvb %xmm0, %xmm2, %xmm3
396 ; SSE41-NEXT:    movdqa %xmm3, %xmm2
397 ; SSE41-NEXT:    psrlw $2, %xmm2
398 ; SSE41-NEXT:    paddw %xmm1, %xmm1
399 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
400 ; SSE41-NEXT:    pblendvb %xmm0, %xmm2, %xmm3
401 ; SSE41-NEXT:    movdqa %xmm3, %xmm2
402 ; SSE41-NEXT:    psrlw $1, %xmm2
403 ; SSE41-NEXT:    paddw %xmm1, %xmm1
404 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
405 ; SSE41-NEXT:    pblendvb %xmm0, %xmm2, %xmm3
406 ; SSE41-NEXT:    por %xmm5, %xmm3
407 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
408 ; SSE41-NEXT:    retq
409 ;
410 ; AVX1-LABEL: var_rotate_v8i16:
411 ; AVX1:       # %bb.0:
412 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm2 = [16,16,16,16,16,16,16,16]
413 ; AVX1-NEXT:    vpsubw %xmm1, %xmm2, %xmm2
414 ; AVX1-NEXT:    vpsllw $12, %xmm1, %xmm3
415 ; AVX1-NEXT:    vpsllw $4, %xmm1, %xmm1
416 ; AVX1-NEXT:    vpor %xmm3, %xmm1, %xmm1
417 ; AVX1-NEXT:    vpaddw %xmm1, %xmm1, %xmm3
418 ; AVX1-NEXT:    vpsllw $8, %xmm0, %xmm4
419 ; AVX1-NEXT:    vpblendvb %xmm1, %xmm4, %xmm0, %xmm1
420 ; AVX1-NEXT:    vpsllw $4, %xmm1, %xmm4
421 ; AVX1-NEXT:    vpblendvb %xmm3, %xmm4, %xmm1, %xmm1
422 ; AVX1-NEXT:    vpsllw $2, %xmm1, %xmm4
423 ; AVX1-NEXT:    vpaddw %xmm3, %xmm3, %xmm3
424 ; AVX1-NEXT:    vpblendvb %xmm3, %xmm4, %xmm1, %xmm1
425 ; AVX1-NEXT:    vpsllw $1, %xmm1, %xmm4
426 ; AVX1-NEXT:    vpaddw %xmm3, %xmm3, %xmm3
427 ; AVX1-NEXT:    vpblendvb %xmm3, %xmm4, %xmm1, %xmm1
428 ; AVX1-NEXT:    vpsllw $12, %xmm2, %xmm3
429 ; AVX1-NEXT:    vpsllw $4, %xmm2, %xmm2
430 ; AVX1-NEXT:    vpor %xmm3, %xmm2, %xmm2
431 ; AVX1-NEXT:    vpaddw %xmm2, %xmm2, %xmm3
432 ; AVX1-NEXT:    vpsrlw $8, %xmm0, %xmm4
433 ; AVX1-NEXT:    vpblendvb %xmm2, %xmm4, %xmm0, %xmm0
434 ; AVX1-NEXT:    vpsrlw $4, %xmm0, %xmm2
435 ; AVX1-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
436 ; AVX1-NEXT:    vpsrlw $2, %xmm0, %xmm2
437 ; AVX1-NEXT:    vpaddw %xmm3, %xmm3, %xmm3
438 ; AVX1-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
439 ; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm2
440 ; AVX1-NEXT:    vpaddw %xmm3, %xmm3, %xmm3
441 ; AVX1-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
442 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
443 ; AVX1-NEXT:    retq
444 ;
445 ; AVX2-LABEL: var_rotate_v8i16:
446 ; AVX2:       # %bb.0:
447 ; AVX2-NEXT:    vmovdqa {{.*#+}} xmm2 = [16,16,16,16,16,16,16,16]
448 ; AVX2-NEXT:    vpsubw %xmm1, %xmm2, %xmm2
449 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero
450 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
451 ; AVX2-NEXT:    vpsllvd %ymm1, %ymm0, %ymm1
452 ; AVX2-NEXT:    vmovdqa {{.*#+}} ymm3 = [0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
453 ; AVX2-NEXT:    vpshufb %ymm3, %ymm1, %ymm1
454 ; AVX2-NEXT:    vpermq {{.*#+}} ymm1 = ymm1[0,2,2,3]
455 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero
456 ; AVX2-NEXT:    vpsrlvd %ymm2, %ymm0, %ymm0
457 ; AVX2-NEXT:    vpshufb %ymm3, %ymm0, %ymm0
458 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
459 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
460 ; AVX2-NEXT:    vzeroupper
461 ; AVX2-NEXT:    retq
462 ;
463 ; AVX512BW-LABEL: var_rotate_v8i16:
464 ; AVX512BW:       # %bb.0:
465 ; AVX512BW-NEXT:    # kill: def %xmm1 killed %xmm1 def %zmm1
466 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
467 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm2 = [16,16,16,16,16,16,16,16]
468 ; AVX512BW-NEXT:    vpsubw %xmm1, %xmm2, %xmm2
469 ; AVX512BW-NEXT:    vpsllvw %zmm1, %zmm0, %zmm1
470 ; AVX512BW-NEXT:    vpsrlvw %zmm2, %zmm0, %zmm0
471 ; AVX512BW-NEXT:    vpor %xmm0, %xmm1, %xmm0
472 ; AVX512BW-NEXT:    vzeroupper
473 ; AVX512BW-NEXT:    retq
474 ;
475 ; AVX512VL-LABEL: var_rotate_v8i16:
476 ; AVX512VL:       # %bb.0:
477 ; AVX512VL-NEXT:    vmovdqa {{.*#+}} xmm2 = [16,16,16,16,16,16,16,16]
478 ; AVX512VL-NEXT:    vpsubw %xmm1, %xmm2, %xmm2
479 ; AVX512VL-NEXT:    vpsllvw %xmm1, %xmm0, %xmm1
480 ; AVX512VL-NEXT:    vpsrlvw %xmm2, %xmm0, %xmm0
481 ; AVX512VL-NEXT:    vpor %xmm0, %xmm1, %xmm0
482 ; AVX512VL-NEXT:    retq
483 ;
484 ; XOP-LABEL: var_rotate_v8i16:
485 ; XOP:       # %bb.0:
486 ; XOP-NEXT:    vprotw %xmm1, %xmm0, %xmm0
487 ; XOP-NEXT:    retq
488 ;
489 ; X32-SSE-LABEL: var_rotate_v8i16:
490 ; X32-SSE:       # %bb.0:
491 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm3 = [16,16,16,16,16,16,16,16]
492 ; X32-SSE-NEXT:    psubw %xmm1, %xmm3
493 ; X32-SSE-NEXT:    psllw $12, %xmm1
494 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm2
495 ; X32-SSE-NEXT:    psraw $15, %xmm2
496 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm4
497 ; X32-SSE-NEXT:    psllw $8, %xmm4
498 ; X32-SSE-NEXT:    pand %xmm2, %xmm4
499 ; X32-SSE-NEXT:    pandn %xmm0, %xmm2
500 ; X32-SSE-NEXT:    por %xmm4, %xmm2
501 ; X32-SSE-NEXT:    paddw %xmm1, %xmm1
502 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm4
503 ; X32-SSE-NEXT:    psraw $15, %xmm4
504 ; X32-SSE-NEXT:    movdqa %xmm4, %xmm5
505 ; X32-SSE-NEXT:    pandn %xmm2, %xmm5
506 ; X32-SSE-NEXT:    psllw $4, %xmm2
507 ; X32-SSE-NEXT:    pand %xmm4, %xmm2
508 ; X32-SSE-NEXT:    por %xmm5, %xmm2
509 ; X32-SSE-NEXT:    paddw %xmm1, %xmm1
510 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm4
511 ; X32-SSE-NEXT:    psraw $15, %xmm4
512 ; X32-SSE-NEXT:    movdqa %xmm4, %xmm5
513 ; X32-SSE-NEXT:    pandn %xmm2, %xmm5
514 ; X32-SSE-NEXT:    psllw $2, %xmm2
515 ; X32-SSE-NEXT:    pand %xmm4, %xmm2
516 ; X32-SSE-NEXT:    por %xmm5, %xmm2
517 ; X32-SSE-NEXT:    paddw %xmm1, %xmm1
518 ; X32-SSE-NEXT:    psraw $15, %xmm1
519 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm4
520 ; X32-SSE-NEXT:    pandn %xmm2, %xmm4
521 ; X32-SSE-NEXT:    psllw $1, %xmm2
522 ; X32-SSE-NEXT:    pand %xmm1, %xmm2
523 ; X32-SSE-NEXT:    psllw $12, %xmm3
524 ; X32-SSE-NEXT:    movdqa %xmm3, %xmm1
525 ; X32-SSE-NEXT:    psraw $15, %xmm1
526 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm5
527 ; X32-SSE-NEXT:    pandn %xmm0, %xmm5
528 ; X32-SSE-NEXT:    psrlw $8, %xmm0
529 ; X32-SSE-NEXT:    pand %xmm1, %xmm0
530 ; X32-SSE-NEXT:    por %xmm5, %xmm0
531 ; X32-SSE-NEXT:    paddw %xmm3, %xmm3
532 ; X32-SSE-NEXT:    movdqa %xmm3, %xmm1
533 ; X32-SSE-NEXT:    psraw $15, %xmm1
534 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm5
535 ; X32-SSE-NEXT:    pandn %xmm0, %xmm5
536 ; X32-SSE-NEXT:    psrlw $4, %xmm0
537 ; X32-SSE-NEXT:    pand %xmm1, %xmm0
538 ; X32-SSE-NEXT:    por %xmm5, %xmm0
539 ; X32-SSE-NEXT:    paddw %xmm3, %xmm3
540 ; X32-SSE-NEXT:    movdqa %xmm3, %xmm1
541 ; X32-SSE-NEXT:    psraw $15, %xmm1
542 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm5
543 ; X32-SSE-NEXT:    pandn %xmm0, %xmm5
544 ; X32-SSE-NEXT:    psrlw $2, %xmm0
545 ; X32-SSE-NEXT:    pand %xmm1, %xmm0
546 ; X32-SSE-NEXT:    por %xmm5, %xmm0
547 ; X32-SSE-NEXT:    paddw %xmm3, %xmm3
548 ; X32-SSE-NEXT:    psraw $15, %xmm3
549 ; X32-SSE-NEXT:    movdqa %xmm3, %xmm1
550 ; X32-SSE-NEXT:    pandn %xmm0, %xmm1
551 ; X32-SSE-NEXT:    psrlw $1, %xmm0
552 ; X32-SSE-NEXT:    pand %xmm3, %xmm0
553 ; X32-SSE-NEXT:    por %xmm1, %xmm0
554 ; X32-SSE-NEXT:    por %xmm4, %xmm0
555 ; X32-SSE-NEXT:    por %xmm2, %xmm0
556 ; X32-SSE-NEXT:    retl
557   %b16 = sub <8 x i16> <i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16, i16 16>, %b
558   %shl = shl <8 x i16> %a, %b
559   %lshr = lshr <8 x i16> %a, %b16
560   %or = or <8 x i16> %shl, %lshr
561   ret <8 x i16> %or
562 }
563
564 define <16 x i8> @var_rotate_v16i8(<16 x i8> %a, <16 x i8> %b) nounwind {
565 ; SSE2-LABEL: var_rotate_v16i8:
566 ; SSE2:       # %bb.0:
567 ; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
568 ; SSE2-NEXT:    psubb %xmm1, %xmm4
569 ; SSE2-NEXT:    psllw $5, %xmm1
570 ; SSE2-NEXT:    pxor %xmm3, %xmm3
571 ; SSE2-NEXT:    pxor %xmm2, %xmm2
572 ; SSE2-NEXT:    pcmpgtb %xmm1, %xmm2
573 ; SSE2-NEXT:    movdqa %xmm0, %xmm5
574 ; SSE2-NEXT:    psllw $4, %xmm5
575 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm5
576 ; SSE2-NEXT:    pand %xmm2, %xmm5
577 ; SSE2-NEXT:    pandn %xmm0, %xmm2
578 ; SSE2-NEXT:    por %xmm5, %xmm2
579 ; SSE2-NEXT:    paddb %xmm1, %xmm1
580 ; SSE2-NEXT:    pxor %xmm5, %xmm5
581 ; SSE2-NEXT:    pcmpgtb %xmm1, %xmm5
582 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
583 ; SSE2-NEXT:    pandn %xmm2, %xmm6
584 ; SSE2-NEXT:    psllw $2, %xmm2
585 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm2
586 ; SSE2-NEXT:    pand %xmm5, %xmm2
587 ; SSE2-NEXT:    por %xmm6, %xmm2
588 ; SSE2-NEXT:    paddb %xmm1, %xmm1
589 ; SSE2-NEXT:    pxor %xmm5, %xmm5
590 ; SSE2-NEXT:    pcmpgtb %xmm1, %xmm5
591 ; SSE2-NEXT:    movdqa %xmm5, %xmm1
592 ; SSE2-NEXT:    pandn %xmm2, %xmm1
593 ; SSE2-NEXT:    paddb %xmm2, %xmm2
594 ; SSE2-NEXT:    pand %xmm5, %xmm2
595 ; SSE2-NEXT:    psllw $5, %xmm4
596 ; SSE2-NEXT:    pxor %xmm5, %xmm5
597 ; SSE2-NEXT:    pcmpgtb %xmm4, %xmm5
598 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
599 ; SSE2-NEXT:    pandn %xmm0, %xmm6
600 ; SSE2-NEXT:    psrlw $4, %xmm0
601 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
602 ; SSE2-NEXT:    pand %xmm5, %xmm0
603 ; SSE2-NEXT:    por %xmm6, %xmm0
604 ; SSE2-NEXT:    paddb %xmm4, %xmm4
605 ; SSE2-NEXT:    pxor %xmm5, %xmm5
606 ; SSE2-NEXT:    pcmpgtb %xmm4, %xmm5
607 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
608 ; SSE2-NEXT:    pandn %xmm0, %xmm6
609 ; SSE2-NEXT:    psrlw $2, %xmm0
610 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
611 ; SSE2-NEXT:    pand %xmm5, %xmm0
612 ; SSE2-NEXT:    por %xmm6, %xmm0
613 ; SSE2-NEXT:    paddb %xmm4, %xmm4
614 ; SSE2-NEXT:    pcmpgtb %xmm4, %xmm3
615 ; SSE2-NEXT:    movdqa %xmm3, %xmm4
616 ; SSE2-NEXT:    pandn %xmm0, %xmm4
617 ; SSE2-NEXT:    psrlw $1, %xmm0
618 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
619 ; SSE2-NEXT:    pand %xmm3, %xmm0
620 ; SSE2-NEXT:    por %xmm4, %xmm0
621 ; SSE2-NEXT:    por %xmm1, %xmm0
622 ; SSE2-NEXT:    por %xmm2, %xmm0
623 ; SSE2-NEXT:    retq
624 ;
625 ; SSE41-LABEL: var_rotate_v16i8:
626 ; SSE41:       # %bb.0:
627 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
628 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
629 ; SSE41-NEXT:    movdqa {{.*#+}} xmm2 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
630 ; SSE41-NEXT:    psubb %xmm3, %xmm2
631 ; SSE41-NEXT:    psllw $5, %xmm3
632 ; SSE41-NEXT:    movdqa %xmm1, %xmm5
633 ; SSE41-NEXT:    psllw $4, %xmm5
634 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm5
635 ; SSE41-NEXT:    movdqa %xmm1, %xmm4
636 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
637 ; SSE41-NEXT:    pblendvb %xmm0, %xmm5, %xmm4
638 ; SSE41-NEXT:    movdqa %xmm4, %xmm5
639 ; SSE41-NEXT:    psllw $2, %xmm5
640 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm5
641 ; SSE41-NEXT:    paddb %xmm3, %xmm3
642 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
643 ; SSE41-NEXT:    pblendvb %xmm0, %xmm5, %xmm4
644 ; SSE41-NEXT:    movdqa %xmm4, %xmm5
645 ; SSE41-NEXT:    paddb %xmm5, %xmm5
646 ; SSE41-NEXT:    paddb %xmm3, %xmm3
647 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
648 ; SSE41-NEXT:    pblendvb %xmm0, %xmm5, %xmm4
649 ; SSE41-NEXT:    psllw $5, %xmm2
650 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
651 ; SSE41-NEXT:    paddb %xmm3, %xmm3
652 ; SSE41-NEXT:    movdqa %xmm1, %xmm5
653 ; SSE41-NEXT:    psrlw $4, %xmm5
654 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm5
655 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
656 ; SSE41-NEXT:    pblendvb %xmm0, %xmm5, %xmm1
657 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
658 ; SSE41-NEXT:    psrlw $2, %xmm2
659 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm2
660 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
661 ; SSE41-NEXT:    pblendvb %xmm0, %xmm2, %xmm1
662 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
663 ; SSE41-NEXT:    psrlw $1, %xmm2
664 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm2
665 ; SSE41-NEXT:    paddb %xmm3, %xmm3
666 ; SSE41-NEXT:    movdqa %xmm3, %xmm0
667 ; SSE41-NEXT:    pblendvb %xmm0, %xmm2, %xmm1
668 ; SSE41-NEXT:    por %xmm4, %xmm1
669 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
670 ; SSE41-NEXT:    retq
671 ;
672 ; AVX-LABEL: var_rotate_v16i8:
673 ; AVX:       # %bb.0:
674 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
675 ; AVX-NEXT:    vpsubb %xmm1, %xmm2, %xmm2
676 ; AVX-NEXT:    vpsllw $5, %xmm1, %xmm1
677 ; AVX-NEXT:    vpsllw $4, %xmm0, %xmm3
678 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm3, %xmm3
679 ; AVX-NEXT:    vpblendvb %xmm1, %xmm3, %xmm0, %xmm3
680 ; AVX-NEXT:    vpsllw $2, %xmm3, %xmm4
681 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm4, %xmm4
682 ; AVX-NEXT:    vpaddb %xmm1, %xmm1, %xmm1
683 ; AVX-NEXT:    vpblendvb %xmm1, %xmm4, %xmm3, %xmm3
684 ; AVX-NEXT:    vpaddb %xmm3, %xmm3, %xmm4
685 ; AVX-NEXT:    vpaddb %xmm1, %xmm1, %xmm1
686 ; AVX-NEXT:    vpblendvb %xmm1, %xmm4, %xmm3, %xmm1
687 ; AVX-NEXT:    vpsllw $5, %xmm2, %xmm2
688 ; AVX-NEXT:    vpaddb %xmm2, %xmm2, %xmm3
689 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm4
690 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm4, %xmm4
691 ; AVX-NEXT:    vpblendvb %xmm2, %xmm4, %xmm0, %xmm0
692 ; AVX-NEXT:    vpsrlw $2, %xmm0, %xmm2
693 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm2, %xmm2
694 ; AVX-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
695 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm2
696 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm2, %xmm2
697 ; AVX-NEXT:    vpaddb %xmm3, %xmm3, %xmm3
698 ; AVX-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
699 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
700 ; AVX-NEXT:    retq
701 ;
702 ; AVX512BW-LABEL: var_rotate_v16i8:
703 ; AVX512BW:       # %bb.0:
704 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm2 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
705 ; AVX512BW-NEXT:    vpsubb %xmm1, %xmm2, %xmm2
706 ; AVX512BW-NEXT:    vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero
707 ; AVX512BW-NEXT:    vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero
708 ; AVX512BW-NEXT:    vpsllvw %zmm1, %zmm0, %zmm1
709 ; AVX512BW-NEXT:    vpmovwb %zmm1, %ymm1
710 ; AVX512BW-NEXT:    vpmovzxbw {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero,xmm2[8],zero,xmm2[9],zero,xmm2[10],zero,xmm2[11],zero,xmm2[12],zero,xmm2[13],zero,xmm2[14],zero,xmm2[15],zero
711 ; AVX512BW-NEXT:    vpsrlvw %zmm2, %zmm0, %zmm0
712 ; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
713 ; AVX512BW-NEXT:    vpor %xmm0, %xmm1, %xmm0
714 ; AVX512BW-NEXT:    vzeroupper
715 ; AVX512BW-NEXT:    retq
716 ;
717 ; AVX512VL-LABEL: var_rotate_v16i8:
718 ; AVX512VL:       # %bb.0:
719 ; AVX512VL-NEXT:    vmovdqa {{.*#+}} xmm2 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
720 ; AVX512VL-NEXT:    vpsubb %xmm1, %xmm2, %xmm2
721 ; AVX512VL-NEXT:    vpmovzxbw {{.*#+}} ymm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero,xmm1[8],zero,xmm1[9],zero,xmm1[10],zero,xmm1[11],zero,xmm1[12],zero,xmm1[13],zero,xmm1[14],zero,xmm1[15],zero
722 ; AVX512VL-NEXT:    vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero
723 ; AVX512VL-NEXT:    vpsllvw %ymm1, %ymm0, %ymm1
724 ; AVX512VL-NEXT:    vpmovwb %ymm1, %xmm1
725 ; AVX512VL-NEXT:    vpmovzxbw {{.*#+}} ymm2 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero,xmm2[8],zero,xmm2[9],zero,xmm2[10],zero,xmm2[11],zero,xmm2[12],zero,xmm2[13],zero,xmm2[14],zero,xmm2[15],zero
726 ; AVX512VL-NEXT:    vpsrlvw %ymm2, %ymm0, %ymm0
727 ; AVX512VL-NEXT:    vpmovwb %ymm0, %xmm0
728 ; AVX512VL-NEXT:    vpor %xmm0, %xmm1, %xmm0
729 ; AVX512VL-NEXT:    vzeroupper
730 ; AVX512VL-NEXT:    retq
731 ;
732 ; XOP-LABEL: var_rotate_v16i8:
733 ; XOP:       # %bb.0:
734 ; XOP-NEXT:    vprotb %xmm1, %xmm0, %xmm0
735 ; XOP-NEXT:    retq
736 ;
737 ; X32-SSE-LABEL: var_rotate_v16i8:
738 ; X32-SSE:       # %bb.0:
739 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm4 = [8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8]
740 ; X32-SSE-NEXT:    psubb %xmm1, %xmm4
741 ; X32-SSE-NEXT:    psllw $5, %xmm1
742 ; X32-SSE-NEXT:    pxor %xmm3, %xmm3
743 ; X32-SSE-NEXT:    pxor %xmm2, %xmm2
744 ; X32-SSE-NEXT:    pcmpgtb %xmm1, %xmm2
745 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm5
746 ; X32-SSE-NEXT:    psllw $4, %xmm5
747 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm5
748 ; X32-SSE-NEXT:    pand %xmm2, %xmm5
749 ; X32-SSE-NEXT:    pandn %xmm0, %xmm2
750 ; X32-SSE-NEXT:    por %xmm5, %xmm2
751 ; X32-SSE-NEXT:    paddb %xmm1, %xmm1
752 ; X32-SSE-NEXT:    pxor %xmm5, %xmm5
753 ; X32-SSE-NEXT:    pcmpgtb %xmm1, %xmm5
754 ; X32-SSE-NEXT:    movdqa %xmm5, %xmm6
755 ; X32-SSE-NEXT:    pandn %xmm2, %xmm6
756 ; X32-SSE-NEXT:    psllw $2, %xmm2
757 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm2
758 ; X32-SSE-NEXT:    pand %xmm5, %xmm2
759 ; X32-SSE-NEXT:    por %xmm6, %xmm2
760 ; X32-SSE-NEXT:    paddb %xmm1, %xmm1
761 ; X32-SSE-NEXT:    pxor %xmm5, %xmm5
762 ; X32-SSE-NEXT:    pcmpgtb %xmm1, %xmm5
763 ; X32-SSE-NEXT:    movdqa %xmm5, %xmm1
764 ; X32-SSE-NEXT:    pandn %xmm2, %xmm1
765 ; X32-SSE-NEXT:    paddb %xmm2, %xmm2
766 ; X32-SSE-NEXT:    pand %xmm5, %xmm2
767 ; X32-SSE-NEXT:    psllw $5, %xmm4
768 ; X32-SSE-NEXT:    pxor %xmm5, %xmm5
769 ; X32-SSE-NEXT:    pcmpgtb %xmm4, %xmm5
770 ; X32-SSE-NEXT:    movdqa %xmm5, %xmm6
771 ; X32-SSE-NEXT:    pandn %xmm0, %xmm6
772 ; X32-SSE-NEXT:    psrlw $4, %xmm0
773 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
774 ; X32-SSE-NEXT:    pand %xmm5, %xmm0
775 ; X32-SSE-NEXT:    por %xmm6, %xmm0
776 ; X32-SSE-NEXT:    paddb %xmm4, %xmm4
777 ; X32-SSE-NEXT:    pxor %xmm5, %xmm5
778 ; X32-SSE-NEXT:    pcmpgtb %xmm4, %xmm5
779 ; X32-SSE-NEXT:    movdqa %xmm5, %xmm6
780 ; X32-SSE-NEXT:    pandn %xmm0, %xmm6
781 ; X32-SSE-NEXT:    psrlw $2, %xmm0
782 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
783 ; X32-SSE-NEXT:    pand %xmm5, %xmm0
784 ; X32-SSE-NEXT:    por %xmm6, %xmm0
785 ; X32-SSE-NEXT:    paddb %xmm4, %xmm4
786 ; X32-SSE-NEXT:    pcmpgtb %xmm4, %xmm3
787 ; X32-SSE-NEXT:    movdqa %xmm3, %xmm4
788 ; X32-SSE-NEXT:    pandn %xmm0, %xmm4
789 ; X32-SSE-NEXT:    psrlw $1, %xmm0
790 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
791 ; X32-SSE-NEXT:    pand %xmm3, %xmm0
792 ; X32-SSE-NEXT:    por %xmm4, %xmm0
793 ; X32-SSE-NEXT:    por %xmm1, %xmm0
794 ; X32-SSE-NEXT:    por %xmm2, %xmm0
795 ; X32-SSE-NEXT:    retl
796   %b8 = sub <16 x i8> <i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8, i8 8>, %b
797   %shl = shl <16 x i8> %a, %b
798   %lshr = lshr <16 x i8> %a, %b8
799   %or = or <16 x i8> %shl, %lshr
800   ret <16 x i8> %or
801 }
802
803 ;
804 ; Constant Rotates
805 ;
806
807 define <2 x i64> @constant_rotate_v2i64(<2 x i64> %a) nounwind {
808 ; SSE2-LABEL: constant_rotate_v2i64:
809 ; SSE2:       # %bb.0:
810 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
811 ; SSE2-NEXT:    psllq $4, %xmm1
812 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
813 ; SSE2-NEXT:    psllq $14, %xmm2
814 ; SSE2-NEXT:    movsd {{.*#+}} xmm2 = xmm1[0],xmm2[1]
815 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
816 ; SSE2-NEXT:    psrlq $60, %xmm1
817 ; SSE2-NEXT:    psrlq $50, %xmm0
818 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
819 ; SSE2-NEXT:    orpd %xmm2, %xmm0
820 ; SSE2-NEXT:    retq
821 ;
822 ; SSE41-LABEL: constant_rotate_v2i64:
823 ; SSE41:       # %bb.0:
824 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
825 ; SSE41-NEXT:    psllq $14, %xmm1
826 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
827 ; SSE41-NEXT:    psllq $4, %xmm2
828 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm2[0,1,2,3],xmm1[4,5,6,7]
829 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
830 ; SSE41-NEXT:    psrlq $50, %xmm1
831 ; SSE41-NEXT:    psrlq $60, %xmm0
832 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm1[4,5,6,7]
833 ; SSE41-NEXT:    por %xmm2, %xmm0
834 ; SSE41-NEXT:    retq
835 ;
836 ; AVX1-LABEL: constant_rotate_v2i64:
837 ; AVX1:       # %bb.0:
838 ; AVX1-NEXT:    vpsllq $14, %xmm0, %xmm1
839 ; AVX1-NEXT:    vpsllq $4, %xmm0, %xmm2
840 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm1 = xmm2[0,1,2,3],xmm1[4,5,6,7]
841 ; AVX1-NEXT:    vpsrlq $50, %xmm0, %xmm2
842 ; AVX1-NEXT:    vpsrlq $60, %xmm0, %xmm0
843 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm2[4,5,6,7]
844 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
845 ; AVX1-NEXT:    retq
846 ;
847 ; AVX2-LABEL: constant_rotate_v2i64:
848 ; AVX2:       # %bb.0:
849 ; AVX2-NEXT:    vpsllvq {{.*}}(%rip), %xmm0, %xmm1
850 ; AVX2-NEXT:    vpsrlvq {{.*}}(%rip), %xmm0, %xmm0
851 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
852 ; AVX2-NEXT:    retq
853 ;
854 ; AVX512BW-LABEL: constant_rotate_v2i64:
855 ; AVX512BW:       # %bb.0:
856 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
857 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm1 = [4,14]
858 ; AVX512BW-NEXT:    vprolvq %zmm1, %zmm0, %zmm0
859 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 killed %zmm0
860 ; AVX512BW-NEXT:    vzeroupper
861 ; AVX512BW-NEXT:    retq
862 ;
863 ; AVX512VL-LABEL: constant_rotate_v2i64:
864 ; AVX512VL:       # %bb.0:
865 ; AVX512VL-NEXT:    vprolvq {{.*}}(%rip), %xmm0, %xmm0
866 ; AVX512VL-NEXT:    retq
867 ;
868 ; XOP-LABEL: constant_rotate_v2i64:
869 ; XOP:       # %bb.0:
870 ; XOP-NEXT:    vprotq {{.*}}(%rip), %xmm0, %xmm0
871 ; XOP-NEXT:    retq
872 ;
873 ; X32-SSE-LABEL: constant_rotate_v2i64:
874 ; X32-SSE:       # %bb.0:
875 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
876 ; X32-SSE-NEXT:    psllq $4, %xmm1
877 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm2
878 ; X32-SSE-NEXT:    psllq $14, %xmm2
879 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm2 = xmm1[0],xmm2[1]
880 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
881 ; X32-SSE-NEXT:    psrlq $60, %xmm1
882 ; X32-SSE-NEXT:    psrlq $50, %xmm0
883 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm1[0],xmm0[1]
884 ; X32-SSE-NEXT:    orpd %xmm2, %xmm0
885 ; X32-SSE-NEXT:    retl
886   %shl = shl <2 x i64> %a, <i64 4, i64 14>
887   %lshr = lshr <2 x i64> %a, <i64 60, i64 50>
888   %or = or <2 x i64> %shl, %lshr
889   ret <2 x i64> %or
890 }
891
892 define <4 x i32> @constant_rotate_v4i32(<4 x i32> %a) nounwind {
893 ; SSE2-LABEL: constant_rotate_v4i32:
894 ; SSE2:       # %bb.0:
895 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [16,32,64,128]
896 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
897 ; SSE2-NEXT:    pmuludq %xmm1, %xmm2
898 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
899 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
900 ; SSE2-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
901 ; SSE2-NEXT:    pmuludq %xmm1, %xmm3
902 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[0,2,2,3]
903 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
904 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
905 ; SSE2-NEXT:    psrld $27, %xmm1
906 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
907 ; SSE2-NEXT:    psrld $25, %xmm3
908 ; SSE2-NEXT:    movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
909 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[1,3,2,3]
910 ; SSE2-NEXT:    movdqa %xmm0, %xmm3
911 ; SSE2-NEXT:    psrld $28, %xmm3
912 ; SSE2-NEXT:    psrld $26, %xmm0
913 ; SSE2-NEXT:    movsd {{.*#+}} xmm0 = xmm3[0],xmm0[1]
914 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
915 ; SSE2-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
916 ; SSE2-NEXT:    por %xmm2, %xmm0
917 ; SSE2-NEXT:    retq
918 ;
919 ; SSE41-LABEL: constant_rotate_v4i32:
920 ; SSE41:       # %bb.0:
921 ; SSE41-NEXT:    movdqa {{.*#+}} xmm1 = [16,32,64,128]
922 ; SSE41-NEXT:    pmulld %xmm0, %xmm1
923 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
924 ; SSE41-NEXT:    psrld $25, %xmm2
925 ; SSE41-NEXT:    movdqa %xmm0, %xmm3
926 ; SSE41-NEXT:    psrld $27, %xmm3
927 ; SSE41-NEXT:    pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]
928 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
929 ; SSE41-NEXT:    psrld $26, %xmm2
930 ; SSE41-NEXT:    psrld $28, %xmm0
931 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm2[4,5,6,7]
932 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm0[0,1],xmm3[2,3],xmm0[4,5],xmm3[6,7]
933 ; SSE41-NEXT:    por %xmm1, %xmm0
934 ; SSE41-NEXT:    retq
935 ;
936 ; AVX1-LABEL: constant_rotate_v4i32:
937 ; AVX1:       # %bb.0:
938 ; AVX1-NEXT:    vpmulld {{.*}}(%rip), %xmm0, %xmm1
939 ; AVX1-NEXT:    vpsrld $25, %xmm0, %xmm2
940 ; AVX1-NEXT:    vpsrld $27, %xmm0, %xmm3
941 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]
942 ; AVX1-NEXT:    vpsrld $26, %xmm0, %xmm3
943 ; AVX1-NEXT:    vpsrld $28, %xmm0, %xmm0
944 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1,2,3],xmm3[4,5,6,7]
945 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0,1],xmm2[2,3],xmm0[4,5],xmm2[6,7]
946 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
947 ; AVX1-NEXT:    retq
948 ;
949 ; AVX2-LABEL: constant_rotate_v4i32:
950 ; AVX2:       # %bb.0:
951 ; AVX2-NEXT:    vpsllvd {{.*}}(%rip), %xmm0, %xmm1
952 ; AVX2-NEXT:    vpsrlvd {{.*}}(%rip), %xmm0, %xmm0
953 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
954 ; AVX2-NEXT:    retq
955 ;
956 ; AVX512BW-LABEL: constant_rotate_v4i32:
957 ; AVX512BW:       # %bb.0:
958 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
959 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm1 = [4,5,6,7]
960 ; AVX512BW-NEXT:    vprolvd %zmm1, %zmm0, %zmm0
961 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 killed %zmm0
962 ; AVX512BW-NEXT:    vzeroupper
963 ; AVX512BW-NEXT:    retq
964 ;
965 ; AVX512VL-LABEL: constant_rotate_v4i32:
966 ; AVX512VL:       # %bb.0:
967 ; AVX512VL-NEXT:    vprolvd {{.*}}(%rip), %xmm0, %xmm0
968 ; AVX512VL-NEXT:    retq
969 ;
970 ; XOP-LABEL: constant_rotate_v4i32:
971 ; XOP:       # %bb.0:
972 ; XOP-NEXT:    vprotd {{.*}}(%rip), %xmm0, %xmm0
973 ; XOP-NEXT:    retq
974 ;
975 ; X32-SSE-LABEL: constant_rotate_v4i32:
976 ; X32-SSE:       # %bb.0:
977 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm1 = [16,32,64,128]
978 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm2
979 ; X32-SSE-NEXT:    pmuludq %xmm1, %xmm2
980 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3]
981 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
982 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm3 = xmm0[1,1,3,3]
983 ; X32-SSE-NEXT:    pmuludq %xmm1, %xmm3
984 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[0,2,2,3]
985 ; X32-SSE-NEXT:    punpckldq {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
986 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
987 ; X32-SSE-NEXT:    psrld $27, %xmm1
988 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm3
989 ; X32-SSE-NEXT:    psrld $25, %xmm3
990 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm3 = xmm1[0],xmm3[1]
991 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm1 = xmm3[1,3,2,3]
992 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm3
993 ; X32-SSE-NEXT:    psrld $28, %xmm3
994 ; X32-SSE-NEXT:    psrld $26, %xmm0
995 ; X32-SSE-NEXT:    movsd {{.*#+}} xmm0 = xmm3[0],xmm0[1]
996 ; X32-SSE-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3]
997 ; X32-SSE-NEXT:    punpckldq {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
998 ; X32-SSE-NEXT:    por %xmm2, %xmm0
999 ; X32-SSE-NEXT:    retl
1000   %shl = shl <4 x i32> %a, <i32 4, i32 5, i32 6, i32 7>
1001   %lshr = lshr <4 x i32> %a, <i32 28, i32 27, i32 26, i32 25>
1002   %or = or <4 x i32> %shl, %lshr
1003   ret <4 x i32> %or
1004 }
1005
1006 define <8 x i16> @constant_rotate_v8i16(<8 x i16> %a) nounwind {
1007 ; SSE2-LABEL: constant_rotate_v8i16:
1008 ; SSE2:       # %bb.0:
1009 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [1,2,4,8,16,32,64,128]
1010 ; SSE2-NEXT:    pmullw %xmm0, %xmm2
1011 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [0,65535,65535,65535,65535,65535,65535,65535]
1012 ; SSE2-NEXT:    movdqa %xmm1, %xmm3
1013 ; SSE2-NEXT:    pandn %xmm0, %xmm3
1014 ; SSE2-NEXT:    psrlw $8, %xmm0
1015 ; SSE2-NEXT:    pand %xmm1, %xmm0
1016 ; SSE2-NEXT:    por %xmm3, %xmm0
1017 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [0,65535,65535,65535,65535,0,0,0]
1018 ; SSE2-NEXT:    movdqa %xmm1, %xmm3
1019 ; SSE2-NEXT:    pandn %xmm0, %xmm3
1020 ; SSE2-NEXT:    psrlw $4, %xmm0
1021 ; SSE2-NEXT:    pand %xmm1, %xmm0
1022 ; SSE2-NEXT:    por %xmm3, %xmm0
1023 ; SSE2-NEXT:    movdqa {{.*#+}} xmm1 = [0,65535,65535,0,0,65535,65535,0]
1024 ; SSE2-NEXT:    movdqa %xmm1, %xmm3
1025 ; SSE2-NEXT:    pandn %xmm0, %xmm3
1026 ; SSE2-NEXT:    psrlw $2, %xmm0
1027 ; SSE2-NEXT:    pand %xmm1, %xmm0
1028 ; SSE2-NEXT:    por %xmm3, %xmm0
1029 ; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [65535,0,65535,0,65535,0,65535,0]
1030 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
1031 ; SSE2-NEXT:    pand %xmm3, %xmm1
1032 ; SSE2-NEXT:    psrlw $1, %xmm0
1033 ; SSE2-NEXT:    pandn %xmm0, %xmm3
1034 ; SSE2-NEXT:    por %xmm2, %xmm3
1035 ; SSE2-NEXT:    por %xmm3, %xmm1
1036 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
1037 ; SSE2-NEXT:    retq
1038 ;
1039 ; SSE41-LABEL: constant_rotate_v8i16:
1040 ; SSE41:       # %bb.0:
1041 ; SSE41-NEXT:    movdqa {{.*#+}} xmm1 = [1,2,4,8,16,32,64,128]
1042 ; SSE41-NEXT:    pmullw %xmm0, %xmm1
1043 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
1044 ; SSE41-NEXT:    psrlw $8, %xmm2
1045 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm0[0],xmm2[1,2,3,4,5,6,7]
1046 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
1047 ; SSE41-NEXT:    psrlw $4, %xmm0
1048 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0],xmm0[1,2,3,4],xmm2[5,6,7]
1049 ; SSE41-NEXT:    movdqa %xmm0, %xmm2
1050 ; SSE41-NEXT:    psrlw $2, %xmm2
1051 ; SSE41-NEXT:    pblendw {{.*#+}} xmm2 = xmm0[0],xmm2[1,2],xmm0[3,4],xmm2[5,6],xmm0[7]
1052 ; SSE41-NEXT:    movdqa %xmm2, %xmm0
1053 ; SSE41-NEXT:    psrlw $1, %xmm0
1054 ; SSE41-NEXT:    pblendw {{.*#+}} xmm0 = xmm2[0],xmm0[1],xmm2[2],xmm0[3],xmm2[4],xmm0[5],xmm2[6],xmm0[7]
1055 ; SSE41-NEXT:    por %xmm1, %xmm0
1056 ; SSE41-NEXT:    retq
1057 ;
1058 ; AVX1-LABEL: constant_rotate_v8i16:
1059 ; AVX1:       # %bb.0:
1060 ; AVX1-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm1
1061 ; AVX1-NEXT:    vpsrlw $8, %xmm0, %xmm2
1062 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3,4,5,6,7]
1063 ; AVX1-NEXT:    vpsrlw $4, %xmm0, %xmm2
1064 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1,2,3,4],xmm0[5,6,7]
1065 ; AVX1-NEXT:    vpsrlw $2, %xmm0, %xmm2
1066 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1,2],xmm0[3,4],xmm2[5,6],xmm0[7]
1067 ; AVX1-NEXT:    vpsrlw $1, %xmm0, %xmm2
1068 ; AVX1-NEXT:    vpblendw {{.*#+}} xmm0 = xmm0[0],xmm2[1],xmm0[2],xmm2[3],xmm0[4],xmm2[5],xmm0[6],xmm2[7]
1069 ; AVX1-NEXT:    vpor %xmm0, %xmm1, %xmm0
1070 ; AVX1-NEXT:    retq
1071 ;
1072 ; AVX2-LABEL: constant_rotate_v8i16:
1073 ; AVX2:       # %bb.0:
1074 ; AVX2-NEXT:    vpmullw {{.*}}(%rip), %xmm0, %xmm1
1075 ; AVX2-NEXT:    vpmovzxwd {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
1076 ; AVX2-NEXT:    vpsrlvd {{.*}}(%rip), %ymm0, %ymm0
1077 ; AVX2-NEXT:    vpshufb {{.*#+}} ymm0 = ymm0[0,1,4,5,8,9,12,13,8,9,12,13,12,13,14,15,16,17,20,21,24,25,28,29,24,25,28,29,28,29,30,31]
1078 ; AVX2-NEXT:    vpermq {{.*#+}} ymm0 = ymm0[0,2,2,3]
1079 ; AVX2-NEXT:    vpor %xmm0, %xmm1, %xmm0
1080 ; AVX2-NEXT:    vzeroupper
1081 ; AVX2-NEXT:    retq
1082 ;
1083 ; AVX512BW-LABEL: constant_rotate_v8i16:
1084 ; AVX512BW:       # %bb.0:
1085 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
1086 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm1 = [0,1,2,3,4,5,6,7]
1087 ; AVX512BW-NEXT:    vpsllvw %zmm1, %zmm0, %zmm1
1088 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} xmm2 = [16,15,14,13,12,11,10,9]
1089 ; AVX512BW-NEXT:    vpsrlvw %zmm2, %zmm0, %zmm0
1090 ; AVX512BW-NEXT:    vpor %xmm0, %xmm1, %xmm0
1091 ; AVX512BW-NEXT:    vzeroupper
1092 ; AVX512BW-NEXT:    retq
1093 ;
1094 ; AVX512VL-LABEL: constant_rotate_v8i16:
1095 ; AVX512VL:       # %bb.0:
1096 ; AVX512VL-NEXT:    vpsllvw {{.*}}(%rip), %xmm0, %xmm1
1097 ; AVX512VL-NEXT:    vpsrlvw {{.*}}(%rip), %xmm0, %xmm0
1098 ; AVX512VL-NEXT:    vpor %xmm0, %xmm1, %xmm0
1099 ; AVX512VL-NEXT:    retq
1100 ;
1101 ; XOP-LABEL: constant_rotate_v8i16:
1102 ; XOP:       # %bb.0:
1103 ; XOP-NEXT:    vprotw {{.*}}(%rip), %xmm0, %xmm0
1104 ; XOP-NEXT:    retq
1105 ;
1106 ; X32-SSE-LABEL: constant_rotate_v8i16:
1107 ; X32-SSE:       # %bb.0:
1108 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm2 = [1,2,4,8,16,32,64,128]
1109 ; X32-SSE-NEXT:    pmullw %xmm0, %xmm2
1110 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm1 = [0,65535,65535,65535,65535,65535,65535,65535]
1111 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm3
1112 ; X32-SSE-NEXT:    pandn %xmm0, %xmm3
1113 ; X32-SSE-NEXT:    psrlw $8, %xmm0
1114 ; X32-SSE-NEXT:    pand %xmm1, %xmm0
1115 ; X32-SSE-NEXT:    por %xmm3, %xmm0
1116 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm1 = [0,65535,65535,65535,65535,0,0,0]
1117 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm3
1118 ; X32-SSE-NEXT:    pandn %xmm0, %xmm3
1119 ; X32-SSE-NEXT:    psrlw $4, %xmm0
1120 ; X32-SSE-NEXT:    pand %xmm1, %xmm0
1121 ; X32-SSE-NEXT:    por %xmm3, %xmm0
1122 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm1 = [0,65535,65535,0,0,65535,65535,0]
1123 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm3
1124 ; X32-SSE-NEXT:    pandn %xmm0, %xmm3
1125 ; X32-SSE-NEXT:    psrlw $2, %xmm0
1126 ; X32-SSE-NEXT:    pand %xmm1, %xmm0
1127 ; X32-SSE-NEXT:    por %xmm3, %xmm0
1128 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm3 = [65535,0,65535,0,65535,0,65535,0]
1129 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1130 ; X32-SSE-NEXT:    pand %xmm3, %xmm1
1131 ; X32-SSE-NEXT:    psrlw $1, %xmm0
1132 ; X32-SSE-NEXT:    pandn %xmm0, %xmm3
1133 ; X32-SSE-NEXT:    por %xmm2, %xmm3
1134 ; X32-SSE-NEXT:    por %xmm3, %xmm1
1135 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm0
1136 ; X32-SSE-NEXT:    retl
1137   %shl = shl <8 x i16> %a, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>
1138   %lshr = lshr <8 x i16> %a, <i16 16, i16 15, i16 14, i16 13, i16 12, i16 11, i16 10, i16 9>
1139   %or = or <8 x i16> %shl, %lshr
1140   ret <8 x i16> %or
1141 }
1142
1143 define <16 x i8> @constant_rotate_v16i8(<16 x i8> %a) nounwind {
1144 ; SSE2-LABEL: constant_rotate_v16i8:
1145 ; SSE2:       # %bb.0:
1146 ; SSE2-NEXT:    movdqa {{.*#+}} xmm3 = [8192,24640,41088,57536,57600,41152,24704,8256]
1147 ; SSE2-NEXT:    pxor %xmm2, %xmm2
1148 ; SSE2-NEXT:    pxor %xmm1, %xmm1
1149 ; SSE2-NEXT:    pcmpgtb %xmm3, %xmm1
1150 ; SSE2-NEXT:    movdqa %xmm0, %xmm4
1151 ; SSE2-NEXT:    psllw $4, %xmm4
1152 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm4
1153 ; SSE2-NEXT:    pand %xmm1, %xmm4
1154 ; SSE2-NEXT:    pandn %xmm0, %xmm1
1155 ; SSE2-NEXT:    por %xmm4, %xmm1
1156 ; SSE2-NEXT:    paddb %xmm3, %xmm3
1157 ; SSE2-NEXT:    pxor %xmm4, %xmm4
1158 ; SSE2-NEXT:    pcmpgtb %xmm3, %xmm4
1159 ; SSE2-NEXT:    movdqa %xmm4, %xmm5
1160 ; SSE2-NEXT:    pandn %xmm1, %xmm5
1161 ; SSE2-NEXT:    psllw $2, %xmm1
1162 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm1
1163 ; SSE2-NEXT:    pand %xmm4, %xmm1
1164 ; SSE2-NEXT:    por %xmm5, %xmm1
1165 ; SSE2-NEXT:    paddb %xmm3, %xmm3
1166 ; SSE2-NEXT:    pxor %xmm4, %xmm4
1167 ; SSE2-NEXT:    pcmpgtb %xmm3, %xmm4
1168 ; SSE2-NEXT:    movdqa %xmm4, %xmm3
1169 ; SSE2-NEXT:    pandn %xmm1, %xmm3
1170 ; SSE2-NEXT:    paddb %xmm1, %xmm1
1171 ; SSE2-NEXT:    pand %xmm4, %xmm1
1172 ; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [57600,41152,24704,8256,8192,24640,41088,57536]
1173 ; SSE2-NEXT:    pxor %xmm5, %xmm5
1174 ; SSE2-NEXT:    pcmpgtb %xmm4, %xmm5
1175 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
1176 ; SSE2-NEXT:    pandn %xmm0, %xmm6
1177 ; SSE2-NEXT:    psrlw $4, %xmm0
1178 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
1179 ; SSE2-NEXT:    pand %xmm5, %xmm0
1180 ; SSE2-NEXT:    por %xmm6, %xmm0
1181 ; SSE2-NEXT:    paddb %xmm4, %xmm4
1182 ; SSE2-NEXT:    pxor %xmm5, %xmm5
1183 ; SSE2-NEXT:    pcmpgtb %xmm4, %xmm5
1184 ; SSE2-NEXT:    movdqa %xmm5, %xmm6
1185 ; SSE2-NEXT:    pandn %xmm0, %xmm6
1186 ; SSE2-NEXT:    psrlw $2, %xmm0
1187 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
1188 ; SSE2-NEXT:    pand %xmm5, %xmm0
1189 ; SSE2-NEXT:    por %xmm6, %xmm0
1190 ; SSE2-NEXT:    paddb %xmm4, %xmm4
1191 ; SSE2-NEXT:    pcmpgtb %xmm4, %xmm2
1192 ; SSE2-NEXT:    movdqa %xmm2, %xmm4
1193 ; SSE2-NEXT:    pandn %xmm0, %xmm4
1194 ; SSE2-NEXT:    psrlw $1, %xmm0
1195 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
1196 ; SSE2-NEXT:    pand %xmm2, %xmm0
1197 ; SSE2-NEXT:    por %xmm4, %xmm0
1198 ; SSE2-NEXT:    por %xmm3, %xmm0
1199 ; SSE2-NEXT:    por %xmm1, %xmm0
1200 ; SSE2-NEXT:    retq
1201 ;
1202 ; SSE41-LABEL: constant_rotate_v16i8:
1203 ; SSE41:       # %bb.0:
1204 ; SSE41-NEXT:    movdqa %xmm0, %xmm1
1205 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
1206 ; SSE41-NEXT:    psllw $4, %xmm3
1207 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm3
1208 ; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [8192,24640,41088,57536,57600,41152,24704,8256]
1209 ; SSE41-NEXT:    movdqa %xmm1, %xmm2
1210 ; SSE41-NEXT:    pblendvb %xmm0, %xmm3, %xmm2
1211 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
1212 ; SSE41-NEXT:    psllw $2, %xmm3
1213 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm3
1214 ; SSE41-NEXT:    paddb %xmm0, %xmm0
1215 ; SSE41-NEXT:    pblendvb %xmm0, %xmm3, %xmm2
1216 ; SSE41-NEXT:    movdqa %xmm2, %xmm3
1217 ; SSE41-NEXT:    paddb %xmm3, %xmm3
1218 ; SSE41-NEXT:    paddb %xmm0, %xmm0
1219 ; SSE41-NEXT:    pblendvb %xmm0, %xmm3, %xmm2
1220 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
1221 ; SSE41-NEXT:    psrlw $4, %xmm3
1222 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm3
1223 ; SSE41-NEXT:    movdqa {{.*#+}} xmm0 = [57600,41152,24704,8256,8192,24640,41088,57536]
1224 ; SSE41-NEXT:    pblendvb %xmm0, %xmm3, %xmm1
1225 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
1226 ; SSE41-NEXT:    psrlw $2, %xmm3
1227 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm3
1228 ; SSE41-NEXT:    paddb %xmm0, %xmm0
1229 ; SSE41-NEXT:    pblendvb %xmm0, %xmm3, %xmm1
1230 ; SSE41-NEXT:    movdqa %xmm1, %xmm3
1231 ; SSE41-NEXT:    psrlw $1, %xmm3
1232 ; SSE41-NEXT:    pand {{.*}}(%rip), %xmm3
1233 ; SSE41-NEXT:    paddb %xmm0, %xmm0
1234 ; SSE41-NEXT:    pblendvb %xmm0, %xmm3, %xmm1
1235 ; SSE41-NEXT:    por %xmm2, %xmm1
1236 ; SSE41-NEXT:    movdqa %xmm1, %xmm0
1237 ; SSE41-NEXT:    retq
1238 ;
1239 ; AVX-LABEL: constant_rotate_v16i8:
1240 ; AVX:       # %bb.0:
1241 ; AVX-NEXT:    vpsllw $4, %xmm0, %xmm1
1242 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1243 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [8192,24640,41088,57536,57600,41152,24704,8256]
1244 ; AVX-NEXT:    vpblendvb %xmm2, %xmm1, %xmm0, %xmm1
1245 ; AVX-NEXT:    vpsllw $2, %xmm1, %xmm3
1246 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm3, %xmm3
1247 ; AVX-NEXT:    vpaddb %xmm2, %xmm2, %xmm2
1248 ; AVX-NEXT:    vpblendvb %xmm2, %xmm3, %xmm1, %xmm1
1249 ; AVX-NEXT:    vpaddb %xmm1, %xmm1, %xmm3
1250 ; AVX-NEXT:    vpaddb %xmm2, %xmm2, %xmm2
1251 ; AVX-NEXT:    vpblendvb %xmm2, %xmm3, %xmm1, %xmm1
1252 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm2
1253 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm2, %xmm2
1254 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm3 = [57600,41152,24704,8256,8192,24640,41088,57536]
1255 ; AVX-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
1256 ; AVX-NEXT:    vpsrlw $2, %xmm0, %xmm2
1257 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm2, %xmm2
1258 ; AVX-NEXT:    vpaddb %xmm3, %xmm3, %xmm3
1259 ; AVX-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
1260 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm2
1261 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm2, %xmm2
1262 ; AVX-NEXT:    vpaddb %xmm3, %xmm3, %xmm3
1263 ; AVX-NEXT:    vpblendvb %xmm3, %xmm2, %xmm0, %xmm0
1264 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1265 ; AVX-NEXT:    retq
1266 ;
1267 ; AVX512BW-LABEL: constant_rotate_v16i8:
1268 ; AVX512BW:       # %bb.0:
1269 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} ymm1 = [0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1]
1270 ; AVX512BW-NEXT:    vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero
1271 ; AVX512BW-NEXT:    vpsllvw %zmm1, %zmm0, %zmm1
1272 ; AVX512BW-NEXT:    vpmovwb %zmm1, %ymm1
1273 ; AVX512BW-NEXT:    vmovdqa {{.*#+}} ymm2 = [8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7]
1274 ; AVX512BW-NEXT:    vpsrlvw %zmm2, %zmm0, %zmm0
1275 ; AVX512BW-NEXT:    vpmovwb %zmm0, %ymm0
1276 ; AVX512BW-NEXT:    vpor %xmm0, %xmm1, %xmm0
1277 ; AVX512BW-NEXT:    vzeroupper
1278 ; AVX512BW-NEXT:    retq
1279 ;
1280 ; AVX512VL-LABEL: constant_rotate_v16i8:
1281 ; AVX512VL:       # %bb.0:
1282 ; AVX512VL-NEXT:    vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero
1283 ; AVX512VL-NEXT:    vpsllvw {{.*}}(%rip), %ymm0, %ymm1
1284 ; AVX512VL-NEXT:    vpmovwb %ymm1, %xmm1
1285 ; AVX512VL-NEXT:    vpsrlvw {{.*}}(%rip), %ymm0, %ymm0
1286 ; AVX512VL-NEXT:    vpmovwb %ymm0, %xmm0
1287 ; AVX512VL-NEXT:    vpor %xmm0, %xmm1, %xmm0
1288 ; AVX512VL-NEXT:    vzeroupper
1289 ; AVX512VL-NEXT:    retq
1290 ;
1291 ; XOP-LABEL: constant_rotate_v16i8:
1292 ; XOP:       # %bb.0:
1293 ; XOP-NEXT:    vprotb {{.*}}(%rip), %xmm0, %xmm0
1294 ; XOP-NEXT:    retq
1295 ;
1296 ; X32-SSE-LABEL: constant_rotate_v16i8:
1297 ; X32-SSE:       # %bb.0:
1298 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm3 = [8192,24640,41088,57536,57600,41152,24704,8256]
1299 ; X32-SSE-NEXT:    pxor %xmm2, %xmm2
1300 ; X32-SSE-NEXT:    pxor %xmm1, %xmm1
1301 ; X32-SSE-NEXT:    pcmpgtb %xmm3, %xmm1
1302 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm4
1303 ; X32-SSE-NEXT:    psllw $4, %xmm4
1304 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm4
1305 ; X32-SSE-NEXT:    pand %xmm1, %xmm4
1306 ; X32-SSE-NEXT:    pandn %xmm0, %xmm1
1307 ; X32-SSE-NEXT:    por %xmm4, %xmm1
1308 ; X32-SSE-NEXT:    paddb %xmm3, %xmm3
1309 ; X32-SSE-NEXT:    pxor %xmm4, %xmm4
1310 ; X32-SSE-NEXT:    pcmpgtb %xmm3, %xmm4
1311 ; X32-SSE-NEXT:    movdqa %xmm4, %xmm5
1312 ; X32-SSE-NEXT:    pandn %xmm1, %xmm5
1313 ; X32-SSE-NEXT:    psllw $2, %xmm1
1314 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm1
1315 ; X32-SSE-NEXT:    pand %xmm4, %xmm1
1316 ; X32-SSE-NEXT:    por %xmm5, %xmm1
1317 ; X32-SSE-NEXT:    paddb %xmm3, %xmm3
1318 ; X32-SSE-NEXT:    pxor %xmm4, %xmm4
1319 ; X32-SSE-NEXT:    pcmpgtb %xmm3, %xmm4
1320 ; X32-SSE-NEXT:    movdqa %xmm4, %xmm3
1321 ; X32-SSE-NEXT:    pandn %xmm1, %xmm3
1322 ; X32-SSE-NEXT:    paddb %xmm1, %xmm1
1323 ; X32-SSE-NEXT:    pand %xmm4, %xmm1
1324 ; X32-SSE-NEXT:    movdqa {{.*#+}} xmm4 = [57600,41152,24704,8256,8192,24640,41088,57536]
1325 ; X32-SSE-NEXT:    pxor %xmm5, %xmm5
1326 ; X32-SSE-NEXT:    pcmpgtb %xmm4, %xmm5
1327 ; X32-SSE-NEXT:    movdqa %xmm5, %xmm6
1328 ; X32-SSE-NEXT:    pandn %xmm0, %xmm6
1329 ; X32-SSE-NEXT:    psrlw $4, %xmm0
1330 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1331 ; X32-SSE-NEXT:    pand %xmm5, %xmm0
1332 ; X32-SSE-NEXT:    por %xmm6, %xmm0
1333 ; X32-SSE-NEXT:    paddb %xmm4, %xmm4
1334 ; X32-SSE-NEXT:    pxor %xmm5, %xmm5
1335 ; X32-SSE-NEXT:    pcmpgtb %xmm4, %xmm5
1336 ; X32-SSE-NEXT:    movdqa %xmm5, %xmm6
1337 ; X32-SSE-NEXT:    pandn %xmm0, %xmm6
1338 ; X32-SSE-NEXT:    psrlw $2, %xmm0
1339 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1340 ; X32-SSE-NEXT:    pand %xmm5, %xmm0
1341 ; X32-SSE-NEXT:    por %xmm6, %xmm0
1342 ; X32-SSE-NEXT:    paddb %xmm4, %xmm4
1343 ; X32-SSE-NEXT:    pcmpgtb %xmm4, %xmm2
1344 ; X32-SSE-NEXT:    movdqa %xmm2, %xmm4
1345 ; X32-SSE-NEXT:    pandn %xmm0, %xmm4
1346 ; X32-SSE-NEXT:    psrlw $1, %xmm0
1347 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1348 ; X32-SSE-NEXT:    pand %xmm2, %xmm0
1349 ; X32-SSE-NEXT:    por %xmm4, %xmm0
1350 ; X32-SSE-NEXT:    por %xmm3, %xmm0
1351 ; X32-SSE-NEXT:    por %xmm1, %xmm0
1352 ; X32-SSE-NEXT:    retl
1353   %shl = shl <16 x i8> %a, <i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1>
1354   %lshr = lshr <16 x i8> %a, <i8 8, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1, i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7>
1355   %or = or <16 x i8> %shl, %lshr
1356   ret <16 x i8> %or
1357 }
1358
1359 ;
1360 ; Uniform Constant Rotates
1361 ;
1362
1363 define <2 x i64> @splatconstant_rotate_v2i64(<2 x i64> %a) nounwind {
1364 ; SSE-LABEL: splatconstant_rotate_v2i64:
1365 ; SSE:       # %bb.0:
1366 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1367 ; SSE-NEXT:    psllq $14, %xmm1
1368 ; SSE-NEXT:    psrlq $50, %xmm0
1369 ; SSE-NEXT:    por %xmm1, %xmm0
1370 ; SSE-NEXT:    retq
1371 ;
1372 ; AVX-LABEL: splatconstant_rotate_v2i64:
1373 ; AVX:       # %bb.0:
1374 ; AVX-NEXT:    vpsllq $14, %xmm0, %xmm1
1375 ; AVX-NEXT:    vpsrlq $50, %xmm0, %xmm0
1376 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1377 ; AVX-NEXT:    retq
1378 ;
1379 ; AVX512BW-LABEL: splatconstant_rotate_v2i64:
1380 ; AVX512BW:       # %bb.0:
1381 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
1382 ; AVX512BW-NEXT:    vprolq $14, %zmm0, %zmm0
1383 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 killed %zmm0
1384 ; AVX512BW-NEXT:    vzeroupper
1385 ; AVX512BW-NEXT:    retq
1386 ;
1387 ; AVX512VL-LABEL: splatconstant_rotate_v2i64:
1388 ; AVX512VL:       # %bb.0:
1389 ; AVX512VL-NEXT:    vprolq $14, %xmm0, %xmm0
1390 ; AVX512VL-NEXT:    retq
1391 ;
1392 ; XOP-LABEL: splatconstant_rotate_v2i64:
1393 ; XOP:       # %bb.0:
1394 ; XOP-NEXT:    vprotq $14, %xmm0, %xmm0
1395 ; XOP-NEXT:    retq
1396 ;
1397 ; X32-SSE-LABEL: splatconstant_rotate_v2i64:
1398 ; X32-SSE:       # %bb.0:
1399 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1400 ; X32-SSE-NEXT:    psllq $14, %xmm1
1401 ; X32-SSE-NEXT:    psrlq $50, %xmm0
1402 ; X32-SSE-NEXT:    por %xmm1, %xmm0
1403 ; X32-SSE-NEXT:    retl
1404   %shl = shl <2 x i64> %a, <i64 14, i64 14>
1405   %lshr = lshr <2 x i64> %a, <i64 50, i64 50>
1406   %or = or <2 x i64> %shl, %lshr
1407   ret <2 x i64> %or
1408 }
1409
1410 define <4 x i32> @splatconstant_rotate_v4i32(<4 x i32> %a) nounwind {
1411 ; SSE-LABEL: splatconstant_rotate_v4i32:
1412 ; SSE:       # %bb.0:
1413 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1414 ; SSE-NEXT:    pslld $4, %xmm1
1415 ; SSE-NEXT:    psrld $28, %xmm0
1416 ; SSE-NEXT:    por %xmm1, %xmm0
1417 ; SSE-NEXT:    retq
1418 ;
1419 ; AVX-LABEL: splatconstant_rotate_v4i32:
1420 ; AVX:       # %bb.0:
1421 ; AVX-NEXT:    vpslld $4, %xmm0, %xmm1
1422 ; AVX-NEXT:    vpsrld $28, %xmm0, %xmm0
1423 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1424 ; AVX-NEXT:    retq
1425 ;
1426 ; AVX512BW-LABEL: splatconstant_rotate_v4i32:
1427 ; AVX512BW:       # %bb.0:
1428 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
1429 ; AVX512BW-NEXT:    vprold $4, %zmm0, %zmm0
1430 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 killed %zmm0
1431 ; AVX512BW-NEXT:    vzeroupper
1432 ; AVX512BW-NEXT:    retq
1433 ;
1434 ; AVX512VL-LABEL: splatconstant_rotate_v4i32:
1435 ; AVX512VL:       # %bb.0:
1436 ; AVX512VL-NEXT:    vprold $4, %xmm0, %xmm0
1437 ; AVX512VL-NEXT:    retq
1438 ;
1439 ; XOP-LABEL: splatconstant_rotate_v4i32:
1440 ; XOP:       # %bb.0:
1441 ; XOP-NEXT:    vprotd $4, %xmm0, %xmm0
1442 ; XOP-NEXT:    retq
1443 ;
1444 ; X32-SSE-LABEL: splatconstant_rotate_v4i32:
1445 ; X32-SSE:       # %bb.0:
1446 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1447 ; X32-SSE-NEXT:    pslld $4, %xmm1
1448 ; X32-SSE-NEXT:    psrld $28, %xmm0
1449 ; X32-SSE-NEXT:    por %xmm1, %xmm0
1450 ; X32-SSE-NEXT:    retl
1451   %shl = shl <4 x i32> %a, <i32 4, i32 4, i32 4, i32 4>
1452   %lshr = lshr <4 x i32> %a, <i32 28, i32 28, i32 28, i32 28>
1453   %or = or <4 x i32> %shl, %lshr
1454   ret <4 x i32> %or
1455 }
1456
1457 define <8 x i16> @splatconstant_rotate_v8i16(<8 x i16> %a) nounwind {
1458 ; SSE-LABEL: splatconstant_rotate_v8i16:
1459 ; SSE:       # %bb.0:
1460 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1461 ; SSE-NEXT:    psllw $7, %xmm1
1462 ; SSE-NEXT:    psrlw $9, %xmm0
1463 ; SSE-NEXT:    por %xmm1, %xmm0
1464 ; SSE-NEXT:    retq
1465 ;
1466 ; AVX-LABEL: splatconstant_rotate_v8i16:
1467 ; AVX:       # %bb.0:
1468 ; AVX-NEXT:    vpsllw $7, %xmm0, %xmm1
1469 ; AVX-NEXT:    vpsrlw $9, %xmm0, %xmm0
1470 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1471 ; AVX-NEXT:    retq
1472 ;
1473 ; AVX512-LABEL: splatconstant_rotate_v8i16:
1474 ; AVX512:       # %bb.0:
1475 ; AVX512-NEXT:    vpsllw $7, %xmm0, %xmm1
1476 ; AVX512-NEXT:    vpsrlw $9, %xmm0, %xmm0
1477 ; AVX512-NEXT:    vpor %xmm0, %xmm1, %xmm0
1478 ; AVX512-NEXT:    retq
1479 ;
1480 ; XOP-LABEL: splatconstant_rotate_v8i16:
1481 ; XOP:       # %bb.0:
1482 ; XOP-NEXT:    vprotw $7, %xmm0, %xmm0
1483 ; XOP-NEXT:    retq
1484 ;
1485 ; X32-SSE-LABEL: splatconstant_rotate_v8i16:
1486 ; X32-SSE:       # %bb.0:
1487 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1488 ; X32-SSE-NEXT:    psllw $7, %xmm1
1489 ; X32-SSE-NEXT:    psrlw $9, %xmm0
1490 ; X32-SSE-NEXT:    por %xmm1, %xmm0
1491 ; X32-SSE-NEXT:    retl
1492   %shl = shl <8 x i16> %a, <i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7, i16 7>
1493   %lshr = lshr <8 x i16> %a, <i16 9, i16 9, i16 9, i16 9, i16 9, i16 9, i16 9, i16 9>
1494   %or = or <8 x i16> %shl, %lshr
1495   ret <8 x i16> %or
1496 }
1497
1498 define <16 x i8> @splatconstant_rotate_v16i8(<16 x i8> %a) nounwind {
1499 ; SSE-LABEL: splatconstant_rotate_v16i8:
1500 ; SSE:       # %bb.0:
1501 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1502 ; SSE-NEXT:    psllw $4, %xmm1
1503 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
1504 ; SSE-NEXT:    psrlw $4, %xmm0
1505 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
1506 ; SSE-NEXT:    por %xmm1, %xmm0
1507 ; SSE-NEXT:    retq
1508 ;
1509 ; AVX-LABEL: splatconstant_rotate_v16i8:
1510 ; AVX:       # %bb.0:
1511 ; AVX-NEXT:    vpsllw $4, %xmm0, %xmm1
1512 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1513 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm0
1514 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1515 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1516 ; AVX-NEXT:    retq
1517 ;
1518 ; AVX512-LABEL: splatconstant_rotate_v16i8:
1519 ; AVX512:       # %bb.0:
1520 ; AVX512-NEXT:    vpsllw $4, %xmm0, %xmm1
1521 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1522 ; AVX512-NEXT:    vpsrlw $4, %xmm0, %xmm0
1523 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1524 ; AVX512-NEXT:    vpor %xmm0, %xmm1, %xmm0
1525 ; AVX512-NEXT:    retq
1526 ;
1527 ; XOP-LABEL: splatconstant_rotate_v16i8:
1528 ; XOP:       # %bb.0:
1529 ; XOP-NEXT:    vprotb $4, %xmm0, %xmm0
1530 ; XOP-NEXT:    retq
1531 ;
1532 ; X32-SSE-LABEL: splatconstant_rotate_v16i8:
1533 ; X32-SSE:       # %bb.0:
1534 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1535 ; X32-SSE-NEXT:    psllw $4, %xmm1
1536 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm1
1537 ; X32-SSE-NEXT:    psrlw $4, %xmm0
1538 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1539 ; X32-SSE-NEXT:    por %xmm1, %xmm0
1540 ; X32-SSE-NEXT:    retl
1541   %shl = shl <16 x i8> %a, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
1542   %lshr = lshr <16 x i8> %a, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
1543   %or = or <16 x i8> %shl, %lshr
1544   ret <16 x i8> %or
1545 }
1546
1547 ;
1548 ; Masked Uniform Constant Rotates
1549 ;
1550
1551 define <2 x i64> @splatconstant_rotate_mask_v2i64(<2 x i64> %a) nounwind {
1552 ; SSE-LABEL: splatconstant_rotate_mask_v2i64:
1553 ; SSE:       # %bb.0:
1554 ; SSE-NEXT:    psrlq $49, %xmm0
1555 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
1556 ; SSE-NEXT:    retq
1557 ;
1558 ; AVX-LABEL: splatconstant_rotate_mask_v2i64:
1559 ; AVX:       # %bb.0:
1560 ; AVX-NEXT:    vpsrlq $49, %xmm0, %xmm0
1561 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1562 ; AVX-NEXT:    retq
1563 ;
1564 ; AVX512BW-LABEL: splatconstant_rotate_mask_v2i64:
1565 ; AVX512BW:       # %bb.0:
1566 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
1567 ; AVX512BW-NEXT:    vprolq $15, %zmm0, %zmm0
1568 ; AVX512BW-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1569 ; AVX512BW-NEXT:    vzeroupper
1570 ; AVX512BW-NEXT:    retq
1571 ;
1572 ; AVX512VL-LABEL: splatconstant_rotate_mask_v2i64:
1573 ; AVX512VL:       # %bb.0:
1574 ; AVX512VL-NEXT:    vprolq $15, %xmm0, %xmm0
1575 ; AVX512VL-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1576 ; AVX512VL-NEXT:    retq
1577 ;
1578 ; XOP-LABEL: splatconstant_rotate_mask_v2i64:
1579 ; XOP:       # %bb.0:
1580 ; XOP-NEXT:    vprotq $15, %xmm0, %xmm0
1581 ; XOP-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1582 ; XOP-NEXT:    retq
1583 ;
1584 ; X32-SSE-LABEL: splatconstant_rotate_mask_v2i64:
1585 ; X32-SSE:       # %bb.0:
1586 ; X32-SSE-NEXT:    psrlq $49, %xmm0
1587 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1588 ; X32-SSE-NEXT:    retl
1589   %shl = shl <2 x i64> %a, <i64 15, i64 15>
1590   %lshr = lshr <2 x i64> %a, <i64 49, i64 49>
1591   %rmask = and <2 x i64> %lshr, <i64 255, i64 127>
1592   %lmask = and <2 x i64> %shl, <i64 65, i64 33>
1593   %or = or <2 x i64> %lmask, %rmask
1594   ret <2 x i64> %or
1595 }
1596
1597 define <4 x i32> @splatconstant_rotate_mask_v4i32(<4 x i32> %a) nounwind {
1598 ; SSE-LABEL: splatconstant_rotate_mask_v4i32:
1599 ; SSE:       # %bb.0:
1600 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1601 ; SSE-NEXT:    pslld $4, %xmm1
1602 ; SSE-NEXT:    psrld $28, %xmm0
1603 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
1604 ; SSE-NEXT:    por %xmm0, %xmm1
1605 ; SSE-NEXT:    movdqa %xmm1, %xmm0
1606 ; SSE-NEXT:    retq
1607 ;
1608 ; AVX-LABEL: splatconstant_rotate_mask_v4i32:
1609 ; AVX:       # %bb.0:
1610 ; AVX-NEXT:    vpslld $4, %xmm0, %xmm1
1611 ; AVX-NEXT:    vpsrld $28, %xmm0, %xmm0
1612 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1613 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1614 ; AVX-NEXT:    retq
1615 ;
1616 ; AVX512BW-LABEL: splatconstant_rotate_mask_v4i32:
1617 ; AVX512BW:       # %bb.0:
1618 ; AVX512BW-NEXT:    # kill: def %xmm0 killed %xmm0 def %zmm0
1619 ; AVX512BW-NEXT:    vprold $4, %zmm0, %zmm0
1620 ; AVX512BW-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1621 ; AVX512BW-NEXT:    vzeroupper
1622 ; AVX512BW-NEXT:    retq
1623 ;
1624 ; AVX512VL-LABEL: splatconstant_rotate_mask_v4i32:
1625 ; AVX512VL:       # %bb.0:
1626 ; AVX512VL-NEXT:    vprold $4, %xmm0, %xmm0
1627 ; AVX512VL-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1628 ; AVX512VL-NEXT:    retq
1629 ;
1630 ; XOP-LABEL: splatconstant_rotate_mask_v4i32:
1631 ; XOP:       # %bb.0:
1632 ; XOP-NEXT:    vprotd $4, %xmm0, %xmm0
1633 ; XOP-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1634 ; XOP-NEXT:    retq
1635 ;
1636 ; X32-SSE-LABEL: splatconstant_rotate_mask_v4i32:
1637 ; X32-SSE:       # %bb.0:
1638 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1639 ; X32-SSE-NEXT:    pslld $4, %xmm1
1640 ; X32-SSE-NEXT:    psrld $28, %xmm0
1641 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm1
1642 ; X32-SSE-NEXT:    por %xmm0, %xmm1
1643 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm0
1644 ; X32-SSE-NEXT:    retl
1645   %shl = shl <4 x i32> %a, <i32 4, i32 4, i32 4, i32 4>
1646   %lshr = lshr <4 x i32> %a, <i32 28, i32 28, i32 28, i32 28>
1647   %rmask = and <4 x i32> %lshr, <i32 127, i32 255, i32 511, i32 1023>
1648   %lmask = and <4 x i32> %shl, <i32 1023, i32 511, i32 255, i32 127>
1649   %or = or <4 x i32> %lmask, %rmask
1650   ret <4 x i32> %or
1651 }
1652
1653 define <8 x i16> @splatconstant_rotate_mask_v8i16(<8 x i16> %a) nounwind {
1654 ; SSE-LABEL: splatconstant_rotate_mask_v8i16:
1655 ; SSE:       # %bb.0:
1656 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1657 ; SSE-NEXT:    psllw $5, %xmm1
1658 ; SSE-NEXT:    psrlw $11, %xmm0
1659 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
1660 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
1661 ; SSE-NEXT:    por %xmm0, %xmm1
1662 ; SSE-NEXT:    movdqa %xmm1, %xmm0
1663 ; SSE-NEXT:    retq
1664 ;
1665 ; AVX-LABEL: splatconstant_rotate_mask_v8i16:
1666 ; AVX:       # %bb.0:
1667 ; AVX-NEXT:    vpsllw $5, %xmm0, %xmm1
1668 ; AVX-NEXT:    vpsrlw $11, %xmm0, %xmm0
1669 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1670 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1671 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1672 ; AVX-NEXT:    retq
1673 ;
1674 ; AVX512-LABEL: splatconstant_rotate_mask_v8i16:
1675 ; AVX512:       # %bb.0:
1676 ; AVX512-NEXT:    vpsllw $5, %xmm0, %xmm1
1677 ; AVX512-NEXT:    vpsrlw $11, %xmm0, %xmm0
1678 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1679 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1680 ; AVX512-NEXT:    vpor %xmm0, %xmm1, %xmm0
1681 ; AVX512-NEXT:    retq
1682 ;
1683 ; XOP-LABEL: splatconstant_rotate_mask_v8i16:
1684 ; XOP:       # %bb.0:
1685 ; XOP-NEXT:    vprotw $5, %xmm0, %xmm0
1686 ; XOP-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1687 ; XOP-NEXT:    retq
1688 ;
1689 ; X32-SSE-LABEL: splatconstant_rotate_mask_v8i16:
1690 ; X32-SSE:       # %bb.0:
1691 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1692 ; X32-SSE-NEXT:    psllw $5, %xmm1
1693 ; X32-SSE-NEXT:    psrlw $11, %xmm0
1694 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1695 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm1
1696 ; X32-SSE-NEXT:    por %xmm0, %xmm1
1697 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm0
1698 ; X32-SSE-NEXT:    retl
1699   %shl = shl <8 x i16> %a, <i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5>
1700   %lshr = lshr <8 x i16> %a, <i16 11, i16 11, i16 11, i16 11, i16 11, i16 11, i16 11, i16 11>
1701   %rmask = and <8 x i16> %lshr, <i16 55, i16 55, i16 55, i16 55, i16 55, i16 55, i16 55, i16 55>
1702   %lmask = and <8 x i16> %shl, <i16 33, i16 33, i16 33, i16 33, i16 33, i16 33, i16 33, i16 33>
1703   %or = or <8 x i16> %lmask, %rmask
1704   ret <8 x i16> %or
1705 }
1706
1707 define <16 x i8> @splatconstant_rotate_mask_v16i8(<16 x i8> %a) nounwind {
1708 ; SSE-LABEL: splatconstant_rotate_mask_v16i8:
1709 ; SSE:       # %bb.0:
1710 ; SSE-NEXT:    movdqa %xmm0, %xmm1
1711 ; SSE-NEXT:    psllw $4, %xmm1
1712 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
1713 ; SSE-NEXT:    psrlw $4, %xmm0
1714 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
1715 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
1716 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
1717 ; SSE-NEXT:    por %xmm0, %xmm1
1718 ; SSE-NEXT:    movdqa %xmm1, %xmm0
1719 ; SSE-NEXT:    retq
1720 ;
1721 ; AVX-LABEL: splatconstant_rotate_mask_v16i8:
1722 ; AVX:       # %bb.0:
1723 ; AVX-NEXT:    vpsllw $4, %xmm0, %xmm1
1724 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1725 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm0
1726 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1727 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1728 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1729 ; AVX-NEXT:    vpor %xmm0, %xmm1, %xmm0
1730 ; AVX-NEXT:    retq
1731 ;
1732 ; AVX512-LABEL: splatconstant_rotate_mask_v16i8:
1733 ; AVX512:       # %bb.0:
1734 ; AVX512-NEXT:    vpsllw $4, %xmm0, %xmm1
1735 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1736 ; AVX512-NEXT:    vpsrlw $4, %xmm0, %xmm0
1737 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1738 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1739 ; AVX512-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
1740 ; AVX512-NEXT:    vpor %xmm0, %xmm1, %xmm0
1741 ; AVX512-NEXT:    retq
1742 ;
1743 ; XOP-LABEL: splatconstant_rotate_mask_v16i8:
1744 ; XOP:       # %bb.0:
1745 ; XOP-NEXT:    vprotb $4, %xmm0, %xmm0
1746 ; XOP-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
1747 ; XOP-NEXT:    retq
1748 ;
1749 ; X32-SSE-LABEL: splatconstant_rotate_mask_v16i8:
1750 ; X32-SSE:       # %bb.0:
1751 ; X32-SSE-NEXT:    movdqa %xmm0, %xmm1
1752 ; X32-SSE-NEXT:    psllw $4, %xmm1
1753 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm1
1754 ; X32-SSE-NEXT:    psrlw $4, %xmm0
1755 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1756 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm0
1757 ; X32-SSE-NEXT:    pand {{\.LCPI.*}}, %xmm1
1758 ; X32-SSE-NEXT:    por %xmm0, %xmm1
1759 ; X32-SSE-NEXT:    movdqa %xmm1, %xmm0
1760 ; X32-SSE-NEXT:    retl
1761   %shl = shl <16 x i8> %a, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
1762   %lshr = lshr <16 x i8> %a, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
1763   %rmask = and <16 x i8> %lshr, <i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55, i8 55>
1764   %lmask = and <16 x i8> %shl, <i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33, i8 33>
1765   %or = or <16 x i8> %lmask, %rmask
1766   ret <16 x i8> %or
1767 }