Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / and-or-not.ll
blobca093eba1b568858788023d3648b574dd370e455
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i4)
6 ; PR1510
8 ; (a | b) & ~(a & b) --> a ^ b
10 define i32 @and_to_xor1(i32 %a, i32 %b) {
11 ; CHECK-LABEL: @and_to_xor1(
12 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
13 ; CHECK-NEXT:    ret i32 [[AND2]]
15   %or = or i32 %a, %b
16   %and = and i32 %a, %b
17   %not = xor i32 %and, -1
18   %and2 = and i32 %or, %not
19   ret i32 %and2
22 ; ~(a & b) & (a | b) --> a ^ b
24 define i32 @and_to_xor2(i32 %a, i32 %b) {
25 ; CHECK-LABEL: @and_to_xor2(
26 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
27 ; CHECK-NEXT:    ret i32 [[AND2]]
29   %or = or i32 %a, %b
30   %and = and i32 %a, %b
31   %not = xor i32 %and, -1
32   %and2 = and i32 %not, %or
33   ret i32 %and2
36 ; (a | b) & ~(b & a) --> a ^ b
38 define i32 @and_to_xor3(i32 %a, i32 %b) {
39 ; CHECK-LABEL: @and_to_xor3(
40 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
41 ; CHECK-NEXT:    ret i32 [[AND2]]
43   %or = or i32 %a, %b
44   %and = and i32 %b, %a
45   %not = xor i32 %and, -1
46   %and2 = and i32 %or, %not
47   ret i32 %and2
50 ; ~(a & b) & (b | a) --> a ^ b
52 define i32 @and_to_xor4(i32 %a, i32 %b) {
53 ; CHECK-LABEL: @and_to_xor4(
54 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
55 ; CHECK-NEXT:    ret i32 [[AND2]]
57   %or = or i32 %b, %a
58   %and = and i32 %a, %b
59   %not = xor i32 %and, -1
60   %and2 = and i32 %not, %or
61   ret i32 %and2
64 define <4 x i32> @and_to_xor1_vec(<4 x i32> %a, <4 x i32> %b) {
65 ; CHECK-LABEL: @and_to_xor1_vec(
66 ; CHECK-NEXT:    [[AND2:%.*]] = xor <4 x i32> [[A:%.*]], [[B:%.*]]
67 ; CHECK-NEXT:    ret <4 x i32> [[AND2]]
69   %or = or <4 x i32> %a, %b
70   %and = and <4 x i32> %a, %b
71   %not = xor <4 x i32> %and, < i32 -1, i32 -1, i32 -1, i32 -1 >
72   %and2 = and <4 x i32> %or, %not
73   ret <4 x i32> %and2
76 ; In the next 4 tests, cast instructions are used to thwart operand complexity
77 ; canonicalizations, so we can test all of the commuted patterns.
79 ; (a | ~b) & (~a | b) --> ~(a ^ b)
81 define i32 @and_to_nxor1(float %fa, float %fb) {
82 ; CHECK-LABEL: @and_to_nxor1(
83 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
84 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
85 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
86 ; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP1]], -1
87 ; CHECK-NEXT:    ret i32 [[AND]]
89   %a = fptosi float %fa to i32
90   %b = fptosi float %fb to i32
91   %nota = xor i32 %a, -1
92   %notb = xor i32 %b, -1
93   %or1 = or i32 %a, %notb
94   %or2 = or i32 %nota, %b
95   %and = and i32 %or1, %or2
96   ret i32 %and
99 ; (a | ~b) & (b | ~a) --> ~(a ^ b)
101 define i32 @and_to_nxor2(float %fa, float %fb) {
102 ; CHECK-LABEL: @and_to_nxor2(
103 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
104 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
105 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
106 ; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP1]], -1
107 ; CHECK-NEXT:    ret i32 [[AND]]
109   %a = fptosi float %fa to i32
110   %b = fptosi float %fb to i32
111   %nota = xor i32 %a, -1
112   %notb = xor i32 %b, -1
113   %or1 = or i32 %a, %notb
114   %or2 = or i32 %b, %nota
115   %and = and i32 %or1, %or2
116   ret i32 %and
119 ; (~a | b) & (a | ~b) --> ~(a ^ b)
121 define i32 @and_to_nxor3(float %fa, float %fb) {
122 ; CHECK-LABEL: @and_to_nxor3(
123 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
124 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
125 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[A]]
126 ; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP1]], -1
127 ; CHECK-NEXT:    ret i32 [[AND]]
129   %a = fptosi float %fa to i32
130   %b = fptosi float %fb to i32
131   %nota = xor i32 %a, -1
132   %notb = xor i32 %b, -1
133   %or1 = or i32 %nota, %b
134   %or2 = or i32 %a, %notb
135   %and = and i32 %or1, %or2
136   ret i32 %and
139 ; (~a | b) & (~b | a) --> ~(a ^ b)
141 define i32 @and_to_nxor4(float %fa, float %fb) {
142 ; CHECK-LABEL: @and_to_nxor4(
143 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
144 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
145 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[A]]
146 ; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP1]], -1
147 ; CHECK-NEXT:    ret i32 [[AND]]
149   %a = fptosi float %fa to i32
150   %b = fptosi float %fb to i32
151   %nota = xor i32 %a, -1
152   %notb = xor i32 %b, -1
153   %or1 = or i32 %nota, %b
154   %or2 = or i32 %notb, %a
155   %and = and i32 %or1, %or2
156   ret i32 %and
159 ; (a & ~b) | (~a & b) --> a ^ b
161 define i32 @or_to_xor1(float %fa, float %fb) {
162 ; CHECK-LABEL: @or_to_xor1(
163 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
164 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
165 ; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[A]], [[B]]
166 ; CHECK-NEXT:    ret i32 [[OR]]
168   %a = fptosi float %fa to i32
169   %b = fptosi float %fb to i32
170   %nota = xor i32 %a, -1
171   %notb = xor i32 %b, -1
172   %and1 = and i32 %a, %notb
173   %and2 = and i32 %nota, %b
174   %or = or i32 %and1, %and2
175   ret i32 %or
178 ; (a & ~b) | (b & ~a) --> a ^ b
180 define i32 @or_to_xor2(float %fa, float %fb) {
181 ; CHECK-LABEL: @or_to_xor2(
182 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
183 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
184 ; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[A]], [[B]]
185 ; CHECK-NEXT:    ret i32 [[OR]]
187   %a = fptosi float %fa to i32
188   %b = fptosi float %fb to i32
189   %nota = xor i32 %a, -1
190   %notb = xor i32 %b, -1
191   %and1 = and i32 %a, %notb
192   %and2 = and i32 %b, %nota
193   %or = or i32 %and1, %and2
194   ret i32 %or
197 ; (~a & b) | (~b & a) --> a ^ b
199 define i32 @or_to_xor3(float %fa, float %fb) {
200 ; CHECK-LABEL: @or_to_xor3(
201 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
202 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
203 ; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[B]], [[A]]
204 ; CHECK-NEXT:    ret i32 [[OR]]
206   %a = fptosi float %fa to i32
207   %b = fptosi float %fb to i32
208   %nota = xor i32 %a, -1
209   %notb = xor i32 %b, -1
210   %and1 = and i32 %nota, %b
211   %and2 = and i32 %notb, %a
212   %or = or i32 %and1, %and2
213   ret i32 %or
216 ; (~a & b) | (a & ~b) --> a ^ b
218 define i32 @or_to_xor4(float %fa, float %fb) {
219 ; CHECK-LABEL: @or_to_xor4(
220 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
221 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
222 ; CHECK-NEXT:    [[OR:%.*]] = xor i32 [[B]], [[A]]
223 ; CHECK-NEXT:    ret i32 [[OR]]
225   %a = fptosi float %fa to i32
226   %b = fptosi float %fb to i32
227   %nota = xor i32 %a, -1
228   %notb = xor i32 %b, -1
229   %and1 = and i32 %nota, %b
230   %and2 = and i32 %a, %notb
231   %or = or i32 %and1, %and2
232   ret i32 %or
235 ; (a & b) | ~(a | b) --> ~(a ^ b)
237 define i32 @or_to_nxor1(i32 %a, i32 %b) {
238 ; CHECK-LABEL: @or_to_nxor1(
239 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
240 ; CHECK-NEXT:    [[OR2:%.*]] = xor i32 [[TMP1]], -1
241 ; CHECK-NEXT:    ret i32 [[OR2]]
243   %and = and i32 %a, %b
244   %or = or i32 %a, %b
245   %notor = xor i32 %or, -1
246   %or2 = or i32 %and, %notor
247   ret i32 %or2
250 ; (a & b) | ~(b | a) --> ~(a ^ b)
252 define i32 @or_to_nxor2(i32 %a, i32 %b) {
253 ; CHECK-LABEL: @or_to_nxor2(
254 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
255 ; CHECK-NEXT:    [[OR2:%.*]] = xor i32 [[TMP1]], -1
256 ; CHECK-NEXT:    ret i32 [[OR2]]
258   %and = and i32 %a, %b
259   %or = or i32 %b, %a
260   %notor = xor i32 %or, -1
261   %or2 = or i32 %and, %notor
262   ret i32 %or2
265 ; ~(a | b) | (a & b) --> ~(a ^ b)
267 define i32 @or_to_nxor3(i32 %a, i32 %b) {
268 ; CHECK-LABEL: @or_to_nxor3(
269 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
270 ; CHECK-NEXT:    [[OR2:%.*]] = xor i32 [[TMP1]], -1
271 ; CHECK-NEXT:    ret i32 [[OR2]]
273   %and = and i32 %a, %b
274   %or = or i32 %a, %b
275   %notor = xor i32 %or, -1
276   %or2 = or i32 %notor, %and
277   ret i32 %or2
280 ; ~(a | b) | (b & a) --> ~(a ^ b)
282 define i32 @or_to_nxor4(i32 %a, i32 %b) {
283 ; CHECK-LABEL: @or_to_nxor4(
284 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
285 ; CHECK-NEXT:    [[OR2:%.*]] = xor i32 [[TMP1]], -1
286 ; CHECK-NEXT:    ret i32 [[OR2]]
288   %and = and i32 %b, %a
289   %or = or i32 %a, %b
290   %notor = xor i32 %or, -1
291   %or2 = or i32 %notor, %and
292   ret i32 %or2
295 ; (a & b) ^ (a | b) --> a ^ b
297 define i32 @xor_to_xor1(i32 %a, i32 %b) {
298 ; CHECK-LABEL: @xor_to_xor1(
299 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
300 ; CHECK-NEXT:    ret i32 [[XOR]]
302   %and = and i32 %a, %b
303   %or = or i32 %a, %b
304   %xor = xor i32 %and, %or
305   ret i32 %xor
308 ; (a & b) ^ (b | a) --> a ^ b
310 define i32 @xor_to_xor2(i32 %a, i32 %b) {
311 ; CHECK-LABEL: @xor_to_xor2(
312 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
313 ; CHECK-NEXT:    ret i32 [[XOR]]
315   %and = and i32 %a, %b
316   %or = or i32 %b, %a
317   %xor = xor i32 %and, %or
318   ret i32 %xor
321 ; (a | b) ^ (a & b) --> a ^ b
323 define i32 @xor_to_xor3(i32 %a, i32 %b) {
324 ; CHECK-LABEL: @xor_to_xor3(
325 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
326 ; CHECK-NEXT:    ret i32 [[XOR]]
328   %or = or i32 %a, %b
329   %and = and i32 %a, %b
330   %xor = xor i32 %or, %and
331   ret i32 %xor
334 ; (a | b) ^ (b & a) --> a ^ b
336 define i32 @xor_to_xor4(i32 %a, i32 %b) {
337 ; CHECK-LABEL: @xor_to_xor4(
338 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
339 ; CHECK-NEXT:    ret i32 [[XOR]]
341   %or = or i32 %a, %b
342   %and = and i32 %b, %a
343   %xor = xor i32 %or, %and
344   ret i32 %xor
347 ; (a | ~b) ^ (~a | b) --> a ^ b
349 ; In the next 8 tests, cast instructions are used to thwart operand complexity
350 ; canonicalizations, so we can test all of the commuted patterns.
352 define i32 @xor_to_xor5(float %fa, float %fb) {
353 ; CHECK-LABEL: @xor_to_xor5(
354 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
355 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
356 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
357 ; CHECK-NEXT:    ret i32 [[XOR]]
359   %a = fptosi float %fa to i32
360   %b = fptosi float %fb to i32
361   %nota = xor i32 %a, -1
362   %notb = xor i32 %b, -1
363   %or1 = or i32 %a, %notb
364   %or2 = or i32 %nota, %b
365   %xor = xor i32 %or1, %or2
366   ret i32 %xor
369 ; (a | ~b) ^ (b | ~a) --> a ^ b
371 define i32 @xor_to_xor6(float %fa, float %fb) {
372 ; CHECK-LABEL: @xor_to_xor6(
373 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
374 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
375 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
376 ; CHECK-NEXT:    ret i32 [[XOR]]
378   %a = fptosi float %fa to i32
379   %b = fptosi float %fb to i32
380   %nota = xor i32 %a, -1
381   %notb = xor i32 %b, -1
382   %or1 = or i32 %a, %notb
383   %or2 = or i32 %b, %nota
384   %xor = xor i32 %or1, %or2
385   ret i32 %xor
388 ; (~a | b) ^ (a | ~b) --> a ^ b
390 define i32 @xor_to_xor7(float %fa, float %fb) {
391 ; CHECK-LABEL: @xor_to_xor7(
392 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
393 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
394 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
395 ; CHECK-NEXT:    ret i32 [[XOR]]
397   %a = fptosi float %fa to i32
398   %b = fptosi float %fb to i32
399   %nota = xor i32 %a, -1
400   %notb = xor i32 %b, -1
401   %or1 = or i32 %a, %notb
402   %or2 = or i32 %nota, %b
403   %xor = xor i32 %or2, %or1
404   ret i32 %xor
407 ; (~a | b) ^ (~b | a) --> a ^ b
409 define i32 @xor_to_xor8(float %fa, float %fb) {
410 ; CHECK-LABEL: @xor_to_xor8(
411 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
412 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
413 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
414 ; CHECK-NEXT:    ret i32 [[XOR]]
416   %a = fptosi float %fa to i32
417   %b = fptosi float %fb to i32
418   %nota = xor i32 %a, -1
419   %notb = xor i32 %b, -1
420   %or1 = or i32 %notb, %a
421   %or2 = or i32 %nota, %b
422   %xor = xor i32 %or2, %or1
423   ret i32 %xor
426 ; (a & ~b) ^ (~a & b) --> a ^ b
428 define i32 @xor_to_xor9(float %fa, float %fb) {
429 ; CHECK-LABEL: @xor_to_xor9(
430 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
431 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
432 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
433 ; CHECK-NEXT:    ret i32 [[XOR]]
435   %a = fptosi float %fa to i32
436   %b = fptosi float %fb to i32
437   %nota = xor i32 %a, -1
438   %notb = xor i32 %b, -1
439   %and1 = and i32 %a, %notb
440   %and2 = and i32 %nota, %b
441   %xor = xor i32 %and1, %and2
442   ret i32 %xor
445 ; (a & ~b) ^ (b & ~a) --> a ^ b
447 define i32 @xor_to_xor10(float %fa, float %fb) {
448 ; CHECK-LABEL: @xor_to_xor10(
449 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
450 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
451 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
452 ; CHECK-NEXT:    ret i32 [[XOR]]
454   %a = fptosi float %fa to i32
455   %b = fptosi float %fb to i32
456   %nota = xor i32 %a, -1
457   %notb = xor i32 %b, -1
458   %and1 = and i32 %a, %notb
459   %and2 = and i32 %b, %nota
460   %xor = xor i32 %and1, %and2
461   ret i32 %xor
464 ; (~a & b) ^ (a & ~b) --> a ^ b
466 define i32 @xor_to_xor11(float %fa, float %fb) {
467 ; CHECK-LABEL: @xor_to_xor11(
468 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
469 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
470 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
471 ; CHECK-NEXT:    ret i32 [[XOR]]
473   %a = fptosi float %fa to i32
474   %b = fptosi float %fb to i32
475   %nota = xor i32 %a, -1
476   %notb = xor i32 %b, -1
477   %and1 = and i32 %a, %notb
478   %and2 = and i32 %nota, %b
479   %xor = xor i32 %and2, %and1
480   ret i32 %xor
483 ; (~a & b) ^ (~b & a) --> a ^ b
485 define i32 @xor_to_xor12(float %fa, float %fb) {
486 ; CHECK-LABEL: @xor_to_xor12(
487 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
488 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
489 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
490 ; CHECK-NEXT:    ret i32 [[XOR]]
492   %a = fptosi float %fa to i32
493   %b = fptosi float %fb to i32
494   %nota = xor i32 %a, -1
495   %notb = xor i32 %b, -1
496   %and1 = and i32 %notb, %a
497   %and2 = and i32 %nota, %b
498   %xor = xor i32 %and2, %and1
499   ret i32 %xor
502 ; https://bugs.llvm.org/show_bug.cgi?id=32830
503 ; Make sure we're matching operands correctly and not folding things wrongly.
505 define i64 @PR32830(i64 %a, i64 %b, i64 %c) {
506 ; CHECK-LABEL: @PR32830(
507 ; CHECK-NEXT:    [[NOTA:%.*]] = xor i64 [[A:%.*]], -1
508 ; CHECK-NEXT:    [[NOTB:%.*]] = xor i64 [[B:%.*]], -1
509 ; CHECK-NEXT:    [[OR1:%.*]] = or i64 [[NOTB]], [[A]]
510 ; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[NOTA]], [[C:%.*]]
511 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[OR1]], [[OR2]]
512 ; CHECK-NEXT:    ret i64 [[AND]]
514   %nota = xor i64 %a, -1
515   %notb = xor i64 %b, -1
516   %or1 = or i64 %notb, %a
517   %or2 = or i64 %nota, %c
518   %and = and i64 %or1, %or2
519   ret i64 %and
522 ; (~a | b) & (~b | a) --> ~(a ^ b)
523 ; TODO: this increases instruction count if the pieces have additional users
524 define i32 @and_to_nxor_multiuse(float %fa, float %fb) {
525 ; CHECK-LABEL: @and_to_nxor_multiuse(
526 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
527 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
528 ; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
529 ; CHECK-NEXT:    [[NOTB:%.*]] = xor i32 [[B]], -1
530 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[NOTA]], [[B]]
531 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[NOTB]], [[A]]
532 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[OR1]], [[OR2]]
533 ; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[OR1]], [[OR2]]
534 ; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], [[AND]]
535 ; CHECK-NEXT:    ret i32 [[MUL2]]
537   %a = fptosi float %fa to i32
538   %b = fptosi float %fb to i32
539   %nota = xor i32 %a, -1
540   %notb = xor i32 %b, -1
541   %or1 = or i32 %nota, %b
542   %or2 = or i32 %notb, %a
543   %and = and i32 %or1, %or2
544   %mul1 = mul i32 %or1, %or2 ; here to increase the use count of the inputs to the and
545   %mul2 = mul i32 %mul1, %and
546   ret i32 %mul2
549 ; (a & b) | ~(a | b) --> ~(a ^ b)
550 ; TODO: this increases instruction count if the pieces have additional users
551 define i32 @or_to_nxor_multiuse(i32 noundef %a, i32 noundef %b) {
552 ; CHECK-LABEL: @or_to_nxor_multiuse(
553 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
554 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A]], [[B]]
555 ; CHECK-NEXT:    [[NOTOR:%.*]] = xor i32 [[OR]], -1
556 ; CHECK-NEXT:    [[OR2:%.*]] = or disjoint i32 [[AND]], [[NOTOR]]
557 ; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[AND]], [[NOTOR]]
558 ; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], [[OR2]]
559 ; CHECK-NEXT:    ret i32 [[MUL2]]
561   %and = and i32 %a, %b
562   %or = or i32 %a, %b
563   %notor = xor i32 %or, -1
564   %or2 = or i32 %and, %notor
565   %mul1 = mul i32 %and, %notor ; here to increase the use count of the inputs to the or
566   %mul2 = mul i32 %mul1, %or2
567   ret i32 %mul2
570 ; (a | b) ^ (~a | ~b) --> ~(a ^ b)
571 define i32 @xor_to_xnor1(float %fa, float %fb) {
572 ; CHECK-LABEL: @xor_to_xnor1(
573 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
574 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
575 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
576 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
577 ; CHECK-NEXT:    ret i32 [[XOR]]
579   %a = fptosi float %fa to i32
580   %b = fptosi float %fb to i32
581   %nota = xor i32 %a, -1
582   %notb = xor i32 %b, -1
583   %or1 = or i32 %a, %b
584   %or2 = or i32 %nota, %notb
585   %xor = xor i32 %or1, %or2
586   ret i32 %xor
589 ; (a | b) ^ (~b | ~a) --> ~(a ^ b)
590 define i32 @xor_to_xnor2(float %fa, float %fb) {
591 ; CHECK-LABEL: @xor_to_xnor2(
592 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
593 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
594 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
595 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
596 ; CHECK-NEXT:    ret i32 [[XOR]]
598   %a = fptosi float %fa to i32
599   %b = fptosi float %fb to i32
600   %nota = xor i32 %a, -1
601   %notb = xor i32 %b, -1
602   %or1 = or i32 %a, %b
603   %or2 = or i32 %notb, %nota
604   %xor = xor i32 %or1, %or2
605   ret i32 %xor
608 ; (~a | ~b) ^ (a | b) --> ~(a ^ b)
609 define i32 @xor_to_xnor3(float %fa, float %fb) {
610 ; CHECK-LABEL: @xor_to_xnor3(
611 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
612 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
613 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
614 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
615 ; CHECK-NEXT:    ret i32 [[XOR]]
617   %a = fptosi float %fa to i32
618   %b = fptosi float %fb to i32
619   %nota = xor i32 %a, -1
620   %notb = xor i32 %b, -1
621   %or1 = or i32 %nota, %notb
622   %or2 = or i32 %a, %b
623   %xor = xor i32 %or1, %or2
624   ret i32 %xor
627 ; (~a | ~b) ^ (b | a) --> ~(a ^ b)
628 define i32 @xor_to_xnor4(float %fa, float %fb) {
629 ; CHECK-LABEL: @xor_to_xnor4(
630 ; CHECK-NEXT:    [[A:%.*]] = fptosi float [[FA:%.*]] to i32
631 ; CHECK-NEXT:    [[B:%.*]] = fptosi float [[FB:%.*]] to i32
632 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[A]]
633 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
634 ; CHECK-NEXT:    ret i32 [[XOR]]
636   %a = fptosi float %fa to i32
637   %b = fptosi float %fb to i32
638   %nota = xor i32 %a, -1
639   %notb = xor i32 %b, -1
640   %or1 = or i32 %nota, %notb
641   %or2 = or i32 %b, %a
642   %xor = xor i32 %or1, %or2
643   ret i32 %xor
646 define i4 @simplify_or_common_op_commute0(i4 %x, i4 %y, i4 %z)  {
647 ; CHECK-LABEL: @simplify_or_common_op_commute0(
648 ; CHECK-NEXT:    ret i4 -1
650   %xy = and i4 %x, %y
651   %xyz = and i4 %xy, %z
652   %not_xyz = xor i4 %xyz, -1
653   %r = or i4 %not_xyz, %x
654   ret i4 %r
657 define i4 @simplify_or_common_op_commute1(i4 %x, i4 %y, i4 %z)  {
658 ; CHECK-LABEL: @simplify_or_common_op_commute1(
659 ; CHECK-NEXT:    ret i4 -1
661   %xy = and i4 %y, %x
662   %xyz = and i4 %xy, %z
663   %not_xyz = xor i4 %xyz, -1
664   %r = or i4 %not_xyz, %x
665   ret i4 %r
668 ; The common operand may bubble through multiple instructions.
670 define i4 @simplify_or_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q)  {
671 ; CHECK-LABEL: @simplify_or_common_op_commute2(
672 ; CHECK-NEXT:    ret i4 -1
674   %z = mul i4 %p, %p ; thwart complexity-based canonicalization
675   %xy = and i4 %x, %y
676   %xyz = and i4 %z, %xy
677   %xyzq = and i4 %xyz, %q
678   %not_xyzq = xor i4 %xyzq, -1
679   %r = or i4 %not_xyzq, %x
680   ret i4 %r
683 define <2 x i4> @simplify_or_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p)  {
684 ; CHECK-LABEL: @simplify_or_common_op_commute3(
685 ; CHECK-NEXT:    ret <2 x i4> <i4 -1, i4 -1>
687   %z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization
688   %xy = and <2 x i4> %y, %x
689   %xyz = and <2 x i4> %z, %xy
690   %not_xyz = xor <2 x i4> %xyz, <i4 -1, i4 -1>
691   %r = or <2 x i4> %x, %not_xyz
692   ret <2 x i4> %r
695 define i4 @simplify_and_common_op_commute0(i4 %x, i4 %y, i4 %z)  {
696 ; CHECK-LABEL: @simplify_and_common_op_commute0(
697 ; CHECK-NEXT:    call void @use(i4 [[X:%.*]])
698 ; CHECK-NEXT:    ret i4 0
700   %xy = or i4 %x, %y
701   call void @use(i4 %x)
702   %xyz = or i4 %xy, %z
703   %not_xyz = xor i4 %xyz, -1
704   %r = and i4 %not_xyz, %x
705   ret i4 %r
708 define i4 @simplify_and_common_op_commute1(i4 %x, i4 %y, i4 %z)  {
709 ; CHECK-LABEL: @simplify_and_common_op_commute1(
710 ; CHECK-NEXT:    ret i4 0
712   %xy = or i4 %y, %x
713   %xyz = or i4 %xy, %z
714   %not_xyz = xor i4 %xyz, -1
715   %r = and i4 %not_xyz, %x
716   ret i4 %r
719 ; The common operand may bubble through multiple instructions.
721 define i4 @simplify_and_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q)  {
722 ; CHECK-LABEL: @simplify_and_common_op_commute2(
723 ; CHECK-NEXT:    ret i4 0
725   %z = mul i4 %p, %p ; thwart complexity-based canonicalization
726   %xy = or i4 %x, %y
727   %xyz = or i4 %z, %xy
728   %xyzq = or i4 %xyz, %q
729   %not_xyzq = xor i4 %xyzq, -1
730   %r = and i4 %not_xyzq, %x
731   ret i4 %r
734 define <2 x i4> @simplify_and_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p)  {
735 ; CHECK-LABEL: @simplify_and_common_op_commute3(
736 ; CHECK-NEXT:    ret <2 x i4> zeroinitializer
738   %z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization
739   %xy = or <2 x i4> %y, %x
740   %xyz = or <2 x i4> %z, %xy
741   %not_xyz = xor <2 x i4> %xyz, <i4 -1, i4 -1>
742   %r = and <2 x i4> %x, %not_xyz
743   ret <2 x i4> %r
746 define i4 @simplify_and_common_op_use1(i4 %x, i4 %y, i4 %z)  {
747 ; CHECK-LABEL: @simplify_and_common_op_use1(
748 ; CHECK-NEXT:    call void @use(i4 [[Y:%.*]])
749 ; CHECK-NEXT:    ret i4 0
751   %xy = or i4 %x, %y
752   call void @use(i4 %y)
753   %xyz = or i4 %xy, %z
754   %not_xyz = xor i4 %xyz, -1
755   %r = and i4 %not_xyz, %x
756   ret i4 %r
759 ; TODO: This should simplify.
761 define i4 @simplify_and_common_op_use2(i4 %x, i4 %y, i4 %z)  {
762 ; CHECK-LABEL: @simplify_and_common_op_use2(
763 ; CHECK-NEXT:    call void @use(i4 [[Y:%.*]])
764 ; CHECK-NEXT:    [[TMP1:%.*]] = or i4 [[X:%.*]], [[Z:%.*]]
765 ; CHECK-NEXT:    [[XYZ:%.*]] = or i4 [[TMP1]], [[Y]]
766 ; CHECK-NEXT:    [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
767 ; CHECK-NEXT:    [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
768 ; CHECK-NEXT:    ret i4 [[R]]
770   %xy = or i4 %y, %x
771   call void @use(i4 %y)
772   %xyz = or i4 %xy, %z
773   %not_xyz = xor i4 %xyz, -1
774   %r = and i4 %not_xyz, %x
775   ret i4 %r
778 ; TODO: This should simplify.
780 define i4 @simplify_and_common_op_use3(i4 %x, i4 %y, i4 %z)  {
781 ; CHECK-LABEL: @simplify_and_common_op_use3(
782 ; CHECK-NEXT:    [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
783 ; CHECK-NEXT:    [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
784 ; CHECK-NEXT:    call void @use(i4 [[Z]])
785 ; CHECK-NEXT:    [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
786 ; CHECK-NEXT:    [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
787 ; CHECK-NEXT:    ret i4 [[R]]
789   %xy = or i4 %x, %y
790   %xyz = or i4 %xy, %z
791   call void @use(i4 %z)
792   %not_xyz = xor i4 %xyz, -1
793   %r = and i4 %not_xyz, %x
794   ret i4 %r
797 define i4 @reduce_xor_common_op_commute0(i4 %x, i4 %y, i4 %z)  {
798 ; CHECK-LABEL: @reduce_xor_common_op_commute0(
799 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[Y:%.*]], [[Z:%.*]]
800 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[X:%.*]]
801 ; CHECK-NEXT:    ret i4 [[R]]
803   %xy = xor i4 %x, %y
804   %xyz = xor i4 %xy, %z
805   %r = or i4 %xyz, %x
806   ret i4 %r
809 define i4 @reduce_xor_common_op_commute1(i4 %x, i4 %y, i4 %z)  {
810 ; CHECK-LABEL: @reduce_xor_common_op_commute1(
811 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[Y:%.*]], [[Z:%.*]]
812 ; CHECK-NEXT:    [[R:%.*]] = or i4 [[TMP1]], [[X:%.*]]
813 ; CHECK-NEXT:    ret i4 [[R]]
815   %xy = xor i4 %y, %x
816   %xyz = xor i4 %xy, %z
817   %r = or i4 %xyz, %x
818   ret i4 %r
821 define i4 @annihilate_xor_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q)  {
822 ; CHECK-LABEL: @annihilate_xor_common_op_commute2(
823 ; CHECK-NEXT:    [[Z:%.*]] = mul i4 [[P:%.*]], [[P]]
824 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[Z]], [[Y:%.*]]
825 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i4 [[TMP1]], [[Q:%.*]]
826 ; CHECK-NEXT:    ret i4 [[TMP2]]
828   %z = mul i4 %p, %p ; thwart complexity-based canonicalization
829   %xy = xor i4 %x, %y
830   %xyz = xor i4 %z, %xy
831   %xyzq = xor i4 %xyz, %q
832   %r = xor i4 %xyzq, %x
833   ret i4 %r
836 define <2 x i4> @reduce_xor_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p)  {
837 ; CHECK-LABEL: @reduce_xor_common_op_commute3(
838 ; CHECK-NEXT:    [[Z:%.*]] = mul <2 x i4> [[P:%.*]], [[P]]
839 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[Z]], [[Y:%.*]]
840 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i4> [[TMP1]], [[X:%.*]]
841 ; CHECK-NEXT:    ret <2 x i4> [[R]]
843   %z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization
844   %xy = xor <2 x i4> %y, %x
845   %xyz = xor <2 x i4> %z, %xy
846   %r = or <2 x i4> %x, %xyz
847   ret <2 x i4> %r