1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512vl | FileCheck %s --check-prefixes=CHECK,AVX512
3 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,AVX2
4 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=CHECK,SSE,SSE41
5 ; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2
7 ; Todo: Support logic for non-splat vectors
8 define <4 x i1> @andnot_eq_v4i32_todo_no_splat(<4 x i32> %x) nounwind {
9 ; AVX512-LABEL: andnot_eq_v4i32_todo_no_splat:
11 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
12 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm0, %k0
13 ; AVX512-NEXT: vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %k1
14 ; AVX512-NEXT: korw %k1, %k0, %k1
15 ; AVX512-NEXT: vmovdqa32 %xmm1, %xmm0 {%k1} {z}
18 ; AVX2-LABEL: andnot_eq_v4i32_todo_no_splat:
20 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
21 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm1
22 ; AVX2-NEXT: vpcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
23 ; AVX2-NEXT: vpor %xmm0, %xmm1, %xmm0
26 ; SSE-LABEL: andnot_eq_v4i32_todo_no_splat:
28 ; SSE-NEXT: pcmpeqd %xmm1, %xmm1
29 ; SSE-NEXT: pcmpeqd %xmm0, %xmm1
30 ; SSE-NEXT: pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
31 ; SSE-NEXT: por %xmm1, %xmm0
33 %cmp1 = icmp eq <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
34 %cmp2 = icmp eq <4 x i32> %x, <i32 -9, i32 -17, i32 -5, i32 -129>
35 %r = or <4 x i1> %cmp1, %cmp2
39 define <4 x i1> @andnot_eq_v4i32(<4 x i32> %x) nounwind {
40 ; AVX512-LABEL: andnot_eq_v4i32:
42 ; AVX512-NEXT: vpandnd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0
43 ; AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm1
44 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0
47 ; AVX2-LABEL: andnot_eq_v4i32:
49 ; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm1 = [4294967287,4294967287,4294967287,4294967287]
50 ; AVX2-NEXT: vpandn %xmm1, %xmm0, %xmm0
51 ; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
52 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm0, %xmm0
55 ; SSE-LABEL: andnot_eq_v4i32:
57 ; SSE-NEXT: pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
58 ; SSE-NEXT: pxor %xmm1, %xmm1
59 ; SSE-NEXT: pcmpeqd %xmm1, %xmm0
61 %cmp1 = icmp eq <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
62 %cmp2 = icmp eq <4 x i32> %x, <i32 -9, i32 -9, i32 -9, i32 -9>
63 %r = or <4 x i1> %cmp1, %cmp2
67 ; Intentional negative test.
68 define <2 x i1> @andnot_eq_v2i64_fail_max_not_n1(<2 x i64> %x) nounwind {
69 ; AVX512-LABEL: andnot_eq_v2i64_fail_max_not_n1:
71 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
72 ; AVX512-NEXT: vpcmpeqq %xmm1, %xmm0, %k0
73 ; AVX512-NEXT: vpcmpeqq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %k1
74 ; AVX512-NEXT: korw %k1, %k0, %k1
75 ; AVX512-NEXT: vmovdqa64 %xmm1, %xmm0 {%k1} {z}
78 ; AVX2-LABEL: andnot_eq_v2i64_fail_max_not_n1:
80 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
81 ; AVX2-NEXT: vpcmpeqq %xmm1, %xmm0, %xmm1
82 ; AVX2-NEXT: vpcmpeqq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
83 ; AVX2-NEXT: vpor %xmm0, %xmm1, %xmm0
86 ; SSE41-LABEL: andnot_eq_v2i64_fail_max_not_n1:
88 ; SSE41-NEXT: pcmpeqd %xmm1, %xmm1
89 ; SSE41-NEXT: pcmpeqq %xmm0, %xmm1
90 ; SSE41-NEXT: pcmpeqq {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
91 ; SSE41-NEXT: por %xmm1, %xmm0
94 ; SSE2-LABEL: andnot_eq_v2i64_fail_max_not_n1:
96 ; SSE2-NEXT: pcmpeqd %xmm1, %xmm1
97 ; SSE2-NEXT: pcmpeqd %xmm0, %xmm1
98 ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm1[1,0,3,2]
99 ; SSE2-NEXT: pand %xmm1, %xmm2
100 ; SSE2-NEXT: pcmpeqd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
101 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,0,3,2]
102 ; SSE2-NEXT: pand %xmm1, %xmm0
103 ; SSE2-NEXT: por %xmm2, %xmm0
105 %cmp1 = icmp eq <2 x i64> %x, <i64 -1, i64 -1>
106 %cmp2 = icmp eq <2 x i64> %x, <i64 7, i64 7>
107 %r = or <2 x i1> %cmp1, %cmp2
111 define <2 x i1> @andnot_eq_v2i64(<2 x i64> %x) nounwind {
112 ; AVX512-LABEL: andnot_eq_v2i64:
114 ; AVX512-NEXT: vpandnq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to2}, %xmm0, %xmm0
115 ; AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm1
116 ; AVX512-NEXT: vpcmpeqq %xmm1, %xmm0, %xmm0
119 ; AVX2-LABEL: andnot_eq_v2i64:
121 ; AVX2-NEXT: vpandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
122 ; AVX2-NEXT: vpxor %xmm1, %xmm1, %xmm1
123 ; AVX2-NEXT: vpcmpeqq %xmm1, %xmm0, %xmm0
126 ; SSE41-LABEL: andnot_eq_v2i64:
128 ; SSE41-NEXT: pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
129 ; SSE41-NEXT: pxor %xmm1, %xmm1
130 ; SSE41-NEXT: pcmpeqq %xmm1, %xmm0
133 ; SSE2-LABEL: andnot_eq_v2i64:
135 ; SSE2-NEXT: pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
136 ; SSE2-NEXT: pxor %xmm1, %xmm1
137 ; SSE2-NEXT: pcmpeqd %xmm1, %xmm0
138 ; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,0,3,2]
139 ; SSE2-NEXT: pand %xmm1, %xmm0
141 %cmp1 = icmp eq <2 x i64> %x, <i64 -5, i64 -5>
142 %cmp2 = icmp eq <2 x i64> %x, <i64 -1, i64 -1>
143 %r = or <2 x i1> %cmp1, %cmp2
147 ; Todo: Support logic for non-splat vectors
148 define <8 x i1> @andnot_ne_v8i16_todo_no_splat(<8 x i16> %x) nounwind {
149 ; AVX512-LABEL: andnot_ne_v8i16_todo_no_splat:
151 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
152 ; AVX512-NEXT: vpcmpeqw %xmm1, %xmm0, %xmm2
153 ; AVX512-NEXT: vpcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
154 ; AVX512-NEXT: vpternlogq $54, %xmm2, %xmm1, %xmm0
157 ; AVX2-LABEL: andnot_ne_v8i16_todo_no_splat:
159 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
160 ; AVX2-NEXT: vpcmpeqw %xmm1, %xmm0, %xmm2
161 ; AVX2-NEXT: vpcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
162 ; AVX2-NEXT: vpor %xmm0, %xmm2, %xmm0
163 ; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0
166 ; SSE-LABEL: andnot_ne_v8i16_todo_no_splat:
168 ; SSE-NEXT: pcmpeqd %xmm1, %xmm1
169 ; SSE-NEXT: movdqa %xmm0, %xmm2
170 ; SSE-NEXT: pcmpeqw %xmm1, %xmm2
171 ; SSE-NEXT: pcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
172 ; SSE-NEXT: por %xmm2, %xmm0
173 ; SSE-NEXT: pxor %xmm1, %xmm0
175 %cmp1 = icmp ne <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
176 %cmp2 = icmp ne <8 x i16> %x, <i16 -16385, i16 -257, i16 -33, i16 -8193, i16 -16385, i16 -257, i16 -33, i16 -8193>
177 %r = and <8 x i1> %cmp1, %cmp2
181 define <8 x i1> @andnot_ne_v8i16(<8 x i16> %x) nounwind {
182 ; AVX512-LABEL: andnot_ne_v8i16:
184 ; AVX512-NEXT: vpandnd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0
185 ; AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm1
186 ; AVX512-NEXT: vpcmpeqw %xmm1, %xmm0, %xmm0
187 ; AVX512-NEXT: vpternlogq $15, %xmm0, %xmm0, %xmm0
190 ; AVX2-LABEL: andnot_ne_v8i16:
192 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
193 ; AVX2-NEXT: vpandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
194 ; AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2
195 ; AVX2-NEXT: vpcmpeqw %xmm2, %xmm0, %xmm0
196 ; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0
199 ; SSE-LABEL: andnot_ne_v8i16:
201 ; SSE-NEXT: pcmpeqd %xmm1, %xmm1
202 ; SSE-NEXT: pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
203 ; SSE-NEXT: pxor %xmm2, %xmm2
204 ; SSE-NEXT: pcmpeqw %xmm2, %xmm0
205 ; SSE-NEXT: pxor %xmm1, %xmm0
207 %cmp1 = icmp ne <8 x i16> %x, <i16 -16385, i16 -16385, i16 -16385, i16 -16385, i16 -16385, i16 -16385, i16 -16385, i16 -16385>
208 %cmp2 = icmp ne <8 x i16> %x, <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
209 %r = and <8 x i1> %cmp1, %cmp2
213 ; Intentional negative test.
214 define <16 x i1> @andnot_ne_v16i8_fail_max_not_n1(<16 x i8> %x) nounwind {
215 ; AVX512-LABEL: andnot_ne_v16i8_fail_max_not_n1:
217 ; AVX512-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
218 ; AVX512-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm2
219 ; AVX512-NEXT: vpcmpgtb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
220 ; AVX512-NEXT: vpternlogq $54, %xmm2, %xmm1, %xmm0
223 ; AVX2-LABEL: andnot_ne_v16i8_fail_max_not_n1:
225 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
226 ; AVX2-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm2
227 ; AVX2-NEXT: vpcmpgtb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
228 ; AVX2-NEXT: vpor %xmm0, %xmm2, %xmm0
229 ; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0
232 ; SSE-LABEL: andnot_ne_v16i8_fail_max_not_n1:
234 ; SSE-NEXT: pcmpeqd %xmm1, %xmm1
235 ; SSE-NEXT: movdqa %xmm0, %xmm2
236 ; SSE-NEXT: pcmpeqb %xmm1, %xmm2
237 ; SSE-NEXT: pcmpgtb {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
238 ; SSE-NEXT: por %xmm2, %xmm0
239 ; SSE-NEXT: pxor %xmm1, %xmm0
241 %cmp1 = icmp ne <16 x i8> %x, <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>
242 %cmp2 = icmp ne <16 x i8> %x, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
243 %r = and <16 x i1> %cmp1, %cmp2
247 define <16 x i1> @andnot_ne_v16i8(<16 x i8> %x) nounwind {
248 ; AVX512-LABEL: andnot_ne_v16i8:
250 ; AVX512-NEXT: vpandnd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0
251 ; AVX512-NEXT: vpxor %xmm1, %xmm1, %xmm1
252 ; AVX512-NEXT: vpcmpeqb %xmm1, %xmm0, %xmm0
253 ; AVX512-NEXT: vpternlogq $15, %xmm0, %xmm0, %xmm0
256 ; AVX2-LABEL: andnot_ne_v16i8:
258 ; AVX2-NEXT: vpcmpeqd %xmm1, %xmm1, %xmm1
259 ; AVX2-NEXT: vpandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
260 ; AVX2-NEXT: vpxor %xmm2, %xmm2, %xmm2
261 ; AVX2-NEXT: vpcmpeqb %xmm2, %xmm0, %xmm0
262 ; AVX2-NEXT: vpxor %xmm1, %xmm0, %xmm0
265 ; SSE-LABEL: andnot_ne_v16i8:
267 ; SSE-NEXT: pcmpeqd %xmm1, %xmm1
268 ; SSE-NEXT: pandn {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
269 ; SSE-NEXT: pxor %xmm2, %xmm2
270 ; SSE-NEXT: pcmpeqb %xmm2, %xmm0
271 ; SSE-NEXT: pxor %xmm1, %xmm0
273 %cmp1 = icmp ne <16 x i8> %x, <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>
274 %cmp2 = icmp ne <16 x i8> %x, <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>
275 %r = and <16 x i1> %cmp1, %cmp2
279 define i1 @andnot_ne_i32(i32 %x) nounwind {
280 ; CHECK-LABEL: andnot_ne_i32:
282 ; CHECK-NEXT: addl $1073741825, %edi # imm = 0x40000001
283 ; CHECK-NEXT: testl $-1073741825, %edi # imm = 0xBFFFFFFF
284 ; CHECK-NEXT: setne %al
286 %cmp1 = icmp ne i32 %x, -1
287 %cmp2 = icmp ne i32 %x, -1073741825
288 %r = and i1 %cmp1, %cmp2
292 define i1 @addand_ne_i16(i16 %x) nounwind {
293 ; CHECK-LABEL: addand_ne_i16:
295 ; CHECK-NEXT: addl $3, %edi
296 ; CHECK-NEXT: testl $49151, %edi # imm = 0xBFFF
297 ; CHECK-NEXT: setne %al
299 %cmp1 = icmp ne i16 %x, -3
300 %cmp2 = icmp ne i16 %x, 16381
301 %r = and i1 %cmp1, %cmp2
305 ; Intentional negative test.
306 define <8 x i1> @addand_ne_v8i16_fail(<8 x i16> %x) nounwind {
307 ; AVX512-LABEL: addand_ne_v8i16_fail:
309 ; AVX512-NEXT: vpcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1
310 ; AVX512-NEXT: vpcmpeqd %xmm2, %xmm2, %xmm2
311 ; AVX512-NEXT: vpcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
312 ; AVX512-NEXT: vpternlogq $86, %xmm2, %xmm1, %xmm0
315 ; AVX2-LABEL: addand_ne_v8i16_fail:
317 ; AVX2-NEXT: vpcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm1
318 ; AVX2-NEXT: vpcmpeqd %xmm2, %xmm2, %xmm2
319 ; AVX2-NEXT: vpcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
320 ; AVX2-NEXT: vpor %xmm0, %xmm1, %xmm0
321 ; AVX2-NEXT: vpxor %xmm2, %xmm0, %xmm0
324 ; SSE-LABEL: addand_ne_v8i16_fail:
326 ; SSE-NEXT: movdqa {{.*#+}} xmm1 = [65533,65533,65533,65533,65533,65533,65533,65533]
327 ; SSE-NEXT: pcmpeqw %xmm0, %xmm1
328 ; SSE-NEXT: pcmpeqd %xmm2, %xmm2
329 ; SSE-NEXT: pcmpeqw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
330 ; SSE-NEXT: por %xmm1, %xmm0
331 ; SSE-NEXT: pxor %xmm2, %xmm0
333 %cmp1 = icmp ne <8 x i16> %x, <i16 -3, i16 -3, i16 -3, i16 -3, i16 -3, i16 -3, i16 -3, i16 -3>
334 %cmp2 = icmp ne <8 x i16> %x, <i16 16381, i16 16381, i16 16381, i16 16381, i16 16381, i16 16381, i16 16381, i16 16381>
335 %r = and <8 x i1> %cmp1, %cmp2
339 define i1 @addand_eq_i32(i32 %x) nounwind {
340 ; CHECK-LABEL: addand_eq_i32:
342 ; CHECK-NEXT: incl %edi
343 ; CHECK-NEXT: testl $-9, %edi
344 ; CHECK-NEXT: sete %al
346 %cmp1 = icmp eq i32 %x, -1
347 %cmp2 = icmp eq i32 %x, 7
348 %r = or i1 %cmp1, %cmp2
352 ; Intentional negative test.
353 define i1 @addand_eq_i8_fail_abs_p2_minmax_not(i8 %x) nounwind {
354 ; CHECK-LABEL: addand_eq_i8_fail_abs_p2_minmax_not:
356 ; CHECK-NEXT: cmpb $124, %dil
357 ; CHECK-NEXT: sete %cl
358 ; CHECK-NEXT: cmpb $-8, %dil
359 ; CHECK-NEXT: sete %al
360 ; CHECK-NEXT: orb %cl, %al
362 %cmp1 = icmp eq i8 %x, 124
363 %cmp2 = icmp eq i8 %x, -8
364 %r = or i1 %cmp1, %cmp2
368 define i1 @addand_ne_i8(i8 %x) nounwind {
369 ; CHECK-LABEL: addand_ne_i8:
371 ; CHECK-NEXT: addb $5, %dil
372 ; CHECK-NEXT: testb $-65, %dil
373 ; CHECK-NEXT: setne %al
375 %cmp1 = icmp ne i8 %x, 59
376 %cmp2 = icmp ne i8 %x, -5
377 %r = and i1 %cmp1, %cmp2
381 ; Intentional negative test.
382 define i1 @addand_eq_i64_fail_non_p2_dif(i64 %x) nounwind {
383 ; CHECK-LABEL: addand_eq_i64_fail_non_p2_dif:
385 ; CHECK-NEXT: cmpq $-8, %rdi
386 ; CHECK-NEXT: setne %cl
387 ; CHECK-NEXT: cmpq $-17, %rdi
388 ; CHECK-NEXT: setne %al
389 ; CHECK-NEXT: andb %cl, %al
391 %cmp1 = icmp ne i64 %x, -8
392 %cmp2 = icmp ne i64 %x, -17
393 %r = and i1 %cmp1, %cmp2
397 define i1 @addand_eq_i64(i64 %x) nounwind {
398 ; CHECK-LABEL: addand_eq_i64:
400 ; CHECK-NEXT: addq $256, %rdi # imm = 0x100
401 ; CHECK-NEXT: testq $-1025, %rdi # imm = 0xFBFF
402 ; CHECK-NEXT: setne %al
404 %cmp1 = icmp ne i64 %x, 768
405 %cmp2 = icmp ne i64 %x, -256
406 %r = and i1 %cmp1, %cmp2