xref: /llvm-project/llvm/test/Transforms/InstSimplify/and.ll (revision b280ee1dd7e9b36ae7aaa3953556e4b7a7f31a29)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4define i32 @poison(i32 %x) {
5; CHECK-LABEL: @poison(
6; CHECK-NEXT:    ret i32 poison
7;
8  %v = and i32 %x, poison
9  ret i32 %v
10}
11
12; (X | Y) & (X | ~Y) --> X (commuted 8 ways)
13
14define i8 @or_or_not_commute0(i8 %x, i8 %y) {
15; CHECK-LABEL: @or_or_not_commute0(
16; CHECK-NEXT:    ret i8 [[X:%.*]]
17;
18  %ynot = xor i8 %y, -1
19  %xory = or i8 %x, %y
20  %xorynot = or i8 %x, %ynot
21  %and = and i8 %xory, %xorynot
22  ret i8 %and
23}
24
25define <2 x i5> @or_or_not_commute1(<2 x i5> %x, <2 x i5> %y) {
26; CHECK-LABEL: @or_or_not_commute1(
27; CHECK-NEXT:    ret <2 x i5> [[X:%.*]]
28;
29  %ynot = xor <2 x i5> %y, <i5 -1, i5 -1>
30  %xory = or <2 x i5> %x, %y
31  %xorynot = or <2 x i5> %x, %ynot
32  %and = and <2 x i5> %xorynot, %xory
33  ret <2 x i5> %and
34}
35
36define <2 x i8> @or_or_not_commute2(<2 x i8> %x, <2 x i8> %y) {
37; CHECK-LABEL: @or_or_not_commute2(
38; CHECK-NEXT:    ret <2 x i8> [[X:%.*]]
39;
40  %ynot = xor <2 x i8> %y, <i8 poison, i8 -1>
41  %xory = or <2 x i8> %x, %y
42  %xorynot = or <2 x i8> %ynot, %x
43  %and = and <2 x i8> %xory, %xorynot
44  ret <2 x i8> %and
45}
46
47define i8 @or_or_not_commute3(i8 %x, i8 %y) {
48; CHECK-LABEL: @or_or_not_commute3(
49; CHECK-NEXT:    ret i8 [[X:%.*]]
50;
51  %ynot = xor i8 %y, -1
52  %xory = or i8 %x, %y
53  %xorynot = or i8 %ynot, %x
54  %and = and i8 %xorynot, %xory
55  ret i8 %and
56}
57define i8 @or_or_not_commute4(i8 %x, i8 %y) {
58; CHECK-LABEL: @or_or_not_commute4(
59; CHECK-NEXT:    ret i8 [[X:%.*]]
60;
61  %ynot = xor i8 %y, -1
62  %xory = or i8 %y, %x
63  %xorynot = or i8 %x, %ynot
64  %and = and i8 %xory, %xorynot
65  ret i8 %and
66}
67
68define i8 @or_or_not_commute5(i8 %x, i8 %y) {
69; CHECK-LABEL: @or_or_not_commute5(
70; CHECK-NEXT:    ret i8 [[X:%.*]]
71;
72  %ynot = xor i8 %y, -1
73  %xory = or i8 %y, %x
74  %xorynot = or i8 %x, %ynot
75  %and = and i8 %xorynot, %xory
76  ret i8 %and
77}
78
79define i8 @or_or_not_commute6(i8 %x, i8 %y) {
80; CHECK-LABEL: @or_or_not_commute6(
81; CHECK-NEXT:    ret i8 [[X:%.*]]
82;
83  %ynot = xor i8 %y, -1
84  %xory = or i8 %y, %x
85  %xorynot = or i8 %ynot, %x
86  %and = and i8 %xory, %xorynot
87  ret i8 %and
88}
89
90define i8 @or_or_not_commute7(i8 %x, i8 %y) {
91; CHECK-LABEL: @or_or_not_commute7(
92; CHECK-NEXT:    ret i8 [[X:%.*]]
93;
94  %ynot = xor i8 %y, -1
95  %xory = or i8 %y, %x
96  %xorynot = or i8 %ynot, %x
97  %and = and i8 %xorynot, %xory
98  ret i8 %and
99}
100
101; negative test - wrong logic op
102
103define i8 @or_xor_not(i8 %x, i8 %y) {
104; CHECK-LABEL: @or_xor_not(
105; CHECK-NEXT:    [[YNOT:%.*]] = xor i8 [[Y:%.*]], -1
106; CHECK-NEXT:    [[XXORY:%.*]] = xor i8 [[Y]], [[X:%.*]]
107; CHECK-NEXT:    [[XORYNOT:%.*]] = or i8 [[X]], [[YNOT]]
108; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XORYNOT]], [[XXORY]]
109; CHECK-NEXT:    ret i8 [[AND]]
110;
111  %ynot = xor i8 %y, -1
112  %xxory = xor i8 %y, %x
113  %xorynot = or i8 %x, %ynot
114  %and = and i8 %xorynot, %xxory
115  ret i8 %and
116}
117
118; negative test - must have common operands
119
120define i8 @or_or_not_no_common_op(i8 %x, i8 %y, i8 %z) {
121; CHECK-LABEL: @or_or_not_no_common_op(
122; CHECK-NEXT:    [[XORZ:%.*]] = or i8 [[Z:%.*]], [[X:%.*]]
123; CHECK-NEXT:    [[YNOT:%.*]] = xor i8 [[Y:%.*]], -1
124; CHECK-NEXT:    [[XORYNOT:%.*]] = or i8 [[X]], [[YNOT]]
125; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XORYNOT]], [[XORZ]]
126; CHECK-NEXT:    ret i8 [[AND]]
127;
128  %xorz = or i8 %z, %x
129  %ynot = xor i8 %y, -1
130  %xorynot = or i8 %x, %ynot
131  %and = and i8 %xorynot, %xorz
132  ret i8 %and
133}
134
135; ((X | Y) ^ X ) & ((X | Y) ^ Y) --> 0
136
137define i8 @or_xor(i8 %x, i8 %y) {
138; CHECK-LABEL: @or_xor(
139; CHECK-NEXT:    ret i8 0
140;
141  %or = or i8 %x, %y
142  %xor1 = xor i8 %or, %x
143  %xor2 = xor i8 %or, %y
144  %and = and i8 %xor1, %xor2
145  ret i8 %and
146}
147
148; ((X | Y) ^ Y ) & ((X | Y) ^ X) --> 0
149
150define i8 @or_xor_commute1(i8 %x, i8 %y) {
151; CHECK-LABEL: @or_xor_commute1(
152; CHECK-NEXT:    ret i8 0
153;
154  %or = or i8 %x, %y
155  %xor1 = xor i8 %or, %x
156  %xor2 = xor i8 %or, %y
157  %and = and i8 %xor2, %xor1
158  ret i8 %and
159}
160
161; (X ^ (X | Y) ) & (Y ^ (X | Y)) --> 0
162
163define i71 @or_xor_commute2(i71 %x, i71 %y) {
164; CHECK-LABEL: @or_xor_commute2(
165; CHECK-NEXT:    ret i71 0
166;
167  %or = or i71 %x, %y
168  %xor1 = xor i71 %x, %or
169  %xor2 = xor i71 %y, %or
170  %and = and i71 %xor1, %xor2
171  ret i71 %and
172}
173
174; (Y ^ (X | Y) ) & (X ^ (X | Y)) --> 0
175
176define <2 x i64> @or_xor_commute3(<2 x i64> %x, <2 x i64> %y) {
177; CHECK-LABEL: @or_xor_commute3(
178; CHECK-NEXT:    ret <2 x i64> zeroinitializer
179;
180  %or = or <2 x i64> %x, %y
181  %xor1 = xor <2 x i64> %y, %or
182  %xor2 = xor <2 x i64> %x, %or
183  %and = and <2 x i64> %xor1, %xor2
184  ret <2 x i64> %and
185}
186
187; ((X | Y) ^ X ) & (Y ^ (X | Y)) --> 0
188
189define i32 @or_xor_commute4(i32 %x, i32 %y) {
190; CHECK-LABEL: @or_xor_commute4(
191; CHECK-NEXT:    ret i32 0
192;
193  %or = or i32 %x, %y
194  %xor1 = xor i32 %or, %x
195  %xor2 = xor i32 %y, %or
196  %and = and i32 %xor1, %xor2
197  ret i32 %and
198}
199
200; ((X | Y) ^ Y ) & (X ^ (X | Y)) --> 0
201
202define i32 @or_xor_commute5(i32 %x, i32 %y) {
203; CHECK-LABEL: @or_xor_commute5(
204; CHECK-NEXT:    ret i32 0
205;
206  %or = or i32 %x, %y
207  %xor1 = xor i32 %or, %y
208  %xor2 = xor i32 %x, %or
209  %and = and i32 %xor1, %xor2
210  ret i32 %and
211}
212
213; (X ^ (X | Y) ) & ((X | Y) ^ Y) --> 0
214
215define i32 @or_xor_commute6(i32 %x, i32 %y) {
216; CHECK-LABEL: @or_xor_commute6(
217; CHECK-NEXT:    ret i32 0
218;
219  %or = or i32 %x, %y
220  %xor1 = xor i32 %x, %or
221  %xor2 = xor i32 %or, %y
222  %and = and i32 %xor1, %xor2
223  ret i32 %and
224}
225
226; (Y ^ (X | Y) ) & ((X | Y) ^ X) --> 0
227
228define i32 @or_xor_commute7(i32 %x, i32 %y) {
229; CHECK-LABEL: @or_xor_commute7(
230; CHECK-NEXT:    ret i32 0
231;
232  %or = or i32 %x, %y
233  %xor1 = xor i32 %y, %or
234  %xor2 = xor i32 %or, %x
235  %and = and i32 %xor1, %xor2
236  ret i32 %and
237}
238
239; (Y ^ (X | Y) ) & ((X | Y) ^ X) --> 0
240
241define i32 @or_xor_complex_op(i32 %x, i32 %in) {
242; CHECK-LABEL: @or_xor_complex_op(
243; CHECK-NEXT:    ret i32 0
244;
245  %y = or i32 %in, 1
246  %or = or i32 %x, %y
247  %xor1 = xor i32 %y, %or
248  %xor2 = xor i32 %or, %x
249  %and = and i32 %xor1, %xor2
250  ret i32 %and
251}
252
253define i32 @or_xor_limitation(i32 %x, i32 %y) {
254; CHECK-LABEL: @or_xor_limitation(
255; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
256; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[X]], [[Y]]
257; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[Y]], [[OR1]]
258; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[OR2]], [[X]]
259; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
260; CHECK-NEXT:    ret i32 [[AND]]
261;
262  %or1 = or i32 %y, %x
263  %or2 = or i32 %x, %y
264  %xor1 = xor i32 %y, %or1
265  %xor2 = xor i32 %or2, %x
266  %and = and i32 %xor1, %xor2
267  ret i32 %and
268}
269