[x86] Restructure the parallel bitmath lowering of popcount into
[oota-llvm.git] / test / CodeGen / X86 / vector-popcnt-128.ll
1 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE2
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse3 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE3
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+ssse3 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSSE3
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+sse4.1 | FileCheck %s --check-prefix=ALL --check-prefix=SSE --check-prefix=SSE41
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX1
6 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=+avx2 | FileCheck %s --check-prefix=ALL --check-prefix=AVX --check-prefix=AVX2
7
8 target triple = "x86_64-unknown-unknown"
9
10 define <2 x i64> @testv2i64(<2 x i64> %in) {
11 ; SSE-LABEL: testv2i64:
12 ; SSE:       # BB#0:
13 ; SSE-NEXT:    movdqa %xmm0, %xmm1
14 ; SSE-NEXT:    psrlq $1, %xmm1
15 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
16 ; SSE-NEXT:    psubq %xmm1, %xmm0
17 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [3689348814741910323,3689348814741910323]
18 ; SSE-NEXT:    movdqa %xmm0, %xmm2
19 ; SSE-NEXT:    pand %xmm1, %xmm2
20 ; SSE-NEXT:    psrlq $2, %xmm0
21 ; SSE-NEXT:    pand %xmm1, %xmm0
22 ; SSE-NEXT:    paddq %xmm2, %xmm0
23 ; SSE-NEXT:    movdqa %xmm0, %xmm1
24 ; SSE-NEXT:    psrlq $4, %xmm1
25 ; SSE-NEXT:    paddq %xmm0, %xmm1
26 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
27 ; SSE-NEXT:    movdqa %xmm1, %xmm0
28 ; SSE-NEXT:    psllq $32, %xmm0
29 ; SSE-NEXT:    paddb %xmm1, %xmm0
30 ; SSE-NEXT:    movdqa %xmm0, %xmm1
31 ; SSE-NEXT:    psllq $16, %xmm1
32 ; SSE-NEXT:    paddb %xmm0, %xmm1
33 ; SSE-NEXT:    movdqa %xmm1, %xmm0
34 ; SSE-NEXT:    psllq $8, %xmm0
35 ; SSE-NEXT:    paddb %xmm1, %xmm0
36 ; SSE-NEXT:    psrlq $56, %xmm0
37 ; SSE-NEXT:    retq
38 ;
39 ; AVX-LABEL: testv2i64:
40 ; AVX:       # BB#0:
41 ; AVX-NEXT:    vpsrlq $1, %xmm0, %xmm1
42 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
43 ; AVX-NEXT:    vpsubq %xmm1, %xmm0, %xmm0
44 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [3689348814741910323,3689348814741910323]
45 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm2
46 ; AVX-NEXT:    vpsrlq $2, %xmm0, %xmm0
47 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
48 ; AVX-NEXT:    vpaddq %xmm0, %xmm2, %xmm0
49 ; AVX-NEXT:    vpsrlq $4, %xmm0, %xmm1
50 ; AVX-NEXT:    vpaddq %xmm1, %xmm0, %xmm0
51 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
52 ; AVX-NEXT:    vpsllq $32, %xmm0, %xmm1
53 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
54 ; AVX-NEXT:    vpsllq $16, %xmm0, %xmm1
55 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
56 ; AVX-NEXT:    vpsllq $8, %xmm0, %xmm1
57 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
58 ; AVX-NEXT:    vpsrlq $56, %xmm0, %xmm0
59 ; AVX-NEXT:    retq
60   %out = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %in)
61   ret <2 x i64> %out
62 }
63
64 define <4 x i32> @testv4i32(<4 x i32> %in) {
65 ; SSE-LABEL: testv4i32:
66 ; SSE:       # BB#0:
67 ; SSE-NEXT:    movdqa %xmm0, %xmm1
68 ; SSE-NEXT:    psrld $1, %xmm1
69 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
70 ; SSE-NEXT:    psubd %xmm1, %xmm0
71 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [858993459,858993459,858993459,858993459]
72 ; SSE-NEXT:    movdqa %xmm0, %xmm2
73 ; SSE-NEXT:    pand %xmm1, %xmm2
74 ; SSE-NEXT:    psrld $2, %xmm0
75 ; SSE-NEXT:    pand %xmm1, %xmm0
76 ; SSE-NEXT:    paddd %xmm2, %xmm0
77 ; SSE-NEXT:    movdqa %xmm0, %xmm1
78 ; SSE-NEXT:    psrld $4, %xmm1
79 ; SSE-NEXT:    paddd %xmm0, %xmm1
80 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
81 ; SSE-NEXT:    movdqa %xmm1, %xmm2
82 ; SSE-NEXT:    psllq $16, %xmm2
83 ; SSE-NEXT:    paddb %xmm1, %xmm2
84 ; SSE-NEXT:    movdqa %xmm2, %xmm0
85 ; SSE-NEXT:    psllq $8, %xmm0
86 ; SSE-NEXT:    paddb %xmm2, %xmm0
87 ; SSE-NEXT:    psrld $24, %xmm0
88 ; SSE-NEXT:    retq
89 ;
90 ; AVX1-LABEL: testv4i32:
91 ; AVX1:       # BB#0:
92 ; AVX1-NEXT:    vpsrld $1, %xmm0, %xmm1
93 ; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
94 ; AVX1-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
95 ; AVX1-NEXT:    vmovdqa {{.*#+}} xmm1 = [858993459,858993459,858993459,858993459]
96 ; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm2
97 ; AVX1-NEXT:    vpsrld $2, %xmm0, %xmm0
98 ; AVX1-NEXT:    vpand %xmm1, %xmm0, %xmm0
99 ; AVX1-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
100 ; AVX1-NEXT:    vpsrld $4, %xmm0, %xmm1
101 ; AVX1-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
102 ; AVX1-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
103 ; AVX1-NEXT:    vpsllq $16, %xmm0, %xmm1
104 ; AVX1-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
105 ; AVX1-NEXT:    vpsllq $8, %xmm0, %xmm1
106 ; AVX1-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
107 ; AVX1-NEXT:    vpsrld $24, %xmm0, %xmm0
108 ; AVX1-NEXT:    retq
109 ;
110 ; AVX2-LABEL: testv4i32:
111 ; AVX2:       # BB#0:
112 ; AVX2-NEXT:    vpsrld $1, %xmm0, %xmm1
113 ; AVX2-NEXT:    vpbroadcastd {{.*}}(%rip), %xmm2
114 ; AVX2-NEXT:    vpand %xmm2, %xmm1, %xmm1
115 ; AVX2-NEXT:    vpsubd %xmm1, %xmm0, %xmm0
116 ; AVX2-NEXT:    vpbroadcastd {{.*}}(%rip), %xmm1
117 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm2
118 ; AVX2-NEXT:    vpsrld $2, %xmm0, %xmm0
119 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
120 ; AVX2-NEXT:    vpaddd %xmm0, %xmm2, %xmm0
121 ; AVX2-NEXT:    vpsrld $4, %xmm0, %xmm1
122 ; AVX2-NEXT:    vpaddd %xmm1, %xmm0, %xmm0
123 ; AVX2-NEXT:    vpbroadcastd {{.*}}(%rip), %xmm1
124 ; AVX2-NEXT:    vpand %xmm1, %xmm0, %xmm0
125 ; AVX2-NEXT:    vpsllq $16, %xmm0, %xmm1
126 ; AVX2-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
127 ; AVX2-NEXT:    vpsllq $8, %xmm0, %xmm1
128 ; AVX2-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
129 ; AVX2-NEXT:    vpsrld $24, %xmm0, %xmm0
130 ; AVX2-NEXT:    retq
131   %out = call <4 x i32> @llvm.ctpop.v4i32(<4 x i32> %in)
132   ret <4 x i32> %out
133 }
134
135 define <8 x i16> @testv8i16(<8 x i16> %in) {
136 ; SSE-LABEL: testv8i16:
137 ; SSE:       # BB#0:
138 ; SSE-NEXT:    movdqa %xmm0, %xmm1
139 ; SSE-NEXT:    psrlw $1, %xmm1
140 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
141 ; SSE-NEXT:    psubw %xmm1, %xmm0
142 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [13107,13107,13107,13107,13107,13107,13107,13107]
143 ; SSE-NEXT:    movdqa %xmm0, %xmm2
144 ; SSE-NEXT:    pand %xmm1, %xmm2
145 ; SSE-NEXT:    psrlw $2, %xmm0
146 ; SSE-NEXT:    pand %xmm1, %xmm0
147 ; SSE-NEXT:    paddw %xmm2, %xmm0
148 ; SSE-NEXT:    movdqa %xmm0, %xmm1
149 ; SSE-NEXT:    psrlw $4, %xmm1
150 ; SSE-NEXT:    paddw %xmm0, %xmm1
151 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
152 ; SSE-NEXT:    movdqa %xmm1, %xmm0
153 ; SSE-NEXT:    psllq $8, %xmm0
154 ; SSE-NEXT:    paddb %xmm1, %xmm0
155 ; SSE-NEXT:    psrlw $8, %xmm0
156 ; SSE-NEXT:    retq
157 ;
158 ; AVX-LABEL: testv8i16:
159 ; AVX:       # BB#0:
160 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm1
161 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
162 ; AVX-NEXT:    vpsubw %xmm1, %xmm0, %xmm0
163 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [13107,13107,13107,13107,13107,13107,13107,13107]
164 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm2
165 ; AVX-NEXT:    vpsrlw $2, %xmm0, %xmm0
166 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
167 ; AVX-NEXT:    vpaddw %xmm0, %xmm2, %xmm0
168 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm1
169 ; AVX-NEXT:    vpaddw %xmm1, %xmm0, %xmm0
170 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
171 ; AVX-NEXT:    vpsllq $8, %xmm0, %xmm1
172 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
173 ; AVX-NEXT:    vpsrlw $8, %xmm0, %xmm0
174 ; AVX-NEXT:    retq
175   %out = call <8 x i16> @llvm.ctpop.v8i16(<8 x i16> %in)
176   ret <8 x i16> %out
177 }
178
179 define <16 x i8> @testv16i8(<16 x i8> %in) {
180 ; SSE-LABEL: testv16i8:
181 ; SSE:       # BB#0:
182 ; SSE-NEXT:    movdqa %xmm0, %xmm1
183 ; SSE-NEXT:    psrlw $1, %xmm1
184 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
185 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm1
186 ; SSE-NEXT:    psubb %xmm1, %xmm0
187 ; SSE-NEXT:    movdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
188 ; SSE-NEXT:    movdqa %xmm0, %xmm2
189 ; SSE-NEXT:    pand %xmm1, %xmm2
190 ; SSE-NEXT:    psrlw $2, %xmm0
191 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
192 ; SSE-NEXT:    pand %xmm1, %xmm0
193 ; SSE-NEXT:    paddb %xmm2, %xmm0
194 ; SSE-NEXT:    movdqa %xmm0, %xmm1
195 ; SSE-NEXT:    psrlw $4, %xmm1
196 ; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
197 ; SSE-NEXT:    pand %xmm2, %xmm1
198 ; SSE-NEXT:    paddb %xmm0, %xmm1
199 ; SSE-NEXT:    pand %xmm2, %xmm1
200 ; SSE-NEXT:    movdqa %xmm1, %xmm0
201 ; SSE-NEXT:    retq
202 ;
203 ; AVX-LABEL: testv16i8:
204 ; AVX:       # BB#0:
205 ; AVX-NEXT:    vpsrlw $1, %xmm0, %xmm1
206 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
207 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm1, %xmm1
208 ; AVX-NEXT:    vpsubb %xmm1, %xmm0, %xmm0
209 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm1 = [51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51]
210 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm2
211 ; AVX-NEXT:    vpsrlw $2, %xmm0, %xmm0
212 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
213 ; AVX-NEXT:    vpand %xmm1, %xmm0, %xmm0
214 ; AVX-NEXT:    vpaddb %xmm0, %xmm2, %xmm0
215 ; AVX-NEXT:    vpsrlw $4, %xmm0, %xmm1
216 ; AVX-NEXT:    vmovdqa {{.*#+}} xmm2 = [15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15]
217 ; AVX-NEXT:    vpand %xmm2, %xmm1, %xmm1
218 ; AVX-NEXT:    vpaddb %xmm1, %xmm0, %xmm0
219 ; AVX-NEXT:    vpand %xmm2, %xmm0, %xmm0
220 ; AVX-NEXT:    retq
221   %out = call <16 x i8> @llvm.ctpop.v16i8(<16 x i8> %in)
222   ret <16 x i8> %out
223 }
224
225 declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
226 declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>)
227 declare <8 x i16> @llvm.ctpop.v8i16(<8 x i16>)
228 declare <16 x i8> @llvm.ctpop.v16i8(<16 x i8>)