9efbc96118c124fcb85d5c6723a2ee28729bac37
[oota-llvm.git] / test / CodeGen / X86 / vector-tzcnt-512.ll
1 ; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl -mattr=+avx512cd | FileCheck %s --check-prefix=ALL --check-prefix=AVX512 --check-prefix=AVX512CD
2
3 define <8 x i64> @testv8i64(<8 x i64> %in) nounwind {
4 ; ALL-LABEL: testv8i64:
5 ; ALL:       ## BB#0:
6 ; ALL-NEXT:    vextracti32x4 $3, %zmm0, %xmm1
7 ; ALL-NEXT:    vpextrq $1, %xmm1, %rax
8 ; ALL-NEXT:    tzcntq %rax, %rax
9 ; ALL-NEXT:    vmovq %rax, %xmm2
10 ; ALL-NEXT:    vmovq %xmm1, %rax
11 ; ALL-NEXT:    tzcntq %rax, %rax
12 ; ALL-NEXT:    vmovq %rax, %xmm1
13 ; ALL-NEXT:    vpunpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]
14 ; ALL-NEXT:    vextracti32x4 $2, %zmm0, %xmm2
15 ; ALL-NEXT:    vpextrq $1, %xmm2, %rax
16 ; ALL-NEXT:    tzcntq %rax, %rax
17 ; ALL-NEXT:    vmovq %rax, %xmm3
18 ; ALL-NEXT:    vmovq %xmm2, %rax
19 ; ALL-NEXT:    tzcntq %rax, %rax
20 ; ALL-NEXT:    vmovq %rax, %xmm2
21 ; ALL-NEXT:    vpunpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
22 ; ALL-NEXT:    vinserti128 $1, %xmm1, %ymm2, %ymm1
23 ; ALL-NEXT:    vextracti32x4 $1, %zmm0, %xmm2
24 ; ALL-NEXT:    vpextrq $1, %xmm2, %rax
25 ; ALL-NEXT:    tzcntq %rax, %rax
26 ; ALL-NEXT:    vmovq %rax, %xmm3
27 ; ALL-NEXT:    vmovq %xmm2, %rax
28 ; ALL-NEXT:    tzcntq %rax, %rax
29 ; ALL-NEXT:    vmovq %rax, %xmm2
30 ; ALL-NEXT:    vpunpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm3[0]
31 ; ALL-NEXT:    vpextrq $1, %xmm0, %rax
32 ; ALL-NEXT:    tzcntq %rax, %rax
33 ; ALL-NEXT:    vmovq %rax, %xmm3
34 ; ALL-NEXT:    vmovq %xmm0, %rax
35 ; ALL-NEXT:    tzcntq %rax, %rax
36 ; ALL-NEXT:    vmovq %rax, %xmm0
37 ; ALL-NEXT:    vpunpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm3[0]
38 ; ALL-NEXT:    vinserti128 $1, %xmm2, %ymm0, %ymm0
39 ; ALL-NEXT:    vinserti64x4 $1, %ymm1, %zmm0, %zmm0
40 ; ALL-NEXT:    retq
41   %out = call <8 x i64> @llvm.cttz.v8i64(<8 x i64> %in, i1 0)
42   ret <8 x i64> %out
43 }
44
45 define <8 x i64> @testv8i64u(<8 x i64> %in) nounwind {
46 ; ALL-LABEL: testv8i64u:
47 ; ALL:       ## BB#0:
48 ; ALL-NEXT:    vpxord %zmm1, %zmm1, %zmm1
49 ; ALL-NEXT:    vpsubq %zmm0, %zmm1, %zmm1
50 ; ALL-NEXT:    vpandq %zmm1, %zmm0, %zmm0
51 ; ALL-NEXT:    vplzcntq %zmm0, %zmm0
52 ; ALL-NEXT:    vpbroadcastq {{.*}}(%rip), %zmm1
53 ; ALL-NEXT:    vpsubq %zmm0, %zmm1, %zmm0
54 ; ALL-NEXT:    retq
55   %out = call <8 x i64> @llvm.cttz.v8i64(<8 x i64> %in, i1 -1)
56   ret <8 x i64> %out
57 }
58
59 define <16 x i32> @testv16i32(<16 x i32> %in) nounwind {
60 ; ALL-LABEL: testv16i32:
61 ; ALL:       ## BB#0:
62 ; ALL-NEXT:    vextracti32x4 $3, %zmm0, %xmm1
63 ; ALL-NEXT:    vpextrd $1, %xmm1, %eax
64 ; ALL-NEXT:    tzcntl %eax, %eax
65 ; ALL-NEXT:    vmovd %xmm1, %ecx
66 ; ALL-NEXT:    tzcntl %ecx, %ecx
67 ; ALL-NEXT:    vmovd %ecx, %xmm2
68 ; ALL-NEXT:    vpinsrd $1, %eax, %xmm2, %xmm2
69 ; ALL-NEXT:    vpextrd $2, %xmm1, %eax
70 ; ALL-NEXT:    tzcntl %eax, %eax
71 ; ALL-NEXT:    vpinsrd $2, %eax, %xmm2, %xmm2
72 ; ALL-NEXT:    vpextrd $3, %xmm1, %eax
73 ; ALL-NEXT:    tzcntl %eax, %eax
74 ; ALL-NEXT:    vpinsrd $3, %eax, %xmm2, %xmm1
75 ; ALL-NEXT:    vextracti32x4 $2, %zmm0, %xmm2
76 ; ALL-NEXT:    vpextrd $1, %xmm2, %eax
77 ; ALL-NEXT:    tzcntl %eax, %eax
78 ; ALL-NEXT:    vmovd %xmm2, %ecx
79 ; ALL-NEXT:    tzcntl %ecx, %ecx
80 ; ALL-NEXT:    vmovd %ecx, %xmm3
81 ; ALL-NEXT:    vpinsrd $1, %eax, %xmm3, %xmm3
82 ; ALL-NEXT:    vpextrd $2, %xmm2, %eax
83 ; ALL-NEXT:    tzcntl %eax, %eax
84 ; ALL-NEXT:    vpinsrd $2, %eax, %xmm3, %xmm3
85 ; ALL-NEXT:    vpextrd $3, %xmm2, %eax
86 ; ALL-NEXT:    tzcntl %eax, %eax
87 ; ALL-NEXT:    vpinsrd $3, %eax, %xmm3, %xmm2
88 ; ALL-NEXT:    vinserti128 $1, %xmm1, %ymm2, %ymm1
89 ; ALL-NEXT:    vextracti32x4 $1, %zmm0, %xmm2
90 ; ALL-NEXT:    vpextrd $1, %xmm2, %eax
91 ; ALL-NEXT:    tzcntl %eax, %eax
92 ; ALL-NEXT:    vmovd %xmm2, %ecx
93 ; ALL-NEXT:    tzcntl %ecx, %ecx
94 ; ALL-NEXT:    vmovd %ecx, %xmm3
95 ; ALL-NEXT:    vpinsrd $1, %eax, %xmm3, %xmm3
96 ; ALL-NEXT:    vpextrd $2, %xmm2, %eax
97 ; ALL-NEXT:    tzcntl %eax, %eax
98 ; ALL-NEXT:    vpinsrd $2, %eax, %xmm3, %xmm3
99 ; ALL-NEXT:    vpextrd $3, %xmm2, %eax
100 ; ALL-NEXT:    tzcntl %eax, %eax
101 ; ALL-NEXT:    vpinsrd $3, %eax, %xmm3, %xmm2
102 ; ALL-NEXT:    vpextrd $1, %xmm0, %eax
103 ; ALL-NEXT:    tzcntl %eax, %eax
104 ; ALL-NEXT:    vmovd %xmm0, %ecx
105 ; ALL-NEXT:    tzcntl %ecx, %ecx
106 ; ALL-NEXT:    vmovd %ecx, %xmm3
107 ; ALL-NEXT:    vpinsrd $1, %eax, %xmm3, %xmm3
108 ; ALL-NEXT:    vpextrd $2, %xmm0, %eax
109 ; ALL-NEXT:    tzcntl %eax, %eax
110 ; ALL-NEXT:    vpinsrd $2, %eax, %xmm3, %xmm3
111 ; ALL-NEXT:    vpextrd $3, %xmm0, %eax
112 ; ALL-NEXT:    tzcntl %eax, %eax
113 ; ALL-NEXT:    vpinsrd $3, %eax, %xmm3, %xmm0
114 ; ALL-NEXT:    vinserti128 $1, %xmm2, %ymm0, %ymm0
115 ; ALL-NEXT:    vinserti64x4 $1, %ymm1, %zmm0, %zmm0
116 ; ALL-NEXT:    retq
117   %out = call <16 x i32> @llvm.cttz.v16i32(<16 x i32> %in, i1 0)
118   ret <16 x i32> %out
119 }
120
121 define <16 x i32> @testv16i32u(<16 x i32> %in) nounwind {
122 ; ALL-LABEL: testv16i32u:
123 ; ALL:       ## BB#0:
124 ; ALL-NEXT:    vpxord %zmm1, %zmm1, %zmm1
125 ; ALL-NEXT:    vpsubd %zmm0, %zmm1, %zmm1
126 ; ALL-NEXT:    vpandd %zmm1, %zmm0, %zmm0
127 ; ALL-NEXT:    vplzcntd %zmm0, %zmm0
128 ; ALL-NEXT:    vpbroadcastd {{.*}}(%rip), %zmm1
129 ; ALL-NEXT:    vpsubd %zmm0, %zmm1, %zmm0
130 ; ALL-NEXT:    retq
131   %out = call <16 x i32> @llvm.cttz.v16i32(<16 x i32> %in, i1 -1)
132   ret <16 x i32> %out
133 }
134
135 define <32 x i16> @testv32i16(<32 x i16> %in) nounwind {
136 ; ALL-LABEL: testv32i16:
137 ; ALL:       ## BB#0:
138 ; ALL-NEXT:    vpxor %ymm2, %ymm2, %ymm2
139 ; ALL-NEXT:    vpsubw %ymm0, %ymm2, %ymm3
140 ; ALL-NEXT:    vpand %ymm3, %ymm0, %ymm0
141 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm3 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
142 ; ALL-NEXT:    vpsubw %ymm3, %ymm0, %ymm0
143 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm4 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
144 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm5
145 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm6 = [0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4]
146 ; ALL-NEXT:    vpshufb %ymm5, %ymm6, %ymm5
147 ; ALL-NEXT:    vpsrlw $4, %ymm0, %ymm0
148 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm0
149 ; ALL-NEXT:    vpshufb %ymm0, %ymm6, %ymm0
150 ; ALL-NEXT:    vpaddb %ymm5, %ymm0, %ymm0
151 ; ALL-NEXT:    vpsllw $8, %ymm0, %ymm5
152 ; ALL-NEXT:    vpaddb %ymm0, %ymm5, %ymm0
153 ; ALL-NEXT:    vpsrlw $8, %ymm0, %ymm0
154 ; ALL-NEXT:    vpsubw %ymm1, %ymm2, %ymm2
155 ; ALL-NEXT:    vpand %ymm2, %ymm1, %ymm1
156 ; ALL-NEXT:    vpsubw %ymm3, %ymm1, %ymm1
157 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm2
158 ; ALL-NEXT:    vpshufb %ymm2, %ymm6, %ymm2
159 ; ALL-NEXT:    vpsrlw $4, %ymm1, %ymm1
160 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm1
161 ; ALL-NEXT:    vpshufb %ymm1, %ymm6, %ymm1
162 ; ALL-NEXT:    vpaddb %ymm2, %ymm1, %ymm1
163 ; ALL-NEXT:    vpsllw $8, %ymm1, %ymm2
164 ; ALL-NEXT:    vpaddb %ymm1, %ymm2, %ymm1
165 ; ALL-NEXT:    vpsrlw $8, %ymm1, %ymm1
166 ; ALL-NEXT:    retq
167   %out = call <32 x i16> @llvm.cttz.v32i16(<32 x i16> %in, i1 0)
168   ret <32 x i16> %out
169 }
170
171 define <32 x i16> @testv32i16u(<32 x i16> %in) nounwind {
172 ; ALL-LABEL: testv32i16u:
173 ; ALL:       ## BB#0:
174 ; ALL-NEXT:    vpxor %ymm2, %ymm2, %ymm2
175 ; ALL-NEXT:    vpsubw %ymm0, %ymm2, %ymm3
176 ; ALL-NEXT:    vpand %ymm3, %ymm0, %ymm0
177 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm3 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
178 ; ALL-NEXT:    vpsubw %ymm3, %ymm0, %ymm0
179 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm4 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
180 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm5
181 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm6 = [0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4]
182 ; ALL-NEXT:    vpshufb %ymm5, %ymm6, %ymm5
183 ; ALL-NEXT:    vpsrlw $4, %ymm0, %ymm0
184 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm0
185 ; ALL-NEXT:    vpshufb %ymm0, %ymm6, %ymm0
186 ; ALL-NEXT:    vpaddb %ymm5, %ymm0, %ymm0
187 ; ALL-NEXT:    vpsllw $8, %ymm0, %ymm5
188 ; ALL-NEXT:    vpaddb %ymm0, %ymm5, %ymm0
189 ; ALL-NEXT:    vpsrlw $8, %ymm0, %ymm0
190 ; ALL-NEXT:    vpsubw %ymm1, %ymm2, %ymm2
191 ; ALL-NEXT:    vpand %ymm2, %ymm1, %ymm1
192 ; ALL-NEXT:    vpsubw %ymm3, %ymm1, %ymm1
193 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm2
194 ; ALL-NEXT:    vpshufb %ymm2, %ymm6, %ymm2
195 ; ALL-NEXT:    vpsrlw $4, %ymm1, %ymm1
196 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm1
197 ; ALL-NEXT:    vpshufb %ymm1, %ymm6, %ymm1
198 ; ALL-NEXT:    vpaddb %ymm2, %ymm1, %ymm1
199 ; ALL-NEXT:    vpsllw $8, %ymm1, %ymm2
200 ; ALL-NEXT:    vpaddb %ymm1, %ymm2, %ymm1
201 ; ALL-NEXT:    vpsrlw $8, %ymm1, %ymm1
202 ; ALL-NEXT:    retq
203   %out = call <32 x i16> @llvm.cttz.v32i16(<32 x i16> %in, i1 -1)
204   ret <32 x i16> %out
205 }
206
207 define <64 x i8> @testv64i8(<64 x i8> %in) nounwind {
208 ; ALL-LABEL: testv64i8:
209 ; ALL:       ## BB#0:
210 ; ALL-NEXT:    vpxor %ymm2, %ymm2, %ymm2
211 ; ALL-NEXT:    vpsubb %ymm0, %ymm2, %ymm3
212 ; ALL-NEXT:    vpand %ymm3, %ymm0, %ymm0
213 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm3 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
214 ; ALL-NEXT:    vpsubb %ymm3, %ymm0, %ymm0
215 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm4 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
216 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm5
217 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm6 = [0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4]
218 ; ALL-NEXT:    vpshufb %ymm5, %ymm6, %ymm5
219 ; ALL-NEXT:    vpsrlw $4, %ymm0, %ymm0
220 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm0
221 ; ALL-NEXT:    vpshufb %ymm0, %ymm6, %ymm0
222 ; ALL-NEXT:    vpaddb %ymm5, %ymm0, %ymm0
223 ; ALL-NEXT:    vpsubb %ymm1, %ymm2, %ymm2
224 ; ALL-NEXT:    vpand %ymm2, %ymm1, %ymm1
225 ; ALL-NEXT:    vpsubb %ymm3, %ymm1, %ymm1
226 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm2
227 ; ALL-NEXT:    vpshufb %ymm2, %ymm6, %ymm2
228 ; ALL-NEXT:    vpsrlw $4, %ymm1, %ymm1
229 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm1
230 ; ALL-NEXT:    vpshufb %ymm1, %ymm6, %ymm1
231 ; ALL-NEXT:    vpaddb %ymm2, %ymm1, %ymm1
232 ; ALL-NEXT:    retq
233   %out = call <64 x i8> @llvm.cttz.v64i8(<64 x i8> %in, i1 0)
234   ret <64 x i8> %out
235 }
236
237 define <64 x i8> @testv64i8u(<64 x i8> %in) nounwind {
238 ; ALL-LABEL: testv64i8u:
239 ; ALL:       ## BB#0:
240 ; ALL-NEXT:    vpxor %ymm2, %ymm2, %ymm2
241 ; ALL-NEXT:    vpsubb %ymm0, %ymm2, %ymm3
242 ; ALL-NEXT:    vpand %ymm3, %ymm0, %ymm0
243 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm3 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
244 ; ALL-NEXT:    vpsubb %ymm3, %ymm0, %ymm0
245 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm4 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
246 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm5
247 ; ALL-NEXT:    vmovdqa {{.*#+}} ymm6 = [0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4]
248 ; ALL-NEXT:    vpshufb %ymm5, %ymm6, %ymm5
249 ; ALL-NEXT:    vpsrlw $4, %ymm0, %ymm0
250 ; ALL-NEXT:    vpand %ymm4, %ymm0, %ymm0
251 ; ALL-NEXT:    vpshufb %ymm0, %ymm6, %ymm0
252 ; ALL-NEXT:    vpaddb %ymm5, %ymm0, %ymm0
253 ; ALL-NEXT:    vpsubb %ymm1, %ymm2, %ymm2
254 ; ALL-NEXT:    vpand %ymm2, %ymm1, %ymm1
255 ; ALL-NEXT:    vpsubb %ymm3, %ymm1, %ymm1
256 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm2
257 ; ALL-NEXT:    vpshufb %ymm2, %ymm6, %ymm2
258 ; ALL-NEXT:    vpsrlw $4, %ymm1, %ymm1
259 ; ALL-NEXT:    vpand %ymm4, %ymm1, %ymm1
260 ; ALL-NEXT:    vpshufb %ymm1, %ymm6, %ymm1
261 ; ALL-NEXT:    vpaddb %ymm2, %ymm1, %ymm1
262 ; ALL-NEXT:    retq
263   %out = call <64 x i8> @llvm.cttz.v64i8(<64 x i8> %in, i1 -1)
264   ret <64 x i8> %out
265 }
266
267 declare <8 x i64> @llvm.cttz.v8i64(<8 x i64>, i1)
268 declare <16 x i32> @llvm.cttz.v16i32(<16 x i32>, i1)
269 declare <32 x i16> @llvm.cttz.v32i16(<32 x i16>, i1)
270 declare <64 x i8> @llvm.cttz.v64i8(<64 x i8>, i1)