Skip to content

Commit c2b477d

Browse files
committed
[X86] Add Tests for AND(Y, XOR(X, SUB(0, X))) -> ANDN(Y, BLSMSK(X)); NFC
1 parent 6c90f87 commit c2b477d

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -mtriple=i686-- -mattr=-bmi,+sse2 | FileCheck %s --check-prefixes=X86,X86-NOBMI
3+
; RUN: llc < %s -mtriple=i686-- -mattr=+bmi,+sse2 | FileCheck %s --check-prefixes=X86,X86-BMI
4+
; RUN: llc < %s -mtriple=x86_64-- -mattr=-bmi | FileCheck %s --check-prefixes=X64,X64-NOBMI
5+
; RUN: llc < %s -mtriple=x86_64-- -mattr=+bmi | FileCheck %s --check-prefixes=X64,X64-BMI
6+
7+
declare void @use(i32)
8+
9+
define i32 @fold_and_xor_neg_v1_32(i32 %x, i32 %y) nounwind {
10+
; X86-LABEL: fold_and_xor_neg_v1_32:
11+
; X86: # %bb.0:
12+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
13+
; X86-NEXT: movl %ecx, %eax
14+
; X86-NEXT: negl %eax
15+
; X86-NEXT: xorl %ecx, %eax
16+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
17+
; X86-NEXT: retl
18+
;
19+
; X64-LABEL: fold_and_xor_neg_v1_32:
20+
; X64: # %bb.0:
21+
; X64-NEXT: movl %edi, %eax
22+
; X64-NEXT: negl %eax
23+
; X64-NEXT: xorl %edi, %eax
24+
; X64-NEXT: andl %esi, %eax
25+
; X64-NEXT: retq
26+
%neg = sub i32 0, %x
27+
%xor = xor i32 %x, %neg
28+
%and = and i32 %xor, %y
29+
ret i32 %and
30+
}
31+
32+
define i32 @fold_and_xor_neg_v2_32(i32 %x, i32 %y) nounwind {
33+
; X86-LABEL: fold_and_xor_neg_v2_32:
34+
; X86: # %bb.0:
35+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
36+
; X86-NEXT: movl %ecx, %eax
37+
; X86-NEXT: negl %eax
38+
; X86-NEXT: xorl %ecx, %eax
39+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
40+
; X86-NEXT: retl
41+
;
42+
; X64-LABEL: fold_and_xor_neg_v2_32:
43+
; X64: # %bb.0:
44+
; X64-NEXT: movl %edi, %eax
45+
; X64-NEXT: negl %eax
46+
; X64-NEXT: xorl %edi, %eax
47+
; X64-NEXT: andl %esi, %eax
48+
; X64-NEXT: retq
49+
%neg = sub i32 0, %x
50+
%xor = xor i32 %x, %neg
51+
%and = and i32 %y, %xor
52+
ret i32 %and
53+
}
54+
55+
define i32 @fold_and_xor_neg_v3_32(i32 %x, i32 %y) nounwind {
56+
; X86-LABEL: fold_and_xor_neg_v3_32:
57+
; X86: # %bb.0:
58+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
59+
; X86-NEXT: movl %ecx, %eax
60+
; X86-NEXT: negl %eax
61+
; X86-NEXT: xorl %ecx, %eax
62+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
63+
; X86-NEXT: retl
64+
;
65+
; X64-LABEL: fold_and_xor_neg_v3_32:
66+
; X64: # %bb.0:
67+
; X64-NEXT: movl %edi, %eax
68+
; X64-NEXT: negl %eax
69+
; X64-NEXT: xorl %edi, %eax
70+
; X64-NEXT: andl %esi, %eax
71+
; X64-NEXT: retq
72+
%neg = sub i32 0, %x
73+
%xor = xor i32 %neg, %x
74+
%and = and i32 %xor, %y
75+
ret i32 %and
76+
}
77+
78+
define i32 @fold_and_xor_neg_v4_32(i32 %x, i32 %y) nounwind {
79+
; X86-LABEL: fold_and_xor_neg_v4_32:
80+
; X86: # %bb.0:
81+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
82+
; X86-NEXT: movl %ecx, %eax
83+
; X86-NEXT: negl %eax
84+
; X86-NEXT: xorl %ecx, %eax
85+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
86+
; X86-NEXT: retl
87+
;
88+
; X64-LABEL: fold_and_xor_neg_v4_32:
89+
; X64: # %bb.0:
90+
; X64-NEXT: movl %edi, %eax
91+
; X64-NEXT: negl %eax
92+
; X64-NEXT: xorl %edi, %eax
93+
; X64-NEXT: andl %esi, %eax
94+
; X64-NEXT: retq
95+
%neg = sub i32 0, %x
96+
%xor = xor i32 %neg, %x
97+
%and = and i32 %y, %xor
98+
ret i32 %and
99+
}
100+
101+
define i64 @fold_and_xor_neg_v1_64(i64 %x, i64 %y) nounwind {
102+
; X86-LABEL: fold_and_xor_neg_v1_64:
103+
; X86: # %bb.0:
104+
; X86-NEXT: pushl %esi
105+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
106+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
107+
; X86-NEXT: xorl %edx, %edx
108+
; X86-NEXT: movl %ecx, %eax
109+
; X86-NEXT: negl %eax
110+
; X86-NEXT: sbbl %esi, %edx
111+
; X86-NEXT: xorl %esi, %edx
112+
; X86-NEXT: xorl %ecx, %eax
113+
; X86-NEXT: andl {{[0-9]+}}(%esp), %edx
114+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
115+
; X86-NEXT: popl %esi
116+
; X86-NEXT: retl
117+
;
118+
; X64-LABEL: fold_and_xor_neg_v1_64:
119+
; X64: # %bb.0:
120+
; X64-NEXT: movq %rdi, %rax
121+
; X64-NEXT: negq %rax
122+
; X64-NEXT: xorq %rdi, %rax
123+
; X64-NEXT: andq %rsi, %rax
124+
; X64-NEXT: retq
125+
%neg = sub i64 0, %x
126+
%xor = xor i64 %x, %neg
127+
%and = and i64 %xor, %y
128+
ret i64 %and
129+
}
130+
131+
; Negative test
132+
define i16 @fold_and_xor_neg_v1_16_negative(i16 %x, i16 %y) nounwind {
133+
; X86-LABEL: fold_and_xor_neg_v1_16_negative:
134+
; X86: # %bb.0:
135+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
136+
; X86-NEXT: movl %ecx, %eax
137+
; X86-NEXT: negl %eax
138+
; X86-NEXT: xorl %ecx, %eax
139+
; X86-NEXT: andw {{[0-9]+}}(%esp), %ax
140+
; X86-NEXT: # kill: def $ax killed $ax killed $eax
141+
; X86-NEXT: retl
142+
;
143+
; X64-LABEL: fold_and_xor_neg_v1_16_negative:
144+
; X64: # %bb.0:
145+
; X64-NEXT: movl %edi, %eax
146+
; X64-NEXT: negl %eax
147+
; X64-NEXT: xorl %edi, %eax
148+
; X64-NEXT: andl %esi, %eax
149+
; X64-NEXT: # kill: def $ax killed $ax killed $eax
150+
; X64-NEXT: retq
151+
%neg = sub i16 0, %x
152+
%xor = xor i16 %x, %neg
153+
%and = and i16 %xor, %y
154+
ret i16 %and
155+
}
156+
157+
; Negative test
158+
define <4 x i32> @fold_and_xor_neg_v1_v4x32_negative(<4 x i32> %x, <4 x i32> %y) nounwind {
159+
; X86-LABEL: fold_and_xor_neg_v1_v4x32_negative:
160+
; X86: # %bb.0:
161+
; X86-NEXT: pxor %xmm2, %xmm2
162+
; X86-NEXT: psubd %xmm0, %xmm2
163+
; X86-NEXT: pxor %xmm2, %xmm0
164+
; X86-NEXT: pand %xmm1, %xmm0
165+
; X86-NEXT: retl
166+
;
167+
; X64-LABEL: fold_and_xor_neg_v1_v4x32_negative:
168+
; X64: # %bb.0:
169+
; X64-NEXT: pxor %xmm2, %xmm2
170+
; X64-NEXT: psubd %xmm0, %xmm2
171+
; X64-NEXT: pxor %xmm2, %xmm0
172+
; X64-NEXT: pand %xmm1, %xmm0
173+
; X64-NEXT: retq
174+
%neg = sub <4 x i32> zeroinitializer, %x
175+
%xor = xor <4 x i32> %x, %neg
176+
%and = and <4 x i32> %xor, %y
177+
ret <4 x i32> %and
178+
}
179+
180+
; Negative test
181+
define i32 @fold_and_xor_neg_v1_32_two_uses_xor_negative(i32 %x, i32 %y) nounwind {
182+
; X86-LABEL: fold_and_xor_neg_v1_32_two_uses_xor_negative:
183+
; X86: # %bb.0:
184+
; X86-NEXT: pushl %esi
185+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
186+
; X86-NEXT: movl %eax, %ecx
187+
; X86-NEXT: negl %ecx
188+
; X86-NEXT: xorl %eax, %ecx
189+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
190+
; X86-NEXT: andl %ecx, %esi
191+
; X86-NEXT: pushl %ecx
192+
; X86-NEXT: calll use@PLT
193+
; X86-NEXT: addl $4, %esp
194+
; X86-NEXT: movl %esi, %eax
195+
; X86-NEXT: popl %esi
196+
; X86-NEXT: retl
197+
;
198+
; X64-LABEL: fold_and_xor_neg_v1_32_two_uses_xor_negative:
199+
; X64: # %bb.0:
200+
; X64-NEXT: pushq %rbx
201+
; X64-NEXT: movl %esi, %ebx
202+
; X64-NEXT: movl %edi, %eax
203+
; X64-NEXT: negl %eax
204+
; X64-NEXT: xorl %eax, %edi
205+
; X64-NEXT: andl %edi, %ebx
206+
; X64-NEXT: callq use@PLT
207+
; X64-NEXT: movl %ebx, %eax
208+
; X64-NEXT: popq %rbx
209+
; X64-NEXT: retq
210+
%neg = sub i32 0, %x
211+
%xor = xor i32 %x, %neg
212+
%and = and i32 %xor, %y
213+
call void @use(i32 %xor)
214+
ret i32 %and
215+
}
216+
217+
; Negative test
218+
define i32 @fold_and_xor_neg_v1_32_two_uses_sub_negative(i32 %x, i32 %y) nounwind {
219+
; X86-LABEL: fold_and_xor_neg_v1_32_two_uses_sub_negative:
220+
; X86: # %bb.0:
221+
; X86-NEXT: pushl %esi
222+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
223+
; X86-NEXT: movl %esi, %eax
224+
; X86-NEXT: negl %eax
225+
; X86-NEXT: xorl %eax, %esi
226+
; X86-NEXT: andl {{[0-9]+}}(%esp), %esi
227+
; X86-NEXT: pushl %eax
228+
; X86-NEXT: calll use@PLT
229+
; X86-NEXT: addl $4, %esp
230+
; X86-NEXT: movl %esi, %eax
231+
; X86-NEXT: popl %esi
232+
; X86-NEXT: retl
233+
;
234+
; X64-LABEL: fold_and_xor_neg_v1_32_two_uses_sub_negative:
235+
; X64: # %bb.0:
236+
; X64-NEXT: pushq %rbx
237+
; X64-NEXT: movl %edi, %ebx
238+
; X64-NEXT: negl %edi
239+
; X64-NEXT: xorl %edi, %ebx
240+
; X64-NEXT: andl %esi, %ebx
241+
; X64-NEXT: callq use@PLT
242+
; X64-NEXT: movl %ebx, %eax
243+
; X64-NEXT: popq %rbx
244+
; X64-NEXT: retq
245+
%neg = sub i32 0, %x
246+
%xor = xor i32 %x, %neg
247+
%and = and i32 %xor, %y
248+
call void @use(i32 %neg)
249+
ret i32 %and
250+
}
251+
252+
; Negative test
253+
define i32 @fold_and_xor_neg_v1_32_no_blsmsk_negative(i32 %x, i32 %y, i32 %z) nounwind {
254+
; X86-LABEL: fold_and_xor_neg_v1_32_no_blsmsk_negative:
255+
; X86: # %bb.0:
256+
; X86-NEXT: xorl %eax, %eax
257+
; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
258+
; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
259+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
260+
; X86-NEXT: retl
261+
;
262+
; X64-LABEL: fold_and_xor_neg_v1_32_no_blsmsk_negative:
263+
; X64: # %bb.0:
264+
; X64-NEXT: movl %edx, %eax
265+
; X64-NEXT: negl %eax
266+
; X64-NEXT: xorl %edi, %eax
267+
; X64-NEXT: andl %esi, %eax
268+
; X64-NEXT: retq
269+
%neg = sub i32 0, %z
270+
%xor = xor i32 %x, %neg
271+
%and = and i32 %xor, %y
272+
ret i32 %and
273+
}
274+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
275+
; X64-BMI: {{.*}}
276+
; X64-NOBMI: {{.*}}
277+
; X86-BMI: {{.*}}
278+
; X86-NOBMI: {{.*}}

0 commit comments

Comments
 (0)