Skip to content

Commit d378ea6

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

File tree

1 file changed

+297
-0
lines changed

1 file changed

+297
-0
lines changed
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
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) {
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) {
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) {
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) {
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) {
102+
; X86-LABEL: fold_and_xor_neg_v1_64:
103+
; X86: # %bb.0:
104+
; X86-NEXT: pushl %esi
105+
; X86-NEXT: .cfi_def_cfa_offset 8
106+
; X86-NEXT: .cfi_offset %esi, -8
107+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
108+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
109+
; X86-NEXT: xorl %edx, %edx
110+
; X86-NEXT: movl %ecx, %eax
111+
; X86-NEXT: negl %eax
112+
; X86-NEXT: sbbl %esi, %edx
113+
; X86-NEXT: xorl %esi, %edx
114+
; X86-NEXT: xorl %ecx, %eax
115+
; X86-NEXT: andl {{[0-9]+}}(%esp), %edx
116+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
117+
; X86-NEXT: popl %esi
118+
; X86-NEXT: .cfi_def_cfa_offset 4
119+
; X86-NEXT: retl
120+
;
121+
; X64-LABEL: fold_and_xor_neg_v1_64:
122+
; X64: # %bb.0:
123+
; X64-NEXT: movq %rdi, %rax
124+
; X64-NEXT: negq %rax
125+
; X64-NEXT: xorq %rdi, %rax
126+
; X64-NEXT: andq %rsi, %rax
127+
; X64-NEXT: retq
128+
%neg = sub i64 0, %x
129+
%xor = xor i64 %x, %neg
130+
%and = and i64 %xor, %y
131+
ret i64 %and
132+
}
133+
134+
; Negative test
135+
define i16 @fold_and_xor_neg_v1_16_negative(i16 %x, i16 %y) {
136+
; X86-LABEL: fold_and_xor_neg_v1_16_negative:
137+
; X86: # %bb.0:
138+
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
139+
; X86-NEXT: movl %ecx, %eax
140+
; X86-NEXT: negl %eax
141+
; X86-NEXT: xorl %ecx, %eax
142+
; X86-NEXT: andw {{[0-9]+}}(%esp), %ax
143+
; X86-NEXT: # kill: def $ax killed $ax killed $eax
144+
; X86-NEXT: retl
145+
;
146+
; X64-LABEL: fold_and_xor_neg_v1_16_negative:
147+
; X64: # %bb.0:
148+
; X64-NEXT: movl %edi, %eax
149+
; X64-NEXT: negl %eax
150+
; X64-NEXT: xorl %edi, %eax
151+
; X64-NEXT: andl %esi, %eax
152+
; X64-NEXT: # kill: def $ax killed $ax killed $eax
153+
; X64-NEXT: retq
154+
%neg = sub i16 0, %x
155+
%xor = xor i16 %x, %neg
156+
%and = and i16 %xor, %y
157+
ret i16 %and
158+
}
159+
160+
; Negative test
161+
define <4 x i32> @fold_and_xor_neg_v1_v4x32_negative(<4 x i32> %x, <4 x i32> %y) {
162+
; X86-LABEL: fold_and_xor_neg_v1_v4x32_negative:
163+
; X86: # %bb.0:
164+
; X86-NEXT: pxor %xmm2, %xmm2
165+
; X86-NEXT: psubd %xmm0, %xmm2
166+
; X86-NEXT: pxor %xmm2, %xmm0
167+
; X86-NEXT: pand %xmm1, %xmm0
168+
; X86-NEXT: retl
169+
;
170+
; X64-LABEL: fold_and_xor_neg_v1_v4x32_negative:
171+
; X64: # %bb.0:
172+
; X64-NEXT: pxor %xmm2, %xmm2
173+
; X64-NEXT: psubd %xmm0, %xmm2
174+
; X64-NEXT: pxor %xmm2, %xmm0
175+
; X64-NEXT: pand %xmm1, %xmm0
176+
; X64-NEXT: retq
177+
%neg = sub <4 x i32> zeroinitializer, %x
178+
%xor = xor <4 x i32> %x, %neg
179+
%and = and <4 x i32> %xor, %y
180+
ret <4 x i32> %and
181+
}
182+
183+
; Negative test
184+
define i32 @fold_and_xor_neg_v1_32_two_uses_xor_negative(i32 %x, i32 %y) {
185+
; X86-LABEL: fold_and_xor_neg_v1_32_two_uses_xor_negative:
186+
; X86: # %bb.0:
187+
; X86-NEXT: pushl %esi
188+
; X86-NEXT: .cfi_def_cfa_offset 8
189+
; X86-NEXT: .cfi_offset %esi, -8
190+
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
191+
; X86-NEXT: movl %eax, %ecx
192+
; X86-NEXT: negl %ecx
193+
; X86-NEXT: xorl %eax, %ecx
194+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
195+
; X86-NEXT: andl %ecx, %esi
196+
; X86-NEXT: pushl %ecx
197+
; X86-NEXT: .cfi_adjust_cfa_offset 4
198+
; X86-NEXT: calll use@PLT
199+
; X86-NEXT: addl $4, %esp
200+
; X86-NEXT: .cfi_adjust_cfa_offset -4
201+
; X86-NEXT: movl %esi, %eax
202+
; X86-NEXT: popl %esi
203+
; X86-NEXT: .cfi_def_cfa_offset 4
204+
; X86-NEXT: retl
205+
;
206+
; X64-LABEL: fold_and_xor_neg_v1_32_two_uses_xor_negative:
207+
; X64: # %bb.0:
208+
; X64-NEXT: pushq %rbx
209+
; X64-NEXT: .cfi_def_cfa_offset 16
210+
; X64-NEXT: .cfi_offset %rbx, -16
211+
; X64-NEXT: movl %esi, %ebx
212+
; X64-NEXT: movl %edi, %eax
213+
; X64-NEXT: negl %eax
214+
; X64-NEXT: xorl %eax, %edi
215+
; X64-NEXT: andl %edi, %ebx
216+
; X64-NEXT: callq use@PLT
217+
; X64-NEXT: movl %ebx, %eax
218+
; X64-NEXT: popq %rbx
219+
; X64-NEXT: .cfi_def_cfa_offset 8
220+
; X64-NEXT: retq
221+
%neg = sub i32 0, %x
222+
%xor = xor i32 %x, %neg
223+
%and = and i32 %xor, %y
224+
call void @use(i32 %xor)
225+
ret i32 %and
226+
}
227+
228+
; Negative test
229+
define i32 @fold_and_xor_neg_v1_32_two_uses_sub_negative(i32 %x, i32 %y) {
230+
; X86-LABEL: fold_and_xor_neg_v1_32_two_uses_sub_negative:
231+
; X86: # %bb.0:
232+
; X86-NEXT: pushl %esi
233+
; X86-NEXT: .cfi_def_cfa_offset 8
234+
; X86-NEXT: .cfi_offset %esi, -8
235+
; X86-NEXT: movl {{[0-9]+}}(%esp), %esi
236+
; X86-NEXT: movl %esi, %eax
237+
; X86-NEXT: negl %eax
238+
; X86-NEXT: xorl %eax, %esi
239+
; X86-NEXT: andl {{[0-9]+}}(%esp), %esi
240+
; X86-NEXT: pushl %eax
241+
; X86-NEXT: .cfi_adjust_cfa_offset 4
242+
; X86-NEXT: calll use@PLT
243+
; X86-NEXT: addl $4, %esp
244+
; X86-NEXT: .cfi_adjust_cfa_offset -4
245+
; X86-NEXT: movl %esi, %eax
246+
; X86-NEXT: popl %esi
247+
; X86-NEXT: .cfi_def_cfa_offset 4
248+
; X86-NEXT: retl
249+
;
250+
; X64-LABEL: fold_and_xor_neg_v1_32_two_uses_sub_negative:
251+
; X64: # %bb.0:
252+
; X64-NEXT: pushq %rbx
253+
; X64-NEXT: .cfi_def_cfa_offset 16
254+
; X64-NEXT: .cfi_offset %rbx, -16
255+
; X64-NEXT: movl %edi, %ebx
256+
; X64-NEXT: negl %edi
257+
; X64-NEXT: xorl %edi, %ebx
258+
; X64-NEXT: andl %esi, %ebx
259+
; X64-NEXT: callq use@PLT
260+
; X64-NEXT: movl %ebx, %eax
261+
; X64-NEXT: popq %rbx
262+
; X64-NEXT: .cfi_def_cfa_offset 8
263+
; X64-NEXT: retq
264+
%neg = sub i32 0, %x
265+
%xor = xor i32 %x, %neg
266+
%and = and i32 %xor, %y
267+
call void @use(i32 %neg)
268+
ret i32 %and
269+
}
270+
271+
; Negative test
272+
define i32 @fold_and_xor_neg_v1_32_no_blsmsk_negative(i32 %x, i32 %y, i32 %z) {
273+
; X86-LABEL: fold_and_xor_neg_v1_32_no_blsmsk_negative:
274+
; X86: # %bb.0:
275+
; X86-NEXT: xorl %eax, %eax
276+
; X86-NEXT: subl {{[0-9]+}}(%esp), %eax
277+
; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
278+
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
279+
; X86-NEXT: retl
280+
;
281+
; X64-LABEL: fold_and_xor_neg_v1_32_no_blsmsk_negative:
282+
; X64: # %bb.0:
283+
; X64-NEXT: movl %edx, %eax
284+
; X64-NEXT: negl %eax
285+
; X64-NEXT: xorl %edi, %eax
286+
; X64-NEXT: andl %esi, %eax
287+
; X64-NEXT: retq
288+
%neg = sub i32 0, %z
289+
%xor = xor i32 %x, %neg
290+
%and = and i32 %xor, %y
291+
ret i32 %and
292+
}
293+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
294+
; X64-BMI: {{.*}}
295+
; X64-NOBMI: {{.*}}
296+
; X86-BMI: {{.*}}
297+
; X86-NOBMI: {{.*}}

0 commit comments

Comments
 (0)