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) {
8 ; CHECK-NEXT: [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
9 ; CHECK-NEXT: [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
10 ; CHECK-NEXT: ret i32 [[Z]]
13 %not = xor i32 %or, -1
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]]
28 %not = xor i32 %or, -1
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]]
42 %not = xor i32 %xor, -1
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]]
57 %not = xor i32 %xor, -1
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]]
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]]
79 %xor = xor i32 %x, %not
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]]
91 %xor = xor i32 %not, %y
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
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
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
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
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
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]]
179 %neg = xor i32 %x, -1
180 %xor = xor i32 %neg, %y
181 %and = and i32 %or, %xor
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
194 %and = and i32 %xor, %or
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
206 %and = and i32 %xor, %or
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]]
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
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
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
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
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]]
283 %and1 = and i32 %or, 1
284 %and2 = and i32 %b, -2
285 %xor = or i32 %and1, %and2
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
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
308 %xor = xor i8 %or, 12
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]]
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]]
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
342 %xor2 = xor i8 %or, 12
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]]
353 %xor = xor i8 %or1, 12
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
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
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
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
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
402 %or2 = or i32 %notx, %noty
403 %xor = xor i32 %or1, %or2
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
417 %or2 = or i32 %noty, %notx
418 %xor = xor i32 %or1, %or2
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
433 %xor = xor i32 %or1, %or2
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
448 %xor = xor i32 %or1, %or2
452 ; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
453 define i8 @test23(i8 %A) {
454 ; CHECK-LABEL: @test23(
455 ; CHECK-NEXT: ret i8 -1
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
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
485 %notor = xor i32 %or, -1
486 %res = or i32 %notor, %andnot
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]]
497 %not = xor i32 %b, -1
498 %ornot = or i32 %a, %not
499 %res = xor i32 %or, %ornot