1 ; TODO: Add AVX512BW shift support
2 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl -mattr=+avx512dq | FileCheck %s --check-prefix=ALL --check-prefix=AVX512 --check-prefix=AVX512DQ
8 define <8 x i64> @var_shift_v8i64(<8 x i64> %a, <8 x i64> %b) nounwind {
9 ; ALL-LABEL: var_shift_v8i64:
11 ; ALL-NEXT: vpsllvq %zmm1, %zmm0, %zmm0
13 %shift = shl <8 x i64> %a, %b
17 define <16 x i32> @var_shift_v16i32(<16 x i32> %a, <16 x i32> %b) nounwind {
18 ; ALL-LABEL: var_shift_v16i32:
20 ; ALL-NEXT: vpsllvd %zmm1, %zmm0, %zmm0
22 %shift = shl <16 x i32> %a, %b
26 define <32 x i16> @var_shift_v32i16(<32 x i16> %a, <32 x i16> %b) nounwind {
27 ; ALL-LABEL: var_shift_v32i16:
29 ; ALL-NEXT: vpxor %ymm4, %ymm4, %ymm4
30 ; ALL-NEXT: vpunpckhwd {{.*#+}} ymm5 = ymm2[4],ymm4[4],ymm2[5],ymm4[5],ymm2[6],ymm4[6],ymm2[7],ymm4[7],ymm2[12],ymm4[12],ymm2[13],ymm4[13],ymm2[14],ymm4[14],ymm2[15],ymm4[15]
31 ; ALL-NEXT: vpunpckhwd {{.*#+}} ymm6 = ymm0[4,4,5,5,6,6,7,7,12,12,13,13,14,14,15,15]
32 ; ALL-NEXT: vpsllvd %ymm5, %ymm6, %ymm5
33 ; ALL-NEXT: vpsrld $16, %ymm5, %ymm5
34 ; ALL-NEXT: vpunpcklwd {{.*#+}} ymm2 = ymm2[0],ymm4[0],ymm2[1],ymm4[1],ymm2[2],ymm4[2],ymm2[3],ymm4[3],ymm2[8],ymm4[8],ymm2[9],ymm4[9],ymm2[10],ymm4[10],ymm2[11],ymm4[11]
35 ; ALL-NEXT: vpunpcklwd {{.*#+}} ymm0 = ymm0[0,0,1,1,2,2,3,3,8,8,9,9,10,10,11,11]
36 ; ALL-NEXT: vpsllvd %ymm2, %ymm0, %ymm0
37 ; ALL-NEXT: vpsrld $16, %ymm0, %ymm0
38 ; ALL-NEXT: vpackusdw %ymm5, %ymm0, %ymm0
39 ; ALL-NEXT: vpunpckhwd {{.*#+}} ymm2 = ymm3[4],ymm4[4],ymm3[5],ymm4[5],ymm3[6],ymm4[6],ymm3[7],ymm4[7],ymm3[12],ymm4[12],ymm3[13],ymm4[13],ymm3[14],ymm4[14],ymm3[15],ymm4[15]
40 ; ALL-NEXT: vpunpckhwd {{.*#+}} ymm5 = ymm1[4,4,5,5,6,6,7,7,12,12,13,13,14,14,15,15]
41 ; ALL-NEXT: vpsllvd %ymm2, %ymm5, %ymm2
42 ; ALL-NEXT: vpsrld $16, %ymm2, %ymm2
43 ; ALL-NEXT: vpunpcklwd {{.*#+}} ymm3 = ymm3[0],ymm4[0],ymm3[1],ymm4[1],ymm3[2],ymm4[2],ymm3[3],ymm4[3],ymm3[8],ymm4[8],ymm3[9],ymm4[9],ymm3[10],ymm4[10],ymm3[11],ymm4[11]
44 ; ALL-NEXT: vpunpcklwd {{.*#+}} ymm1 = ymm1[0,0,1,1,2,2,3,3,8,8,9,9,10,10,11,11]
45 ; ALL-NEXT: vpsllvd %ymm3, %ymm1, %ymm1
46 ; ALL-NEXT: vpsrld $16, %ymm1, %ymm1
47 ; ALL-NEXT: vpackusdw %ymm2, %ymm1, %ymm1
49 %shift = shl <32 x i16> %a, %b
53 define <64 x i8> @var_shift_v64i8(<64 x i8> %a, <64 x i8> %b) nounwind {
54 ; ALL-LABEL: var_shift_v64i8:
56 ; ALL-NEXT: vpsllw $4, %ymm0, %ymm4
57 ; ALL-NEXT: vmovdqa {{.*#+}} ymm5 = [240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240]
58 ; ALL-NEXT: vpand %ymm5, %ymm4, %ymm4
59 ; ALL-NEXT: vpsllw $5, %ymm2, %ymm2
60 ; ALL-NEXT: vpblendvb %ymm2, %ymm4, %ymm0, %ymm0
61 ; ALL-NEXT: vpsllw $2, %ymm0, %ymm4
62 ; ALL-NEXT: vmovdqa {{.*#+}} ymm6 = [252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252]
63 ; ALL-NEXT: vpand %ymm6, %ymm4, %ymm4
64 ; ALL-NEXT: vpaddb %ymm2, %ymm2, %ymm2
65 ; ALL-NEXT: vpblendvb %ymm2, %ymm4, %ymm0, %ymm0
66 ; ALL-NEXT: vpaddb %ymm0, %ymm0, %ymm4
67 ; ALL-NEXT: vpaddb %ymm2, %ymm2, %ymm2
68 ; ALL-NEXT: vpblendvb %ymm2, %ymm4, %ymm0, %ymm0
69 ; ALL-NEXT: vpsllw $4, %ymm1, %ymm2
70 ; ALL-NEXT: vpand %ymm5, %ymm2, %ymm2
71 ; ALL-NEXT: vpsllw $5, %ymm3, %ymm3
72 ; ALL-NEXT: vpblendvb %ymm3, %ymm2, %ymm1, %ymm1
73 ; ALL-NEXT: vpsllw $2, %ymm1, %ymm2
74 ; ALL-NEXT: vpand %ymm6, %ymm2, %ymm2
75 ; ALL-NEXT: vpaddb %ymm3, %ymm3, %ymm3
76 ; ALL-NEXT: vpblendvb %ymm3, %ymm2, %ymm1, %ymm1
77 ; ALL-NEXT: vpaddb %ymm1, %ymm1, %ymm2
78 ; ALL-NEXT: vpaddb %ymm3, %ymm3, %ymm3
79 ; ALL-NEXT: vpblendvb %ymm3, %ymm2, %ymm1, %ymm1
81 %shift = shl <64 x i8> %a, %b
86 ; Uniform Variable Shifts
89 define <8 x i64> @splatvar_shift_v8i64(<8 x i64> %a, <8 x i64> %b) nounwind {
90 ; ALL-LABEL: splatvar_shift_v8i64:
92 ; ALL-NEXT: vpsllq %xmm1, %zmm0, %zmm0
94 %splat = shufflevector <8 x i64> %b, <8 x i64> undef, <8 x i32> zeroinitializer
95 %shift = shl <8 x i64> %a, %splat
99 define <16 x i32> @splatvar_shift_v16i32(<16 x i32> %a, <16 x i32> %b) nounwind {
100 ; ALL-LABEL: splatvar_shift_v16i32:
102 ; ALL-NEXT: vxorps %xmm2, %xmm2, %xmm2
103 ; ALL-NEXT: vmovss %xmm1, %xmm2, %xmm1
104 ; ALL-NEXT: vpslld %xmm1, %zmm0, %zmm0
106 %splat = shufflevector <16 x i32> %b, <16 x i32> undef, <16 x i32> zeroinitializer
107 %shift = shl <16 x i32> %a, %splat
108 ret <16 x i32> %shift
111 define <32 x i16> @splatvar_shift_v32i16(<32 x i16> %a, <32 x i16> %b) nounwind {
112 ; ALL-LABEL: splatvar_shift_v32i16:
114 ; ALL-NEXT: vmovd %xmm2, %eax
115 ; ALL-NEXT: movzwl %ax, %eax
116 ; ALL-NEXT: vmovd %eax, %xmm2
117 ; ALL-NEXT: vpsllw %xmm2, %ymm0, %ymm0
118 ; ALL-NEXT: vpsllw %xmm2, %ymm1, %ymm1
120 %splat = shufflevector <32 x i16> %b, <32 x i16> undef, <32 x i32> zeroinitializer
121 %shift = shl <32 x i16> %a, %splat
122 ret <32 x i16> %shift
125 define <64 x i8> @splatvar_shift_v64i8(<64 x i8> %a, <64 x i8> %b) nounwind {
126 ; ALL-LABEL: splatvar_shift_v64i8:
128 ; ALL-NEXT: vpbroadcastb %xmm2, %ymm2
129 ; ALL-NEXT: vpsllw $4, %ymm0, %ymm3
130 ; ALL-NEXT: vmovdqa {{.*#+}} ymm4 = [240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240]
131 ; ALL-NEXT: vpand %ymm4, %ymm3, %ymm3
132 ; ALL-NEXT: vpsllw $5, %ymm2, %ymm2
133 ; ALL-NEXT: vpblendvb %ymm2, %ymm3, %ymm0, %ymm0
134 ; ALL-NEXT: vpsllw $2, %ymm0, %ymm3
135 ; ALL-NEXT: vmovdqa {{.*#+}} ymm5 = [252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252]
136 ; ALL-NEXT: vpand %ymm5, %ymm3, %ymm3
137 ; ALL-NEXT: vpaddb %ymm2, %ymm2, %ymm6
138 ; ALL-NEXT: vpblendvb %ymm6, %ymm3, %ymm0, %ymm0
139 ; ALL-NEXT: vpaddb %ymm0, %ymm0, %ymm3
140 ; ALL-NEXT: vpaddb %ymm6, %ymm6, %ymm7
141 ; ALL-NEXT: vpblendvb %ymm7, %ymm3, %ymm0, %ymm0
142 ; ALL-NEXT: vpsllw $4, %ymm1, %ymm3
143 ; ALL-NEXT: vpand %ymm4, %ymm3, %ymm3
144 ; ALL-NEXT: vpblendvb %ymm2, %ymm3, %ymm1, %ymm1
145 ; ALL-NEXT: vpsllw $2, %ymm1, %ymm2
146 ; ALL-NEXT: vpand %ymm5, %ymm2, %ymm2
147 ; ALL-NEXT: vpblendvb %ymm6, %ymm2, %ymm1, %ymm1
148 ; ALL-NEXT: vpaddb %ymm1, %ymm1, %ymm2
149 ; ALL-NEXT: vpblendvb %ymm7, %ymm2, %ymm1, %ymm1
151 %splat = shufflevector <64 x i8> %b, <64 x i8> undef, <64 x i32> zeroinitializer
152 %shift = shl <64 x i8> %a, %splat
160 define <8 x i64> @constant_shift_v8i64(<8 x i64> %a) nounwind {
161 ; ALL-LABEL: constant_shift_v8i64:
163 ; ALL-NEXT: vpsllvq {{.*}}(%rip), %zmm0, %zmm0
165 %shift = shl <8 x i64> %a, <i64 1, i64 7, i64 31, i64 62, i64 1, i64 7, i64 31, i64 62>
169 define <16 x i32> @constant_shift_v16i32(<16 x i32> %a) nounwind {
170 ; ALL-LABEL: constant_shift_v16i32:
172 ; ALL-NEXT: vpsllvd {{.*}}(%rip), %zmm0, %zmm0
174 %shift = shl <16 x i32> %a, <i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 8, i32 7, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 8, i32 7>
175 ret <16 x i32> %shift
178 define <32 x i16> @constant_shift_v32i16(<32 x i16> %a) nounwind {
179 ; ALL-LABEL: constant_shift_v32i16:
181 ; ALL-NEXT: vmovdqa {{.*#+}} ymm2 = [1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768]
182 ; ALL-NEXT: vpmullw %ymm2, %ymm0, %ymm0
183 ; ALL-NEXT: vpmullw %ymm2, %ymm1, %ymm1
185 %shift = shl <32 x i16> %a, <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15, i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14, i16 15>
186 ret <32 x i16> %shift
189 define <64 x i8> @constant_shift_v64i8(<64 x i8> %a) nounwind {
190 ; ALL-LABEL: constant_shift_v64i8:
192 ; ALL-NEXT: vpsllw $4, %ymm0, %ymm2
193 ; ALL-NEXT: vmovdqa {{.*#+}} ymm3 = [240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240]
194 ; ALL-NEXT: vpand %ymm3, %ymm2, %ymm2
195 ; ALL-NEXT: vmovdqa {{.*#+}} ymm4 = [0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0,0,1,2,3,4,5,6,7,7,6,5,4,3,2,1,0]
196 ; ALL-NEXT: vpsllw $5, %ymm4, %ymm4
197 ; ALL-NEXT: vpblendvb %ymm4, %ymm2, %ymm0, %ymm0
198 ; ALL-NEXT: vpsllw $2, %ymm0, %ymm2
199 ; ALL-NEXT: vmovdqa {{.*#+}} ymm5 = [252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252]
200 ; ALL-NEXT: vpand %ymm5, %ymm2, %ymm2
201 ; ALL-NEXT: vpaddb %ymm4, %ymm4, %ymm6
202 ; ALL-NEXT: vpblendvb %ymm6, %ymm2, %ymm0, %ymm0
203 ; ALL-NEXT: vpaddb %ymm0, %ymm0, %ymm2
204 ; ALL-NEXT: vpaddb %ymm6, %ymm6, %ymm7
205 ; ALL-NEXT: vpblendvb %ymm7, %ymm2, %ymm0, %ymm0
206 ; ALL-NEXT: vpsllw $4, %ymm1, %ymm2
207 ; ALL-NEXT: vpand %ymm3, %ymm2, %ymm2
208 ; ALL-NEXT: vpblendvb %ymm4, %ymm2, %ymm1, %ymm1
209 ; ALL-NEXT: vpsllw $2, %ymm1, %ymm2
210 ; ALL-NEXT: vpand %ymm5, %ymm2, %ymm2
211 ; ALL-NEXT: vpblendvb %ymm6, %ymm2, %ymm1, %ymm1
212 ; ALL-NEXT: vpaddb %ymm1, %ymm1, %ymm2
213 ; ALL-NEXT: vpblendvb %ymm7, %ymm2, %ymm1, %ymm1
215 %shift = shl <64 x i8> %a, <i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1, i8 0, i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1, i8 0, i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1, i8 0, i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 7, i8 6, i8 5, i8 4, i8 3, i8 2, i8 1, i8 0>
220 ; Uniform Constant Shifts
223 define <8 x i64> @splatconstant_shift_v8i64(<8 x i64> %a) nounwind {
224 ; ALL-LABEL: splatconstant_shift_v8i64:
226 ; ALL-NEXT: vpsllq $7, %zmm0, %zmm0
228 %shift = shl <8 x i64> %a, <i64 7, i64 7, i64 7, i64 7, i64 7, i64 7, i64 7, i64 7>
232 define <16 x i32> @splatconstant_shift_v16i32(<16 x i32> %a) nounwind {
233 ; ALL-LABEL: splatconstant_shift_v16i32:
235 ; ALL-NEXT: vpslld $5, %zmm0, %zmm0
237 %shift = shl <16 x i32> %a, <i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5, i32 5>
238 ret <16 x i32> %shift
241 define <32 x i16> @splatconstant_shift_v32i16(<32 x i16> %a) nounwind {
242 ; ALL-LABEL: splatconstant_shift_v32i16:
244 ; ALL-NEXT: vpsllw $3, %ymm0, %ymm0
245 ; ALL-NEXT: vpsllw $3, %ymm1, %ymm1
247 %shift = shl <32 x i16> %a, <i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3, i16 3>
248 ret <32 x i16> %shift
251 define <64 x i8> @splatconstant_shift_v64i8(<64 x i8> %a) nounwind {
252 ; ALL-LABEL: splatconstant_shift_v64i8:
254 ; ALL-NEXT: vpsllw $3, %ymm0, %ymm0
255 ; ALL-NEXT: vmovdqa {{.*#+}} ymm2 = [248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248]
256 ; ALL-NEXT: vpand %ymm2, %ymm0, %ymm0
257 ; ALL-NEXT: vpsllw $3, %ymm1, %ymm1
258 ; ALL-NEXT: vpand %ymm2, %ymm1, %ymm1
260 %shift = shl <64 x i8> %a, <i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3, i8 3>