[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / or-xor.ll
blobf0a3f58a83eca9f782061e03cd5d328688cc9a01
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 ; X | ~(X | Y) --> X | ~Y
6 define i32 @test1(i32 %x, i32 %y) {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
9 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
10 ; CHECK-NEXT:    ret i32 [[Z]]
12   %or = or i32 %x, %y
13   %not = xor i32 %or, -1
14   %z = or i32 %x, %not
15   ret i32 %z
18 ; Commute (rename) the inner 'or' operands:
19 ; Y | ~(X | Y) --> ~X | Y
21 define i32 @test2(i32 %x, i32 %y) {
22 ; CHECK-LABEL: @test2(
23 ; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
24 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
25 ; CHECK-NEXT:    ret i32 [[Z]]
27   %or = or i32 %x, %y
28   %not = xor i32 %or, -1
29   %z = or i32 %y, %not
30   ret i32 %z
33 ; X | ~(X ^ Y) --> X | ~Y
35 define i32 @test3(i32 %x, i32 %y) {
36 ; CHECK-LABEL: @test3(
37 ; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
38 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
39 ; CHECK-NEXT:    ret i32 [[Z]]
41   %xor = xor i32 %x, %y
42   %not = xor i32 %xor, -1
43   %z = or i32 %x, %not
44   ret i32 %z
47 ; Commute (rename) the 'xor' operands:
48 ; Y | ~(X ^ Y) --> ~X | Y
50 define i32 @test4(i32 %x, i32 %y) {
51 ; CHECK-LABEL: @test4(
52 ; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
53 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
54 ; CHECK-NEXT:    ret i32 [[Z]]
56   %xor = xor i32 %x, %y
57   %not = xor i32 %xor, -1
58   %z = or i32 %y, %not
59   ret i32 %z
62 define i32 @test7(i32 %x, i32 %y) {
63 ; CHECK-LABEL: @test7(
64 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
65 ; CHECK-NEXT:    ret i32 [[Z]]
67   %xor = xor i32 %x, %y
68   %z = or i32 %y, %xor
69   ret i32 %z
72 define i32 @test8(i32 %x, i32 %y) {
73 ; CHECK-LABEL: @test8(
74 ; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
75 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
76 ; CHECK-NEXT:    ret i32 [[Z]]
78   %not = xor i32 %y, -1
79   %xor = xor i32 %x, %not
80   %z = or i32 %y, %xor
81   ret i32 %z
84 define i32 @test9(i32 %x, i32 %y) {
85 ; CHECK-LABEL: @test9(
86 ; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
87 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
88 ; CHECK-NEXT:    ret i32 [[Z]]
90   %not = xor i32 %x, -1
91   %xor = xor i32 %not, %y
92   %z = or i32 %x, %xor
93   ret i32 %z
96 ; (A ^ B) | (~A ^ B) --> -1
98 define i32 @test10(i32 %A, i32 %B) {
99 ; CHECK-LABEL: @test10(
100 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
101 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
102 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
103 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]]
104 ; CHECK-NEXT:    ret i32 [[OR]]
106   %xor1 = xor i32 %B, %A
107   %not = xor i32 %A, -1
108   %xor2 = xor i32 %not, %B
109   %or = or i32 %xor1, %xor2
110   ret i32 %or
113 define i32 @test10_commuted(i32 %A, i32 %B) {
114 ; CHECK-LABEL: @test10_commuted(
115 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
116 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
117 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
118 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]]
119 ; CHECK-NEXT:    ret i32 [[OR]]
121   %xor1 = xor i32 %B, %A
122   %not = xor i32 %A, -1
123   %xor2 = xor i32 %not, %B
124   %or = or i32 %xor2, %xor1
125   ret i32 %or
128 define i32 @test10_extrause(i32 %A, i32 %B, i32* %dst) {
129 ; CHECK-LABEL: @test10_extrause(
130 ; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
131 ; CHECK-NEXT:    store i32 [[NOT]], i32* [[DST:%.*]], align 4
132 ; CHECK-NEXT:    ret i32 -1
134   %xor1 = xor i32 %B, %A
135   %not = xor i32 %A, -1
136   store i32 %not, i32* %dst
137   %xor2 = xor i32 %not, %B
138   %or = or i32 %xor1, %xor2
139   ret i32 %or
142 define i32 @test10_commuted_extrause(i32 %A, i32 %B, i32* %dst) {
143 ; CHECK-LABEL: @test10_commuted_extrause(
144 ; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
145 ; CHECK-NEXT:    store i32 [[NOT]], i32* [[DST:%.*]], align 4
146 ; CHECK-NEXT:    ret i32 -1
148   %xor1 = xor i32 %B, %A
149   %not = xor i32 %A, -1
150   store i32 %not, i32* %dst
151   %xor2 = xor i32 %not, %B
152   %or = or i32 %xor2, %xor1
153   ret i32 %or
156 ; (A ^ B) | ~(A ^ B) --> -1
157 define i32 @test10_canonical(i32 %A, i32 %B) {
158 ; CHECK-LABEL: @test10_canonical(
159 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
160 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[A]], [[B]]
161 ; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[XOR2]], -1
162 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[NOT]]
163 ; CHECK-NEXT:    ret i32 [[OR]]
165   %xor1 = xor i32 %B, %A
166   %xor2 = xor i32 %A, %B
167   %not = xor i32 %xor2, -1
168   %or = or i32 %xor1, %not
169   ret i32 %or
172 ; (x | y) & ((~x) ^ y) -> (x & y)
173 define i32 @test11(i32 %x, i32 %y) {
174 ; CHECK-LABEL: @test11(
175 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
176 ; CHECK-NEXT:    ret i32 [[AND]]
178   %or = or i32 %x, %y
179   %neg = xor i32 %x, -1
180   %xor = xor i32 %neg, %y
181   %and = and i32 %or, %xor
182   ret i32 %and
185 ; ((~x) ^ y) & (x | y) -> (x & y)
186 define i32 @test12(i32 %x, i32 %y) {
187 ; CHECK-LABEL: @test12(
188 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
189 ; CHECK-NEXT:    ret i32 [[AND]]
191   %neg = xor i32 %x, -1
192   %xor = xor i32 %neg, %y
193   %or = or i32 %x, %y
194   %and = and i32 %xor, %or
195   ret i32 %and
198 define i32 @test12_commuted(i32 %x, i32 %y) {
199 ; CHECK-LABEL: @test12_commuted(
200 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
201 ; CHECK-NEXT:    ret i32 [[AND]]
203   %neg = xor i32 %x, -1
204   %xor = xor i32 %neg, %y
205   %or = or i32 %y, %x
206   %and = and i32 %xor, %or
207   ret i32 %and
210 ; ((x | y) ^ (x ^ y)) -> (x & y)
211 define i32 @test13(i32 %x, i32 %y) {
212 ; CHECK-LABEL: @test13(
213 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
214 ; CHECK-NEXT:    ret i32 [[TMP1]]
216   %1 = xor i32 %y, %x
217   %2 = or i32 %y, %x
218   %3 = xor i32 %2, %1
219   ret i32 %3
222 ; ((x | ~y) ^ (~x | y)) -> x ^ y
223 define i32 @test14(i32 %x, i32 %y) {
224 ; CHECK-LABEL: @test14(
225 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
226 ; CHECK-NEXT:    ret i32 [[XOR]]
228   %noty = xor i32 %y, -1
229   %notx = xor i32 %x, -1
230   %or1 = or i32 %x, %noty
231   %or2 = or i32 %notx, %y
232   %xor = xor i32 %or1, %or2
233   ret i32 %xor
236 define i32 @test14_commuted(i32 %x, i32 %y) {
237 ; CHECK-LABEL: @test14_commuted(
238 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
239 ; CHECK-NEXT:    ret i32 [[XOR]]
241   %noty = xor i32 %y, -1
242   %notx = xor i32 %x, -1
243   %or1 = or i32 %noty, %x
244   %or2 = or i32 %notx, %y
245   %xor = xor i32 %or1, %or2
246   ret i32 %xor
249 ; ((x & ~y) ^ (~x & y)) -> x ^ y
250 define i32 @test15(i32 %x, i32 %y) {
251 ; CHECK-LABEL: @test15(
252 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
253 ; CHECK-NEXT:    ret i32 [[XOR]]
255   %noty = xor i32 %y, -1
256   %notx = xor i32 %x, -1
257   %and1 = and i32 %x, %noty
258   %and2 = and i32 %notx, %y
259   %xor = xor i32 %and1, %and2
260   ret i32 %xor
263 define i32 @test15_commuted(i32 %x, i32 %y) {
264 ; CHECK-LABEL: @test15_commuted(
265 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
266 ; CHECK-NEXT:    ret i32 [[XOR]]
268   %noty = xor i32 %y, -1
269   %notx = xor i32 %x, -1
270   %and1 = and i32 %noty, %x
271   %and2 = and i32 %notx, %y
272   %xor = xor i32 %and1, %and2
273   ret i32 %xor
276 define i32 @test16(i32 %a, i32 %b) {
277 ; CHECK-LABEL: @test16(
278 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 1
279 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]]
280 ; CHECK-NEXT:    ret i32 [[XOR]]
282   %or = xor i32 %a, %b
283   %and1 = and i32 %or, 1
284   %and2 = and i32 %b, -2
285   %xor = or i32 %and1, %and2
286   ret i32 %xor
289 define i8 @not_or(i8 %x) {
290 ; CHECK-LABEL: @not_or(
291 ; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
292 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[NOTX]], 7
293 ; CHECK-NEXT:    ret i8 [[OR]]
295   %notx = xor i8 %x, -1
296   %or = or i8 %notx, 7
297   ret i8 %or
300 define i8 @not_or_xor(i8 %x) {
301 ; CHECK-LABEL: @not_or_xor(
302 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8
303 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[TMP1]], -13
304 ; CHECK-NEXT:    ret i8 [[XOR]]
306   %notx = xor i8 %x, -1
307   %or = or i8 %notx, 7
308   %xor = xor i8 %or, 12
309   ret i8 %xor
312 define i8 @xor_or(i8 %x) {
313 ; CHECK-LABEL: @xor_or(
314 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 7
315 ; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 32
316 ; CHECK-NEXT:    ret i8 [[OR]]
318   %xor = xor i8 %x, 32
319   %or = or i8 %xor, 7
320   ret i8 %or
323 define i8 @xor_or2(i8 %x) {
324 ; CHECK-LABEL: @xor_or2(
325 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 7
326 ; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 32
327 ; CHECK-NEXT:    ret i8 [[OR]]
329   %xor = xor i8 %x, 33
330   %or = or i8 %xor, 7
331   ret i8 %or
334 define i8 @xor_or_xor(i8 %x) {
335 ; CHECK-LABEL: @xor_or_xor(
336 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 7
337 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 44
338 ; CHECK-NEXT:    ret i8 [[XOR2]]
340   %xor1 = xor i8 %x, 33
341   %or = or i8 %xor1, 7
342   %xor2 = xor i8 %or, 12
343   ret i8 %xor2
346 define i8 @or_xor_or(i8 %x) {
347 ; CHECK-LABEL: @or_xor_or(
348 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 39
349 ; CHECK-NEXT:    [[OR2:%.*]] = xor i8 [[TMP1]], 8
350 ; CHECK-NEXT:    ret i8 [[OR2]]
352   %or1 = or i8 %x, 33
353   %xor = xor i8 %or1, 12
354   %or2 = or i8 %xor, 7
355   ret i8 %or2
358 define i8 @test17(i8 %A, i8 %B) {
359 ; CHECK-LABEL: @test17(
360 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
361 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[A]], [[B]]
362 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 33
363 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR1]], [[XOR2]]
364 ; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
365 ; CHECK-NEXT:    ret i8 [[RES]]
367   %xor1 = xor i8 %B, %A
368   %not = xor i8 %A, 33
369   %xor2 = xor i8 %not, %B
370   %or = or i8 %xor1, %xor2
371   %res = mul i8 %or, %xor2 ; to increase the use count for the xor
372   ret i8 %res
375 define i8 @test18(i8 %A, i8 %B) {
376 ; CHECK-LABEL: @test18(
377 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
378 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[A]], [[B]]
379 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 33
380 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR2]], [[XOR1]]
381 ; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
382 ; CHECK-NEXT:    ret i8 [[RES]]
384   %xor1 = xor i8 %B, %A
385   %not = xor i8 %A, 33
386   %xor2 = xor i8 %not, %B
387   %or = or i8 %xor2, %xor1
388   %res = mul i8 %or, %xor2 ; to increase the use count for the xor
389   ret i8 %res
392 ; ((x | y) ^ (~x | ~y)) -> ~(x ^ y)
393 define i32 @test19(i32 %x, i32 %y) {
394 ; CHECK-LABEL: @test19(
395 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
396 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
397 ; CHECK-NEXT:    ret i32 [[XOR]]
399   %noty = xor i32 %y, -1
400   %notx = xor i32 %x, -1
401   %or1 = or i32 %x, %y
402   %or2 = or i32 %notx, %noty
403   %xor = xor i32 %or1, %or2
404   ret i32 %xor
407 ; ((x | y) ^ (~y | ~x)) -> ~(x ^ y)
408 define i32 @test20(i32 %x, i32 %y) {
409 ; CHECK-LABEL: @test20(
410 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
411 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
412 ; CHECK-NEXT:    ret i32 [[XOR]]
414   %noty = xor i32 %y, -1
415   %notx = xor i32 %x, -1
416   %or1 = or i32 %x, %y
417   %or2 = or i32 %noty, %notx
418   %xor = xor i32 %or1, %or2
419   ret i32 %xor
422 ; ((~x | ~y) ^ (x | y)) -> ~(x ^ y)
423 define i32 @test21(i32 %x, i32 %y) {
424 ; CHECK-LABEL: @test21(
425 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
426 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
427 ; CHECK-NEXT:    ret i32 [[XOR]]
429   %noty = xor i32 %y, -1
430   %notx = xor i32 %x, -1
431   %or1 = or i32 %notx, %noty
432   %or2 = or i32 %x, %y
433   %xor = xor i32 %or1, %or2
434   ret i32 %xor
437 ; ((~x | ~y) ^ (y | x)) -> ~(x ^ y)
438 define i32 @test22(i32 %x, i32 %y) {
439 ; CHECK-LABEL: @test22(
440 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
441 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
442 ; CHECK-NEXT:    ret i32 [[XOR]]
444   %noty = xor i32 %y, -1
445   %notx = xor i32 %x, -1
446   %or1 = or i32 %notx, %noty
447   %or2 = or i32 %y, %x
448   %xor = xor i32 %or1, %or2
449   ret i32 %xor
452 ; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
453 define i8 @test23(i8 %A) {
454 ; CHECK-LABEL: @test23(
455 ; CHECK-NEXT:    ret i8 -1
457   %B = or i8 %A, -2
458   %C = xor i8 %B, 13
459   %D = or i8 %C, 1
460   %E = xor i8 %D, 12
461   ret i8 %E
464 define i8 @test23v(<2 x i8> %A) {
465 ; CHECK-LABEL: @test23v(
466 ; CHECK-NEXT:    ret i8 -1
468   %B = or <2 x i8> %A, <i8 -2, i8 0>
469   %CV = xor <2 x i8> %B, <i8 13, i8 13>
470   %C = extractelement <2 x i8> %CV, i32 0
471   %D = or i8 %C, 1
472   %E = xor i8 %D, 12
473   ret i8 %E
476 ; ~(a | b) | (~a & b);
477 define i32 @PR45977_f1(i32 %a, i32 %b) {
478 ; CHECK-LABEL: @PR45977_f1(
479 ; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
480 ; CHECK-NEXT:    ret i32 [[NOT]]
482   %not = xor i32 %a, -1
483   %andnot = and i32 %not, %b
484   %or = or i32 %a, %b
485   %notor = xor i32 %or, -1
486   %res = or i32 %notor, %andnot
487   ret i32 %res
490 ; (a | b) ^ (a | ~b)
491 define i32 @PR45977_f2(i32 %a, i32 %b) {
492 ; CHECK-LABEL: @PR45977_f2(
493 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
494 ; CHECK-NEXT:    ret i32 [[TMP1]]
496   %or = or i32 %a, %b
497   %not = xor i32 %b, -1
498   %ornot = or i32 %a, %not
499   %res = xor i32 %or, %ornot
500   ret i32 %res