[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / or-xor.ll
blobab5f2f8ef53bb60276d46a7a2a2df0b1f86febdc
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 @test5(i32 %x, i32 %y) {
63 ; CHECK-LABEL: @test5(
64 ; CHECK-NEXT:    ret i32 -1
66   %and = and i32 %x, %y
67   %not = xor i32 %and, -1
68   %z = or i32 %x, %not
69   ret i32 %z
72 define i32 @test6(i32 %x, i32 %y) {
73 ; CHECK-LABEL: @test6(
74 ; CHECK-NEXT:    ret i32 -1
76   %and = and i32 %x, %y
77   %not = xor i32 %and, -1
78   %z = or i32 %y, %not
79   ret i32 %z
82 define i32 @test7(i32 %x, i32 %y) {
83 ; CHECK-LABEL: @test7(
84 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
85 ; CHECK-NEXT:    ret i32 [[Z]]
87   %xor = xor i32 %x, %y
88   %z = or i32 %y, %xor
89   ret i32 %z
92 define i32 @test8(i32 %x, i32 %y) {
93 ; CHECK-LABEL: @test8(
94 ; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
95 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
96 ; CHECK-NEXT:    ret i32 [[Z]]
98   %not = xor i32 %y, -1
99   %xor = xor i32 %x, %not
100   %z = or i32 %y, %xor
101   ret i32 %z
104 define i32 @test9(i32 %x, i32 %y) {
105 ; CHECK-LABEL: @test9(
106 ; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
107 ; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
108 ; CHECK-NEXT:    ret i32 [[Z]]
110   %not = xor i32 %x, -1
111   %xor = xor i32 %not, %y
112   %z = or i32 %x, %xor
113   ret i32 %z
116 define i32 @test10(i32 %A, i32 %B) {
117 ; CHECK-LABEL: @test10(
118 ; CHECK-NEXT:    ret i32 -1
120   %xor1 = xor i32 %B, %A
121   %not = xor i32 %A, -1
122   %xor2 = xor i32 %not, %B
123   %or = or i32 %xor1, %xor2
124   ret i32 %or
127 define i32 @test10_commuted(i32 %A, i32 %B) {
128 ; CHECK-LABEL: @test10_commuted(
129 ; CHECK-NEXT:    ret i32 -1
131   %xor1 = xor i32 %B, %A
132   %not = xor i32 %A, -1
133   %xor2 = xor i32 %not, %B
134   %or = or i32 %xor2, %xor1
135   ret i32 %or
138 ; (x | y) & ((~x) ^ y) -> (x & y)
139 define i32 @test11(i32 %x, i32 %y) {
140 ; CHECK-LABEL: @test11(
141 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
142 ; CHECK-NEXT:    ret i32 [[AND]]
144   %or = or i32 %x, %y
145   %neg = xor i32 %x, -1
146   %xor = xor i32 %neg, %y
147   %and = and i32 %or, %xor
148   ret i32 %and
151 ; ((~x) ^ y) & (x | y) -> (x & y)
152 define i32 @test12(i32 %x, i32 %y) {
153 ; CHECK-LABEL: @test12(
154 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
155 ; CHECK-NEXT:    ret i32 [[AND]]
157   %neg = xor i32 %x, -1
158   %xor = xor i32 %neg, %y
159   %or = or i32 %x, %y
160   %and = and i32 %xor, %or
161   ret i32 %and
164 define i32 @test12_commuted(i32 %x, i32 %y) {
165 ; CHECK-LABEL: @test12_commuted(
166 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
167 ; CHECK-NEXT:    ret i32 [[AND]]
169   %neg = xor i32 %x, -1
170   %xor = xor i32 %neg, %y
171   %or = or i32 %y, %x
172   %and = and i32 %xor, %or
173   ret i32 %and
176 ; ((x | y) ^ (x ^ y)) -> (x & y)
177 define i32 @test13(i32 %x, i32 %y) {
178 ; CHECK-LABEL: @test13(
179 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
180 ; CHECK-NEXT:    ret i32 [[TMP1]]
182   %1 = xor i32 %y, %x
183   %2 = or i32 %y, %x
184   %3 = xor i32 %2, %1
185   ret i32 %3
188 ; ((x | ~y) ^ (~x | y)) -> x ^ y
189 define i32 @test14(i32 %x, i32 %y) {
190 ; CHECK-LABEL: @test14(
191 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
192 ; CHECK-NEXT:    ret i32 [[XOR]]
194   %noty = xor i32 %y, -1
195   %notx = xor i32 %x, -1
196   %or1 = or i32 %x, %noty
197   %or2 = or i32 %notx, %y
198   %xor = xor i32 %or1, %or2
199   ret i32 %xor
202 define i32 @test14_commuted(i32 %x, i32 %y) {
203 ; CHECK-LABEL: @test14_commuted(
204 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
205 ; CHECK-NEXT:    ret i32 [[XOR]]
207   %noty = xor i32 %y, -1
208   %notx = xor i32 %x, -1
209   %or1 = or i32 %noty, %x
210   %or2 = or i32 %notx, %y
211   %xor = xor i32 %or1, %or2
212   ret i32 %xor
215 ; ((x & ~y) ^ (~x & y)) -> x ^ y
216 define i32 @test15(i32 %x, i32 %y) {
217 ; CHECK-LABEL: @test15(
218 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
219 ; CHECK-NEXT:    ret i32 [[XOR]]
221   %noty = xor i32 %y, -1
222   %notx = xor i32 %x, -1
223   %and1 = and i32 %x, %noty
224   %and2 = and i32 %notx, %y
225   %xor = xor i32 %and1, %and2
226   ret i32 %xor
229 define i32 @test15_commuted(i32 %x, i32 %y) {
230 ; CHECK-LABEL: @test15_commuted(
231 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
232 ; CHECK-NEXT:    ret i32 [[XOR]]
234   %noty = xor i32 %y, -1
235   %notx = xor i32 %x, -1
236   %and1 = and i32 %noty, %x
237   %and2 = and i32 %notx, %y
238   %xor = xor i32 %and1, %and2
239   ret i32 %xor
242 define i32 @test16(i32 %a, i32 %b) {
243 ; CHECK-LABEL: @test16(
244 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 1
245 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]]
246 ; CHECK-NEXT:    ret i32 [[XOR]]
248   %or = xor i32 %a, %b
249   %and1 = and i32 %or, 1
250   %and2 = and i32 %b, -2
251   %xor = or i32 %and1, %and2
252   ret i32 %xor
255 define i8 @not_or(i8 %x) {
256 ; CHECK-LABEL: @not_or(
257 ; CHECK-NEXT:    [[NOTX:%.*]] = or i8 [[X:%.*]], 7
258 ; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[NOTX]], -8
259 ; CHECK-NEXT:    ret i8 [[OR]]
261   %notx = xor i8 %x, -1
262   %or = or i8 %notx, 7
263   ret i8 %or
266 define i8 @not_or_xor(i8 %x) {
267 ; CHECK-LABEL: @not_or_xor(
268 ; CHECK-NEXT:    [[NOTX:%.*]] = or i8 [[X:%.*]], 7
269 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[NOTX]], -12
270 ; CHECK-NEXT:    ret i8 [[XOR]]
272   %notx = xor i8 %x, -1
273   %or = or i8 %notx, 7
274   %xor = xor i8 %or, 12
275   ret i8 %xor
278 define i8 @xor_or(i8 %x) {
279 ; CHECK-LABEL: @xor_or(
280 ; CHECK-NEXT:    [[XOR:%.*]] = or i8 [[X:%.*]], 7
281 ; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[XOR]], 32
282 ; CHECK-NEXT:    ret i8 [[OR]]
284   %xor = xor i8 %x, 32
285   %or = or i8 %xor, 7
286   ret i8 %or
289 define i8 @xor_or2(i8 %x) {
290 ; CHECK-LABEL: @xor_or2(
291 ; CHECK-NEXT:    [[XOR:%.*]] = or i8 [[X:%.*]], 7
292 ; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[XOR]], 32
293 ; CHECK-NEXT:    ret i8 [[OR]]
295   %xor = xor i8 %x, 33
296   %or = or i8 %xor, 7
297   ret i8 %or
300 define i8 @xor_or_xor(i8 %x) {
301 ; CHECK-LABEL: @xor_or_xor(
302 ; CHECK-NEXT:    [[XOR1:%.*]] = or i8 [[X:%.*]], 7
303 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[XOR1]], 44
304 ; CHECK-NEXT:    ret i8 [[XOR2]]
306   %xor1 = xor i8 %x, 33
307   %or = or i8 %xor1, 7
308   %xor2 = xor i8 %or, 12
309   ret i8 %xor2
312 define i8 @or_xor_or(i8 %x) {
313 ; CHECK-LABEL: @or_xor_or(
314 ; CHECK-NEXT:    [[XOR:%.*]] = or i8 [[X:%.*]], 39
315 ; CHECK-NEXT:    [[OR2:%.*]] = xor i8 [[XOR]], 8
316 ; CHECK-NEXT:    ret i8 [[OR2]]
318   %or1 = or i8 %x, 33
319   %xor = xor i8 %or1, 12
320   %or2 = or i8 %xor, 7
321   ret i8 %or2
324 define i8 @test17(i8 %A, i8 %B) {
325 ; CHECK-LABEL: @test17(
326 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
327 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[A]], 33
328 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[NOT]], [[B]]
329 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR1]], 33
330 ; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
331 ; CHECK-NEXT:    ret i8 [[RES]]
333   %xor1 = xor i8 %B, %A
334   %not = xor i8 %A, 33
335   %xor2 = xor i8 %not, %B
336   %or = or i8 %xor1, %xor2
337   %res = mul i8 %or, %xor2 ; to increase the use count for the xor
338   ret i8 %res
341 define i8 @test18(i8 %A, i8 %B) {
342 ; CHECK-LABEL: @test18(
343 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
344 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[A]], 33
345 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[NOT]], [[B]]
346 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR1]], 33
347 ; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
348 ; CHECK-NEXT:    ret i8 [[RES]]
350   %xor1 = xor i8 %B, %A
351   %not = xor i8 %A, 33
352   %xor2 = xor i8 %not, %B
353   %or = or i8 %xor2, %xor1
354   %res = mul i8 %or, %xor2 ; to increase the use count for the xor
355   ret i8 %res
358 ; ((x | y) ^ (~x | ~y)) -> ~(x ^ y)
359 define i32 @test19(i32 %x, i32 %y) {
360 ; CHECK-LABEL: @test19(
361 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
362 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
363 ; CHECK-NEXT:    ret i32 [[XOR]]
365   %noty = xor i32 %y, -1
366   %notx = xor i32 %x, -1
367   %or1 = or i32 %x, %y
368   %or2 = or i32 %notx, %noty
369   %xor = xor i32 %or1, %or2
370   ret i32 %xor
373 ; ((x | y) ^ (~y | ~x)) -> ~(x ^ y)
374 define i32 @test20(i32 %x, i32 %y) {
375 ; CHECK-LABEL: @test20(
376 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
377 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
378 ; CHECK-NEXT:    ret i32 [[XOR]]
380   %noty = xor i32 %y, -1
381   %notx = xor i32 %x, -1
382   %or1 = or i32 %x, %y
383   %or2 = or i32 %noty, %notx
384   %xor = xor i32 %or1, %or2
385   ret i32 %xor
388 ; ((~x | ~y) ^ (x | y)) -> ~(x ^ y)
389 define i32 @test21(i32 %x, i32 %y) {
390 ; CHECK-LABEL: @test21(
391 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
392 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
393 ; CHECK-NEXT:    ret i32 [[XOR]]
395   %noty = xor i32 %y, -1
396   %notx = xor i32 %x, -1
397   %or1 = or i32 %notx, %noty
398   %or2 = or i32 %x, %y
399   %xor = xor i32 %or1, %or2
400   ret i32 %xor
403 ; ((~x | ~y) ^ (y | x)) -> ~(x ^ y)
404 define i32 @test22(i32 %x, i32 %y) {
405 ; CHECK-LABEL: @test22(
406 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
407 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
408 ; CHECK-NEXT:    ret i32 [[XOR]]
410   %noty = xor i32 %y, -1
411   %notx = xor i32 %x, -1
412   %or1 = or i32 %notx, %noty
413   %or2 = or i32 %y, %x
414   %xor = xor i32 %or1, %or2
415   ret i32 %xor