[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / X86 / vector-pcmp.ll
blob89eaad82fd2273a76d9c2492cc4b508444edc3a6
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=CHECK --check-prefix=SSE --check-prefix=SSE2
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE --check-prefix=SSE42
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX2
7 ; Lower common integer comparisons such as 'isPositive' efficiently:
8 ; https://llvm.org/bugs/show_bug.cgi?id=26701
10 define <16 x i8> @test_pcmpgtb(<16 x i8> %x) {
11 ; SSE-LABEL: test_pcmpgtb:
12 ; SSE:       # %bb.0:
13 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
14 ; SSE-NEXT:    pcmpgtb %xmm1, %xmm0
15 ; SSE-NEXT:    retq
17 ; AVX-LABEL: test_pcmpgtb:
18 ; AVX:       # %bb.0:
19 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
20 ; AVX-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
21 ; AVX-NEXT:    retq
22   %sign = ashr <16 x i8> %x, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
23   %not = xor <16 x i8> %sign, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
24   ret <16 x i8> %not
27 define <8 x i16> @test_pcmpgtw(<8 x i16> %x) {
28 ; SSE-LABEL: test_pcmpgtw:
29 ; SSE:       # %bb.0:
30 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
31 ; SSE-NEXT:    pcmpgtw %xmm1, %xmm0
32 ; SSE-NEXT:    retq
34 ; AVX-LABEL: test_pcmpgtw:
35 ; AVX:       # %bb.0:
36 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
37 ; AVX-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
38 ; AVX-NEXT:    retq
39   %sign = ashr <8 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
40   %not = xor <8 x i16> %sign, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
41   ret <8 x i16> %not
44 define <4 x i32> @test_pcmpgtd(<4 x i32> %x) {
45 ; SSE-LABEL: test_pcmpgtd:
46 ; SSE:       # %bb.0:
47 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm1
48 ; SSE-NEXT:    pcmpgtd %xmm1, %xmm0
49 ; SSE-NEXT:    retq
51 ; AVX-LABEL: test_pcmpgtd:
52 ; AVX:       # %bb.0:
53 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
54 ; AVX-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
55 ; AVX-NEXT:    retq
56   %sign = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>
57   %not = xor <4 x i32> %sign, <i32 -1, i32 -1, i32 -1, i32 -1>
58   ret <4 x i32> %not
61 define <2 x i64> @test_pcmpgtq(<2 x i64> %x) {
62 ; SSE2-LABEL: test_pcmpgtq:
63 ; SSE2:       # %bb.0:
64 ; SSE2-NEXT:    psrad $31, %xmm0
65 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
66 ; SSE2-NEXT:    pcmpeqd %xmm0, %xmm0
67 ; SSE2-NEXT:    pxor %xmm1, %xmm0
68 ; SSE2-NEXT:    retq
70 ; SSE42-LABEL: test_pcmpgtq:
71 ; SSE42:       # %bb.0:
72 ; SSE42-NEXT:    pcmpeqd %xmm1, %xmm1
73 ; SSE42-NEXT:    pcmpgtq %xmm1, %xmm0
74 ; SSE42-NEXT:    retq
76 ; AVX-LABEL: test_pcmpgtq:
77 ; AVX:       # %bb.0:
78 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm1, %xmm1
79 ; AVX-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
80 ; AVX-NEXT:    retq
81   %sign = ashr <2 x i64> %x, <i64 63, i64 63>
82   %not = xor <2 x i64> %sign, <i64 -1, i64 -1>
83   ret <2 x i64> %not
86 define <1 x i128> @test_strange_type(<1 x i128> %x) {
87 ; CHECK-LABEL: test_strange_type:
88 ; CHECK:       # %bb.0:
89 ; CHECK-NEXT:    movq %rsi, %rax
90 ; CHECK-NEXT:    sarq $63, %rax
91 ; CHECK-NEXT:    notq %rax
92 ; CHECK-NEXT:    movq %rax, %rdx
93 ; CHECK-NEXT:    retq
94   %sign = ashr <1 x i128> %x, <i128 127>
95   %not = xor <1 x i128> %sign, <i128 -1>
96   ret <1 x i128> %not
99 define <32 x i8> @test_pcmpgtb_256(<32 x i8> %x) {
100 ; SSE-LABEL: test_pcmpgtb_256:
101 ; SSE:       # %bb.0:
102 ; SSE-NEXT:    pcmpeqd %xmm2, %xmm2
103 ; SSE-NEXT:    pcmpgtb %xmm2, %xmm0
104 ; SSE-NEXT:    pcmpgtb %xmm2, %xmm1
105 ; SSE-NEXT:    retq
107 ; AVX1-LABEL: test_pcmpgtb_256:
108 ; AVX1:       # %bb.0:
109 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
110 ; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
111 ; AVX1-NEXT:    vpcmpgtb %xmm1, %xmm2, %xmm1
112 ; AVX1-NEXT:    vpcmpgtb %xmm0, %xmm2, %xmm0
113 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
114 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
115 ; AVX1-NEXT:    vcmptrueps %ymm1, %ymm1, %ymm1
116 ; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
117 ; AVX1-NEXT:    retq
119 ; AVX2-LABEL: test_pcmpgtb_256:
120 ; AVX2:       # %bb.0:
121 ; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
122 ; AVX2-NEXT:    vpcmpgtb %ymm1, %ymm0, %ymm0
123 ; AVX2-NEXT:    retq
124   %sign = ashr <32 x i8> %x, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7>
125   %not = xor <32 x i8> %sign, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
126   ret <32 x i8> %not
129 define <16 x i16> @test_pcmpgtw_256(<16 x i16> %x) {
130 ; SSE-LABEL: test_pcmpgtw_256:
131 ; SSE:       # %bb.0:
132 ; SSE-NEXT:    pcmpeqd %xmm2, %xmm2
133 ; SSE-NEXT:    pcmpgtw %xmm2, %xmm0
134 ; SSE-NEXT:    pcmpgtw %xmm2, %xmm1
135 ; SSE-NEXT:    retq
137 ; AVX1-LABEL: test_pcmpgtw_256:
138 ; AVX1:       # %bb.0:
139 ; AVX1-NEXT:    vpsraw $15, %xmm0, %xmm1
140 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
141 ; AVX1-NEXT:    vpsraw $15, %xmm0, %xmm0
142 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
143 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
144 ; AVX1-NEXT:    vcmptrueps %ymm1, %ymm1, %ymm1
145 ; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
146 ; AVX1-NEXT:    retq
148 ; AVX2-LABEL: test_pcmpgtw_256:
149 ; AVX2:       # %bb.0:
150 ; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
151 ; AVX2-NEXT:    vpcmpgtw %ymm1, %ymm0, %ymm0
152 ; AVX2-NEXT:    retq
153   %sign = ashr <16 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
154   %not = xor <16 x i16> %sign, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
155   ret <16 x i16> %not
158 define <8 x i32> @test_pcmpgtd_256(<8 x i32> %x) {
159 ; SSE-LABEL: test_pcmpgtd_256:
160 ; SSE:       # %bb.0:
161 ; SSE-NEXT:    pcmpeqd %xmm2, %xmm2
162 ; SSE-NEXT:    pcmpgtd %xmm2, %xmm0
163 ; SSE-NEXT:    pcmpgtd %xmm2, %xmm1
164 ; SSE-NEXT:    retq
166 ; AVX1-LABEL: test_pcmpgtd_256:
167 ; AVX1:       # %bb.0:
168 ; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm1
169 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
170 ; AVX1-NEXT:    vpsrad $31, %xmm0, %xmm0
171 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
172 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
173 ; AVX1-NEXT:    vcmptrueps %ymm1, %ymm1, %ymm1
174 ; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
175 ; AVX1-NEXT:    retq
177 ; AVX2-LABEL: test_pcmpgtd_256:
178 ; AVX2:       # %bb.0:
179 ; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
180 ; AVX2-NEXT:    vpcmpgtd %ymm1, %ymm0, %ymm0
181 ; AVX2-NEXT:    retq
182   %sign = ashr <8 x i32> %x, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
183   %not = xor <8 x i32> %sign, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
184   ret <8 x i32> %not
187 define <4 x i64> @test_pcmpgtq_256(<4 x i64> %x) {
188 ; SSE2-LABEL: test_pcmpgtq_256:
189 ; SSE2:       # %bb.0:
190 ; SSE2-NEXT:    psrad $31, %xmm1
191 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm1[1,1,3,3]
192 ; SSE2-NEXT:    psrad $31, %xmm0
193 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[1,1,3,3]
194 ; SSE2-NEXT:    pcmpeqd %xmm2, %xmm2
195 ; SSE2-NEXT:    pxor %xmm2, %xmm0
196 ; SSE2-NEXT:    pxor %xmm2, %xmm1
197 ; SSE2-NEXT:    retq
199 ; SSE42-LABEL: test_pcmpgtq_256:
200 ; SSE42:       # %bb.0:
201 ; SSE42-NEXT:    pcmpeqd %xmm2, %xmm2
202 ; SSE42-NEXT:    pcmpgtq %xmm2, %xmm0
203 ; SSE42-NEXT:    pcmpgtq %xmm2, %xmm1
204 ; SSE42-NEXT:    retq
206 ; AVX1-LABEL: test_pcmpgtq_256:
207 ; AVX1:       # %bb.0:
208 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
209 ; AVX1-NEXT:    vpxor %xmm2, %xmm2, %xmm2
210 ; AVX1-NEXT:    vpcmpgtq %xmm1, %xmm2, %xmm1
211 ; AVX1-NEXT:    vpcmpgtq %xmm0, %xmm2, %xmm0
212 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
213 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
214 ; AVX1-NEXT:    vcmptrueps %ymm1, %ymm1, %ymm1
215 ; AVX1-NEXT:    vxorps %ymm1, %ymm0, %ymm0
216 ; AVX1-NEXT:    retq
218 ; AVX2-LABEL: test_pcmpgtq_256:
219 ; AVX2:       # %bb.0:
220 ; AVX2-NEXT:    vpcmpeqd %ymm1, %ymm1, %ymm1
221 ; AVX2-NEXT:    vpcmpgtq %ymm1, %ymm0, %ymm0
222 ; AVX2-NEXT:    retq
223   %sign = ashr <4 x i64> %x, <i64 63, i64 63, i64 63, i64 63>
224   %not = xor <4 x i64> %sign, <i64 -1, i64 -1, i64 -1, i64 -1>
225   ret <4 x i64> %not
228 define <16 x i8> @cmpeq_zext_v16i8(<16 x i8> %a, <16 x i8> %b) {
229 ; SSE-LABEL: cmpeq_zext_v16i8:
230 ; SSE:       # %bb.0:
231 ; SSE-NEXT:    pcmpeqb %xmm1, %xmm0
232 ; SSE-NEXT:    pand {{.*}}(%rip), %xmm0
233 ; SSE-NEXT:    retq
235 ; AVX-LABEL: cmpeq_zext_v16i8:
236 ; AVX:       # %bb.0:
237 ; AVX-NEXT:    vpcmpeqb %xmm1, %xmm0, %xmm0
238 ; AVX-NEXT:    vpand {{.*}}(%rip), %xmm0, %xmm0
239 ; AVX-NEXT:    retq
240   %cmp = icmp eq <16 x i8> %a, %b
241   %zext = zext <16 x i1> %cmp to <16 x i8>
242   ret <16 x i8> %zext
245 define <16 x i16> @cmpeq_zext_v16i16(<16 x i16> %a, <16 x i16> %b) {
246 ; SSE-LABEL: cmpeq_zext_v16i16:
247 ; SSE:       # %bb.0:
248 ; SSE-NEXT:    pcmpeqw %xmm2, %xmm0
249 ; SSE-NEXT:    psrlw $15, %xmm0
250 ; SSE-NEXT:    pcmpeqw %xmm3, %xmm1
251 ; SSE-NEXT:    psrlw $15, %xmm1
252 ; SSE-NEXT:    retq
254 ; AVX1-LABEL: cmpeq_zext_v16i16:
255 ; AVX1:       # %bb.0:
256 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
257 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
258 ; AVX1-NEXT:    vpcmpeqw %xmm2, %xmm3, %xmm2
259 ; AVX1-NEXT:    vpcmpeqw %xmm1, %xmm0, %xmm0
260 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
261 ; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
262 ; AVX1-NEXT:    retq
264 ; AVX2-LABEL: cmpeq_zext_v16i16:
265 ; AVX2:       # %bb.0:
266 ; AVX2-NEXT:    vpcmpeqw %ymm1, %ymm0, %ymm0
267 ; AVX2-NEXT:    vpsrlw $15, %ymm0, %ymm0
268 ; AVX2-NEXT:    retq
269   %cmp = icmp eq <16 x i16> %a, %b
270   %zext = zext <16 x i1> %cmp to <16 x i16>
271   ret <16 x i16> %zext
274 define <4 x i32> @cmpeq_zext_v4i32(<4 x i32> %a, <4 x i32> %b) {
275 ; SSE-LABEL: cmpeq_zext_v4i32:
276 ; SSE:       # %bb.0:
277 ; SSE-NEXT:    pcmpeqd %xmm1, %xmm0
278 ; SSE-NEXT:    psrld $31, %xmm0
279 ; SSE-NEXT:    retq
281 ; AVX-LABEL: cmpeq_zext_v4i32:
282 ; AVX:       # %bb.0:
283 ; AVX-NEXT:    vpcmpeqd %xmm1, %xmm0, %xmm0
284 ; AVX-NEXT:    vpsrld $31, %xmm0, %xmm0
285 ; AVX-NEXT:    retq
286   %cmp = icmp eq <4 x i32> %a, %b
287   %zext = zext <4 x i1> %cmp to <4 x i32>
288   ret <4 x i32> %zext
291 define <4 x i64> @cmpeq_zext_v4i64(<4 x i64> %a, <4 x i64> %b) {
292 ; SSE2-LABEL: cmpeq_zext_v4i64:
293 ; SSE2:       # %bb.0:
294 ; SSE2-NEXT:    pcmpeqd %xmm2, %xmm0
295 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm0[1,0,3,2]
296 ; SSE2-NEXT:    movdqa {{.*#+}} xmm4 = [1,1]
297 ; SSE2-NEXT:    pand %xmm4, %xmm2
298 ; SSE2-NEXT:    pand %xmm2, %xmm0
299 ; SSE2-NEXT:    pcmpeqd %xmm3, %xmm1
300 ; SSE2-NEXT:    pshufd {{.*#+}} xmm2 = xmm1[1,0,3,2]
301 ; SSE2-NEXT:    pand %xmm4, %xmm2
302 ; SSE2-NEXT:    pand %xmm2, %xmm1
303 ; SSE2-NEXT:    retq
305 ; SSE42-LABEL: cmpeq_zext_v4i64:
306 ; SSE42:       # %bb.0:
307 ; SSE42-NEXT:    pcmpeqq %xmm2, %xmm0
308 ; SSE42-NEXT:    psrlq $63, %xmm0
309 ; SSE42-NEXT:    pcmpeqq %xmm3, %xmm1
310 ; SSE42-NEXT:    psrlq $63, %xmm1
311 ; SSE42-NEXT:    retq
313 ; AVX1-LABEL: cmpeq_zext_v4i64:
314 ; AVX1:       # %bb.0:
315 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
316 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
317 ; AVX1-NEXT:    vpcmpeqq %xmm2, %xmm3, %xmm2
318 ; AVX1-NEXT:    vpcmpeqq %xmm1, %xmm0, %xmm0
319 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
320 ; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
321 ; AVX1-NEXT:    retq
323 ; AVX2-LABEL: cmpeq_zext_v4i64:
324 ; AVX2:       # %bb.0:
325 ; AVX2-NEXT:    vpcmpeqq %ymm1, %ymm0, %ymm0
326 ; AVX2-NEXT:    vpsrlq $63, %ymm0, %ymm0
327 ; AVX2-NEXT:    retq
328   %cmp = icmp eq <4 x i64> %a, %b
329   %zext = zext <4 x i1> %cmp to <4 x i64>
330   ret <4 x i64> %zext
333 define <32 x i8> @cmpgt_zext_v32i8(<32 x i8> %a, <32 x i8> %b) {
334 ; SSE-LABEL: cmpgt_zext_v32i8:
335 ; SSE:       # %bb.0:
336 ; SSE-NEXT:    pcmpgtb %xmm2, %xmm0
337 ; SSE-NEXT:    movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
338 ; SSE-NEXT:    pand %xmm2, %xmm0
339 ; SSE-NEXT:    pcmpgtb %xmm3, %xmm1
340 ; SSE-NEXT:    pand %xmm2, %xmm1
341 ; SSE-NEXT:    retq
343 ; AVX1-LABEL: cmpgt_zext_v32i8:
344 ; AVX1:       # %bb.0:
345 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
346 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
347 ; AVX1-NEXT:    vpcmpgtb %xmm2, %xmm3, %xmm2
348 ; AVX1-NEXT:    vpcmpgtb %xmm1, %xmm0, %xmm0
349 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
350 ; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
351 ; AVX1-NEXT:    retq
353 ; AVX2-LABEL: cmpgt_zext_v32i8:
354 ; AVX2:       # %bb.0:
355 ; AVX2-NEXT:    vpcmpgtb %ymm1, %ymm0, %ymm0
356 ; AVX2-NEXT:    vpand {{.*}}(%rip), %ymm0, %ymm0
357 ; AVX2-NEXT:    retq
358   %cmp = icmp sgt <32 x i8> %a, %b
359   %zext = zext <32 x i1> %cmp to <32 x i8>
360   ret <32 x i8> %zext
363 define <8 x i16> @cmpgt_zext_v8i16(<8 x i16> %a, <8 x i16> %b) {
364 ; SSE-LABEL: cmpgt_zext_v8i16:
365 ; SSE:       # %bb.0:
366 ; SSE-NEXT:    pcmpgtw %xmm1, %xmm0
367 ; SSE-NEXT:    psrlw $15, %xmm0
368 ; SSE-NEXT:    retq
370 ; AVX-LABEL: cmpgt_zext_v8i16:
371 ; AVX:       # %bb.0:
372 ; AVX-NEXT:    vpcmpgtw %xmm1, %xmm0, %xmm0
373 ; AVX-NEXT:    vpsrlw $15, %xmm0, %xmm0
374 ; AVX-NEXT:    retq
375   %cmp = icmp sgt <8 x i16> %a, %b
376   %zext = zext <8 x i1> %cmp to <8 x i16>
377   ret <8 x i16> %zext
380 define <8 x i32> @cmpgt_zext_v8i32(<8 x i32> %a, <8 x i32> %b) {
381 ; SSE-LABEL: cmpgt_zext_v8i32:
382 ; SSE:       # %bb.0:
383 ; SSE-NEXT:    pcmpgtd %xmm2, %xmm0
384 ; SSE-NEXT:    psrld $31, %xmm0
385 ; SSE-NEXT:    pcmpgtd %xmm3, %xmm1
386 ; SSE-NEXT:    psrld $31, %xmm1
387 ; SSE-NEXT:    retq
389 ; AVX1-LABEL: cmpgt_zext_v8i32:
390 ; AVX1:       # %bb.0:
391 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm2
392 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm3
393 ; AVX1-NEXT:    vpcmpgtd %xmm2, %xmm3, %xmm2
394 ; AVX1-NEXT:    vpcmpgtd %xmm1, %xmm0, %xmm0
395 ; AVX1-NEXT:    vinsertf128 $1, %xmm2, %ymm0, %ymm0
396 ; AVX1-NEXT:    vandps {{.*}}(%rip), %ymm0, %ymm0
397 ; AVX1-NEXT:    retq
399 ; AVX2-LABEL: cmpgt_zext_v8i32:
400 ; AVX2:       # %bb.0:
401 ; AVX2-NEXT:    vpcmpgtd %ymm1, %ymm0, %ymm0
402 ; AVX2-NEXT:    vpsrld $31, %ymm0, %ymm0
403 ; AVX2-NEXT:    retq
404   %cmp = icmp sgt <8 x i32> %a, %b
405   %zext = zext <8 x i1> %cmp to <8 x i32>
406   ret <8 x i32> %zext
409 define <2 x i64> @cmpgt_zext_v2i64(<2 x i64> %a, <2 x i64> %b) {
410 ; SSE2-LABEL: cmpgt_zext_v2i64:
411 ; SSE2:       # %bb.0:
412 ; SSE2-NEXT:    movdqa {{.*#+}} xmm2 = [2147483648,2147483648]
413 ; SSE2-NEXT:    pxor %xmm2, %xmm1
414 ; SSE2-NEXT:    pxor %xmm2, %xmm0
415 ; SSE2-NEXT:    movdqa %xmm0, %xmm2
416 ; SSE2-NEXT:    pcmpgtd %xmm1, %xmm2
417 ; SSE2-NEXT:    pcmpeqd %xmm1, %xmm0
418 ; SSE2-NEXT:    pshufd {{.*#+}} xmm1 = xmm0[1,1,3,3]
419 ; SSE2-NEXT:    pand %xmm2, %xmm1
420 ; SSE2-NEXT:    pshufd {{.*#+}} xmm0 = xmm2[1,1,3,3]
421 ; SSE2-NEXT:    por %xmm1, %xmm0
422 ; SSE2-NEXT:    pand {{.*}}(%rip), %xmm0
423 ; SSE2-NEXT:    retq
425 ; SSE42-LABEL: cmpgt_zext_v2i64:
426 ; SSE42:       # %bb.0:
427 ; SSE42-NEXT:    pcmpgtq %xmm1, %xmm0
428 ; SSE42-NEXT:    psrlq $63, %xmm0
429 ; SSE42-NEXT:    retq
431 ; AVX-LABEL: cmpgt_zext_v2i64:
432 ; AVX:       # %bb.0:
433 ; AVX-NEXT:    vpcmpgtq %xmm1, %xmm0, %xmm0
434 ; AVX-NEXT:    vpsrlq $63, %xmm0, %xmm0
435 ; AVX-NEXT:    retq
436   %cmp = icmp sgt <2 x i64> %a, %b
437   %zext = zext <2 x i1> %cmp to <2 x i64>
438   ret <2 x i64> %zext
441 ; Test that we optimize a zext of a vector setcc ne zero where all bits but the
442 ; lsb are known to be zero.
443 define <8 x i32> @cmpne_knownzeros_zext_v8i16_v8i32(<8 x i16> %x) {
444 ; SSE2-LABEL: cmpne_knownzeros_zext_v8i16_v8i32:
445 ; SSE2:       # %bb.0:
446 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
447 ; SSE2-NEXT:    psrlw $15, %xmm1
448 ; SSE2-NEXT:    pxor %xmm2, %xmm2
449 ; SSE2-NEXT:    movdqa %xmm1, %xmm0
450 ; SSE2-NEXT:    punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3]
451 ; SSE2-NEXT:    punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm2[4],xmm1[5],xmm2[5],xmm1[6],xmm2[6],xmm1[7],xmm2[7]
452 ; SSE2-NEXT:    retq
454 ; SSE42-LABEL: cmpne_knownzeros_zext_v8i16_v8i32:
455 ; SSE42:       # %bb.0:
456 ; SSE42-NEXT:    psrlw $15, %xmm0
457 ; SSE42-NEXT:    pmovzxwd {{.*#+}} xmm2 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
458 ; SSE42-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,0,1]
459 ; SSE42-NEXT:    pmovzxwd {{.*#+}} xmm1 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
460 ; SSE42-NEXT:    movdqa %xmm2, %xmm0
461 ; SSE42-NEXT:    retq
463 ; AVX1-LABEL: cmpne_knownzeros_zext_v8i16_v8i32:
464 ; AVX1:       # %bb.0:
465 ; AVX1-NEXT:    vpsrlw $15, %xmm0, %xmm0
466 ; AVX1-NEXT:    vpxor %xmm1, %xmm1, %xmm1
467 ; AVX1-NEXT:    vpunpckhwd {{.*#+}} xmm1 = xmm0[4],xmm1[4],xmm0[5],xmm1[5],xmm0[6],xmm1[6],xmm0[7],xmm1[7]
468 ; AVX1-NEXT:    vpmovzxwd {{.*#+}} xmm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero
469 ; AVX1-NEXT:    vinsertf128 $1, %xmm1, %ymm0, %ymm0
470 ; AVX1-NEXT:    retq
472 ; AVX2-LABEL: cmpne_knownzeros_zext_v8i16_v8i32:
473 ; AVX2:       # %bb.0:
474 ; AVX2-NEXT:    vpsrlw $15, %xmm0, %xmm0
475 ; 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
476 ; AVX2-NEXT:    retq
477   %a = lshr <8 x i16> %x, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15>
478   %b = icmp ne <8 x i16> %a, zeroinitializer
479   %c = zext <8 x i1> %b to <8 x i32>
480   ret <8 x i32> %c
483 define <8 x i32> @cmpne_knownzeros_zext_v8i32_v8i32(<8 x i32> %x) {
484 ; SSE-LABEL: cmpne_knownzeros_zext_v8i32_v8i32:
485 ; SSE:       # %bb.0:
486 ; SSE-NEXT:    psrld $31, %xmm0
487 ; SSE-NEXT:    psrld $31, %xmm1
488 ; SSE-NEXT:    retq
490 ; AVX1-LABEL: cmpne_knownzeros_zext_v8i32_v8i32:
491 ; AVX1:       # %bb.0:
492 ; AVX1-NEXT:    vpsrld $31, %xmm0, %xmm1
493 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
494 ; AVX1-NEXT:    vpsrld $31, %xmm0, %xmm0
495 ; AVX1-NEXT:    vinsertf128 $1, %xmm0, %ymm1, %ymm0
496 ; AVX1-NEXT:    retq
498 ; AVX2-LABEL: cmpne_knownzeros_zext_v8i32_v8i32:
499 ; AVX2:       # %bb.0:
500 ; AVX2-NEXT:    vpsrld $31, %ymm0, %ymm0
501 ; AVX2-NEXT:    retq
502   %a = lshr <8 x i32> %x, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
503   %b = icmp ne <8 x i32> %a, zeroinitializer
504   %c = zext <8 x i1> %b to <8 x i32>
505   ret <8 x i32> %c
508 define <8 x i16> @cmpne_knownzeros_zext_v8i32_v8i16(<8 x i32> %x) {
509 ; SSE2-LABEL: cmpne_knownzeros_zext_v8i32_v8i16:
510 ; SSE2:       # %bb.0:
511 ; SSE2-NEXT:    psrld $31, %xmm1
512 ; SSE2-NEXT:    psrld $31, %xmm0
513 ; SSE2-NEXT:    packuswb %xmm1, %xmm0
514 ; SSE2-NEXT:    retq
516 ; SSE42-LABEL: cmpne_knownzeros_zext_v8i32_v8i16:
517 ; SSE42:       # %bb.0:
518 ; SSE42-NEXT:    psrld $31, %xmm1
519 ; SSE42-NEXT:    psrld $31, %xmm0
520 ; SSE42-NEXT:    packusdw %xmm1, %xmm0
521 ; SSE42-NEXT:    retq
523 ; AVX1-LABEL: cmpne_knownzeros_zext_v8i32_v8i16:
524 ; AVX1:       # %bb.0:
525 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm1
526 ; AVX1-NEXT:    vpsrld $31, %xmm1, %xmm1
527 ; AVX1-NEXT:    vpsrld $31, %xmm0, %xmm0
528 ; AVX1-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
529 ; AVX1-NEXT:    vzeroupper
530 ; AVX1-NEXT:    retq
532 ; AVX2-LABEL: cmpne_knownzeros_zext_v8i32_v8i16:
533 ; AVX2:       # %bb.0:
534 ; AVX2-NEXT:    vpsrld $31, %ymm0, %ymm0
535 ; AVX2-NEXT:    vextracti128 $1, %ymm0, %xmm1
536 ; AVX2-NEXT:    vpackusdw %xmm1, %xmm0, %xmm0
537 ; AVX2-NEXT:    vzeroupper
538 ; AVX2-NEXT:    retq
539   %a = lshr <8 x i32> %x, <i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31, i32 31>
540   %b = icmp ne <8 x i32> %a, zeroinitializer
541   %c = zext <8 x i1> %b to <8 x i16>
542   ret <8 x i16> %c
545 ; PR26697
546 define <4 x i32> @cmpeq_one_mask_bit(<4 x i32> %mask) {
547 ; SSE-LABEL: cmpeq_one_mask_bit:
548 ; SSE:       # %bb.0:
549 ; SSE-NEXT:    psrad $31, %xmm0
550 ; SSE-NEXT:    retq
552 ; AVX-LABEL: cmpeq_one_mask_bit:
553 ; AVX:       # %bb.0:
554 ; AVX-NEXT:    vpsrad $31, %xmm0, %xmm0
555 ; AVX-NEXT:    retq
556   %mask_signbit = and <4 x i32> %mask, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>
557   %mask_bool = icmp ne <4 x i32> %mask_signbit, zeroinitializer
558   %mask_bool_ext = sext <4 x i1> %mask_bool to <4 x i32>
559   ret <4 x i32> %mask_bool_ext