xref: /llvm-project/llvm/test/Transforms/InstCombine/xor2.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; PR1253
5define i1 @test0(i32 %A) {
6; CHECK-LABEL: @test0(
7; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 0
8; CHECK-NEXT:    ret i1 [[C]]
9;
10  %B = xor i32 %A, -2147483648
11  %C = icmp sgt i32 %B, -1
12  ret i1 %C
13}
14
15define <2 x i1> @test0vec(<2 x i32> %A) {
16; CHECK-LABEL: @test0vec(
17; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer
18; CHECK-NEXT:    ret <2 x i1> [[C]]
19;
20  %B = xor <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
21  %C = icmp sgt <2 x i32> %B, <i32 -1, i32 -1>
22  ret <2 x i1> %C
23}
24
25define i1 @test1(i32 %A) {
26; CHECK-LABEL: @test1(
27; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 [[A:%.*]], 0
28; CHECK-NEXT:    ret i1 [[C]]
29;
30  %B = xor i32 %A, 12345
31  %C = icmp slt i32 %B, 0
32  ret i1 %C
33}
34
35; PR1014
36define i32 @test2(i32 %t1) {
37; CHECK-LABEL: @test2(
38; CHECK-NEXT:    [[OVM:%.*]] = and i32 [[T1:%.*]], 32
39; CHECK-NEXT:    [[OV110:%.*]] = or disjoint i32 [[OVM]], 8
40; CHECK-NEXT:    ret i32 [[OV110]]
41;
42  %ovm = and i32 %t1, 32
43  %ov3 = add i32 %ovm, 145
44  %ov110 = xor i32 %ov3, 153
45  ret i32 %ov110
46}
47
48define i32 @test3(i32 %t1) {
49; CHECK-LABEL: @test3(
50; CHECK-NEXT:    [[OVM:%.*]] = and i32 [[T1:%.*]], 32
51; CHECK-NEXT:    [[OV110:%.*]] = or disjoint i32 [[OVM]], 8
52; CHECK-NEXT:    ret i32 [[OV110]]
53;
54  %ovm = or i32 %t1, 145
55  %ov31 = and i32 %ovm, 177
56  %ov110 = xor i32 %ov31, 153
57  ret i32 %ov110
58}
59
60; defect-2 in rdar://12329730
61; (X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
62;   where the "X" has more than one use
63define i32 @test5(i32 %val1) {
64; CHECK-LABEL: @test5(
65; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[VAL1:%.*]], 1234
66; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[VAL1]], 8
67; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[SHR]], 5
68; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[XOR1]], [[XOR]]
69; CHECK-NEXT:    ret i32 [[ADD]]
70;
71  %xor = xor i32 %val1, 1234
72  %shr = lshr i32 %xor, 8
73  %xor1 = xor i32 %shr, 1
74  %add = add i32 %xor1, %xor
75  ret i32 %add
76}
77
78; defect-1 in rdar://12329730
79; Simplify (X^Y) -> X or Y in the user's context if we know that
80; only bits from X or Y are demanded.
81; e.g. the "x ^ 1234" can be optimized into x in the context of "t >> 16".
82;  Put in other word, t >> 16 -> x >> 16.
83; unsigned foo(unsigned x) { unsigned t = x ^ 1234; ;  return (t >> 16) + t;}
84define i32 @test6(i32 %x) {
85; CHECK-LABEL: @test6(
86; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], 1234
87; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[X]], 16
88; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[SHR]], [[XOR]]
89; CHECK-NEXT:    ret i32 [[ADD]]
90;
91  %xor = xor i32 %x, 1234
92  %shr = lshr i32 %xor, 16
93  %add = add i32 %shr, %xor
94  ret i32 %add
95}
96
97
98; (A | B) ^ (~A) -> (A | ~B)
99define i32 @test7(i32 %a, i32 %b) {
100; CHECK-LABEL: @test7(
101; CHECK-NEXT:    [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1
102; CHECK-NEXT:    [[XOR:%.*]] = or i32 [[A:%.*]], [[B_NOT]]
103; CHECK-NEXT:    ret i32 [[XOR]]
104;
105  %or = or i32 %a, %b
106  %neg = xor i32 %a, -1
107  %xor = xor i32 %or, %neg
108  ret i32 %xor
109}
110
111; (~A) ^ (A | B) -> (A | ~B)
112define i32 @test8(i32 %a, i32 %b) {
113; CHECK-LABEL: @test8(
114; CHECK-NEXT:    [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1
115; CHECK-NEXT:    [[XOR:%.*]] = or i32 [[A:%.*]], [[B_NOT]]
116; CHECK-NEXT:    ret i32 [[XOR]]
117;
118  %neg = xor i32 %a, -1
119  %or = or i32 %a, %b
120  %xor = xor i32 %neg, %or
121  ret i32 %xor
122}
123
124; (A & B) ^ (A ^ B) -> (A | B)
125define i32 @test9(i32 %b, i32 %c) {
126; CHECK-LABEL: @test9(
127; CHECK-NEXT:    [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
128; CHECK-NEXT:    ret i32 [[XOR2]]
129;
130  %and = and i32 %b, %c
131  %xor = xor i32 %b, %c
132  %xor2 = xor i32 %and, %xor
133  ret i32 %xor2
134}
135
136; (A & B) ^ (B ^ A) -> (A | B)
137define i32 @test9b(i32 %b, i32 %c) {
138; CHECK-LABEL: @test9b(
139; CHECK-NEXT:    [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
140; CHECK-NEXT:    ret i32 [[XOR2]]
141;
142  %and = and i32 %b, %c
143  %xor = xor i32 %c, %b
144  %xor2 = xor i32 %and, %xor
145  ret i32 %xor2
146}
147
148; (A ^ B) ^ (A & B) -> (A | B)
149define i32 @test10(i32 %b, i32 %c) {
150; CHECK-LABEL: @test10(
151; CHECK-NEXT:    [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
152; CHECK-NEXT:    ret i32 [[XOR2]]
153;
154  %xor = xor i32 %b, %c
155  %and = and i32 %b, %c
156  %xor2 = xor i32 %xor, %and
157  ret i32 %xor2
158}
159
160; (A ^ B) ^ (A & B) -> (A | B)
161define i32 @test10b(i32 %b, i32 %c) {
162; CHECK-LABEL: @test10b(
163; CHECK-NEXT:    [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
164; CHECK-NEXT:    ret i32 [[XOR2]]
165;
166  %xor = xor i32 %b, %c
167  %and = and i32 %c, %b
168  %xor2 = xor i32 %xor, %and
169  ret i32 %xor2
170}
171
172define i32 @test11(i32 %A, i32 %B) {
173; CHECK-LABEL: @test11(
174; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
175; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
176; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
177; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
178; CHECK-NEXT:    ret i32 [[AND]]
179;
180  %xor1 = xor i32 %B, %A
181  %not = xor i32 %A, -1
182  %xor2 = xor i32 %not, %B
183  %and = and i32 %xor1, %xor2
184  ret i32 %and
185}
186
187define i32 @test11b(i32 %A, i32 %B) {
188; CHECK-LABEL: @test11b(
189; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
190; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
191; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
192; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
193; CHECK-NEXT:    ret i32 [[AND]]
194;
195  %xor1 = xor i32 %B, %A
196  %not = xor i32 %A, -1
197  %xor2 = xor i32 %not, %B
198  %and = and i32 %xor2, %xor1
199  ret i32 %and
200}
201
202define i32 @test11c(i32 %A, i32 %B) {
203; CHECK-LABEL: @test11c(
204; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
205; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
206; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
207; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
208; CHECK-NEXT:    ret i32 [[AND]]
209;
210  %xor1 = xor i32 %A, %B
211  %not = xor i32 %A, -1
212  %xor2 = xor i32 %not, %B
213  %and = and i32 %xor1, %xor2
214  ret i32 %and
215}
216
217define i32 @test11d(i32 %A, i32 %B) {
218; CHECK-LABEL: @test11d(
219; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
220; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
221; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
222; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
223; CHECK-NEXT:    ret i32 [[AND]]
224;
225  %xor1 = xor i32 %A, %B
226  %not = xor i32 %A, -1
227  %xor2 = xor i32 %not, %B
228  %and = and i32 %xor2, %xor1
229  ret i32 %and
230}
231
232define i32 @test11e(i32 %A, i32 %B, i32 %C) {
233; CHECK-LABEL: @test11e(
234; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]]
235; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]]
236; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[FORCE]]
237; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
238; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
239; CHECK-NEXT:    ret i32 [[AND]]
240;
241  %force = mul i32 %B, %C
242  %xor1 = xor i32 %force, %A
243  %not = xor i32 %A, -1
244  %xor2 = xor i32 %force, %not
245  %and = and i32 %xor1, %xor2
246  ret i32 %and
247}
248
249define i32 @test11f(i32 %A, i32 %B, i32 %C) {
250; CHECK-LABEL: @test11f(
251; CHECK-NEXT:    [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]]
252; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]]
253; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[FORCE]]
254; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
255; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]
256; CHECK-NEXT:    ret i32 [[AND]]
257;
258  %force = mul i32 %B, %C
259  %xor1 = xor i32 %force, %A
260  %not = xor i32 %A, -1
261  %xor2 = xor i32 %force, %not
262  %and = and i32 %xor2, %xor1
263  ret i32 %and
264}
265
266define i32 @test12(i32 %a, i32 %b) {
267; CHECK-LABEL: @test12(
268; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
269; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
270; CHECK-NEXT:    ret i32 [[XOR]]
271;
272  %negb = xor i32 %b, -1
273  %and = and i32 %a, %negb
274  %nega = xor i32 %a, -1
275  %xor = xor i32 %and, %nega
276  ret i32 %xor
277}
278
279define i32 @test12commuted(i32 %a, i32 %b) {
280; CHECK-LABEL: @test12commuted(
281; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
282; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
283; CHECK-NEXT:    ret i32 [[XOR]]
284;
285  %negb = xor i32 %b, -1
286  %and = and i32 %negb, %a
287  %nega = xor i32 %a, -1
288  %xor = xor i32 %and, %nega
289  ret i32 %xor
290}
291
292; This is a test of canonicalization via operand complexity.
293; The final xor has a binary operator and a (fake) unary operator,
294; so binary (more complex) should come first.
295
296define i32 @test13(i32 %a, i32 %b) {
297; CHECK-LABEL: @test13(
298; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
299; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
300; CHECK-NEXT:    ret i32 [[XOR]]
301;
302  %nega = xor i32 %a, -1
303  %negb = xor i32 %b, -1
304  %and = and i32 %a, %negb
305  %xor = xor i32 %nega, %and
306  ret i32 %xor
307}
308
309define i32 @test13commuted(i32 %a, i32 %b) {
310; CHECK-LABEL: @test13commuted(
311; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
312; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
313; CHECK-NEXT:    ret i32 [[XOR]]
314;
315  %nega = xor i32 %a, -1
316  %negb = xor i32 %b, -1
317  %and = and i32 %negb, %a
318  %xor = xor i32 %nega, %and
319  ret i32 %xor
320}
321
322; (A ^ C) ^ (A | B) -> ((~A) & B) ^ C
323
324define i32 @xor_or_xor_common_op_commute1(i32 %a, i32 %b, i32 %c) {
325; CHECK-LABEL: @xor_or_xor_common_op_commute1(
326; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
327; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
328; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
329; CHECK-NEXT:    ret i32 [[R]]
330;
331  %ac = xor i32 %a, %c
332  %ab = or i32 %a, %b
333  %r = xor i32 %ac, %ab
334  ret i32 %r
335}
336
337; (C ^ A) ^ (A | B) -> ((~A) & B) ^ C
338
339define i32 @xor_or_xor_common_op_commute2(i32 %a, i32 %b, i32 %c) {
340; CHECK-LABEL: @xor_or_xor_common_op_commute2(
341; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
342; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
343; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
344; CHECK-NEXT:    ret i32 [[R]]
345;
346  %ac = xor i32 %c, %a
347  %ab = or i32 %a, %b
348  %r = xor i32 %ac, %ab
349  ret i32 %r
350}
351
352; (A ^ C) ^ (B | A) -> ((~A) & B) ^ C
353
354define i32 @xor_or_xor_common_op_commute3(i32 %a, i32 %b, i32 %c) {
355; CHECK-LABEL: @xor_or_xor_common_op_commute3(
356; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
357; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
358; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
359; CHECK-NEXT:    ret i32 [[R]]
360;
361  %ac = xor i32 %a, %c
362  %ab = or i32 %b, %a
363  %r = xor i32 %ac, %ab
364  ret i32 %r
365}
366
367; (C ^ A) ^ (B | A) -> ((~A) & B) ^ C
368
369define i32 @xor_or_xor_common_op_commute4(i32 %a, i32 %b, i32 %c) {
370; CHECK-LABEL: @xor_or_xor_common_op_commute4(
371; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
372; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
373; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
374; CHECK-NEXT:    ret i32 [[R]]
375;
376  %ac = xor i32 %c, %a
377  %ab = or i32 %b, %a
378  %r = xor i32 %ac, %ab
379  ret i32 %r
380}
381
382; (A | B) ^ (A ^ C) -> ((~A) & B) ^ C
383
384define i32 @xor_or_xor_common_op_commute5(i32 %a, i32 %b, i32 %c) {
385; CHECK-LABEL: @xor_or_xor_common_op_commute5(
386; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
387; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
388; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
389; CHECK-NEXT:    ret i32 [[R]]
390;
391  %ac = xor i32 %a, %c
392  %ab = or i32 %a, %b
393  %r = xor i32 %ab, %ac
394  ret i32 %r
395}
396
397; (A | B) ^ (C ^ A) -> ((~A) & B) ^ C
398
399define i32 @xor_or_xor_common_op_commute6(i32 %a, i32 %b, i32 %c) {
400; CHECK-LABEL: @xor_or_xor_common_op_commute6(
401; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
402; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
403; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
404; CHECK-NEXT:    ret i32 [[R]]
405;
406  %ac = xor i32 %c, %a
407  %ab = or i32 %a, %b
408  %r = xor i32 %ab, %ac
409  ret i32 %r
410}
411
412; (B | A) ^ (A ^ C) -> ((~A) & B) ^ C
413
414define i32 @xor_or_xor_common_op_commute7(i32 %a, i32 %b, i32 %c) {
415; CHECK-LABEL: @xor_or_xor_common_op_commute7(
416; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
417; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
418; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
419; CHECK-NEXT:    ret i32 [[R]]
420;
421  %ac = xor i32 %a, %c
422  %ab = or i32 %b, %a
423  %r = xor i32 %ab, %ac
424  ret i32 %r
425}
426
427; (B | A) ^ (C ^ A) -> ((~A) & B) ^ C
428
429define i32 @xor_or_xor_common_op_commute8(i32 %a, i32 %b, i32 %c) {
430; CHECK-LABEL: @xor_or_xor_common_op_commute8(
431; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
432; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]
433; CHECK-NEXT:    [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]
434; CHECK-NEXT:    ret i32 [[R]]
435;
436  %ac = xor i32 %c, %a
437  %ab = or i32 %b, %a
438  %r = xor i32 %ab, %ac
439  ret i32 %r
440}
441
442define i32 @xor_or_xor_common_op_extra_use1(i32 %a, i32 %b, i32 %c, ptr %p) {
443; CHECK-LABEL: @xor_or_xor_common_op_extra_use1(
444; CHECK-NEXT:    [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]
445; CHECK-NEXT:    store i32 [[AC]], ptr [[P:%.*]], align 4
446; CHECK-NEXT:    [[AB:%.*]] = or i32 [[A]], [[B:%.*]]
447; CHECK-NEXT:    [[R:%.*]] = xor i32 [[AC]], [[AB]]
448; CHECK-NEXT:    ret i32 [[R]]
449;
450  %ac = xor i32 %a, %c
451  store i32 %ac, ptr %p
452  %ab = or i32 %a, %b
453  %r = xor i32 %ac, %ab
454  ret i32 %r
455}
456
457define i32 @xor_or_xor_common_op_extra_use2(i32 %a, i32 %b, i32 %c, ptr %p) {
458; CHECK-LABEL: @xor_or_xor_common_op_extra_use2(
459; CHECK-NEXT:    [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]
460; CHECK-NEXT:    [[AB:%.*]] = or i32 [[A]], [[B:%.*]]
461; CHECK-NEXT:    store i32 [[AB]], ptr [[P:%.*]], align 4
462; CHECK-NEXT:    [[R:%.*]] = xor i32 [[AC]], [[AB]]
463; CHECK-NEXT:    ret i32 [[R]]
464;
465  %ac = xor i32 %a, %c
466  %ab = or i32 %a, %b
467  store i32 %ab, ptr %p
468  %r = xor i32 %ac, %ab
469  ret i32 %r
470}
471
472define i32 @xor_or_xor_common_op_extra_use3(i32 %a, i32 %b, i32 %c, ptr %p1, ptr %p2) {
473; CHECK-LABEL: @xor_or_xor_common_op_extra_use3(
474; CHECK-NEXT:    [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]
475; CHECK-NEXT:    store i32 [[AC]], ptr [[P1:%.*]], align 4
476; CHECK-NEXT:    [[AB:%.*]] = or i32 [[A]], [[B:%.*]]
477; CHECK-NEXT:    store i32 [[AB]], ptr [[P2:%.*]], align 4
478; CHECK-NEXT:    [[R:%.*]] = xor i32 [[AC]], [[AB]]
479; CHECK-NEXT:    ret i32 [[R]]
480;
481  %ac = xor i32 %a, %c
482  store i32 %ac, ptr %p1
483  %ab = or i32 %a, %b
484  store i32 %ab, ptr %p2
485  %r = xor i32 %ac, %ab
486  ret i32 %r
487}
488
489define i8 @test15(i8 %A, i8 %B) {
490; CHECK-LABEL: @test15(
491; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
492; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[A]], [[B]]
493; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 33
494; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XOR1]], [[XOR2]]
495; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[AND]], [[XOR2]]
496; CHECK-NEXT:    ret i8 [[RES]]
497;
498  %xor1 = xor i8 %B, %A
499  %not = xor i8 %A, 33
500  %xor2 = xor i8 %not, %B
501  %and = and i8 %xor1, %xor2
502  %res = mul i8 %and, %xor2 ; to increase the use count for the xor
503  ret i8 %res
504}
505
506define i8 @test16(i8 %A, i8 %B) {
507; CHECK-LABEL: @test16(
508; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
509; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[A]], [[B]]
510; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 33
511; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XOR2]], [[XOR1]]
512; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[AND]], [[XOR2]]
513; CHECK-NEXT:    ret i8 [[RES]]
514;
515  %xor1 = xor i8 %B, %A
516  %not = xor i8 %A, 33
517  %xor2 = xor i8 %not, %B
518  %and = and i8 %xor2, %xor1
519  %res = mul i8 %and, %xor2 ; to increase the use count for the xor
520  ret i8 %res
521}
522
523; Canonicalize ~((A & B) ^ (A | ?)) -> (A & B) | ~(A | ?)
524
525define i3 @not_xor_to_or_not1(i3 %a, i3 %b, i3 %c) {
526; CHECK-LABEL: @not_xor_to_or_not1(
527; CHECK-NEXT:    [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]
528; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[C]]
529; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
530; CHECK-NEXT:    [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]
531; CHECK-NEXT:    ret i3 [[NOT]]
532;
533  %or = or i3 %b, %c
534  %and = and i3 %a, %c
535  %xor = xor i3 %and, %or
536  %not = xor i3 %xor, -1
537  ret i3 %not
538}
539
540define i3 @not_xor_to_or_not2(i3 %a, i3 %b, i3 %c) {
541; CHECK-LABEL: @not_xor_to_or_not2(
542; CHECK-NEXT:    [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]
543; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[C]]
544; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
545; CHECK-NEXT:    [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]
546; CHECK-NEXT:    ret i3 [[NOT]]
547;
548  %or = or i3 %c, %b
549  %and = and i3 %a, %c
550  %xor = xor i3 %and, %or
551  %not = xor i3 %xor, -1
552  ret i3 %not
553}
554
555define i3 @not_xor_to_or_not3(i3 %a, i3 %b, i3 %c) {
556; CHECK-LABEL: @not_xor_to_or_not3(
557; CHECK-NEXT:    [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]
558; CHECK-NEXT:    [[AND:%.*]] = and i3 [[C]], [[A:%.*]]
559; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
560; CHECK-NEXT:    [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]
561; CHECK-NEXT:    ret i3 [[NOT]]
562;
563  %or = or i3 %c, %b
564  %and = and i3 %c, %a
565  %xor = xor i3 %and, %or
566  %not = xor i3 %xor, -1
567  ret i3 %not
568}
569
570define i3 @not_xor_to_or_not4(i3 %a, i3 %b, i3 %c) {
571; CHECK-LABEL: @not_xor_to_or_not4(
572; CHECK-NEXT:    [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]
573; CHECK-NEXT:    [[AND:%.*]] = and i3 [[C]], [[A:%.*]]
574; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
575; CHECK-NEXT:    [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]
576; CHECK-NEXT:    ret i3 [[NOT]]
577;
578  %or = or i3 %b, %c
579  %and = and i3 %c, %a
580  %xor = xor i3 %and, %or
581  %not = xor i3 %xor, -1
582  ret i3 %not
583}
584
585define <3 x i5> @not_xor_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {
586; CHECK-LABEL: @not_xor_to_or_not_vector(
587; CHECK-NEXT:    [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]
588; CHECK-NEXT:    [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]
589; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)
590; CHECK-NEXT:    [[NOT:%.*]] = or <3 x i5> [[AND]], [[TMP1]]
591; CHECK-NEXT:    ret <3 x i5> [[NOT]]
592;
593  %or = or <3 x i5> %b, %c
594  %and = and <3 x i5> %a, %c
595  %xor = xor <3 x i5> %or, %and
596  %not = xor <3 x i5> %xor, <i5 -1, i5 -1, i5 -1>
597  ret <3 x i5> %not
598}
599
600define <3 x i5> @not_xor_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {
601; CHECK-LABEL: @not_xor_to_or_not_vector_poison(
602; CHECK-NEXT:    [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]
603; CHECK-NEXT:    [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]
604; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)
605; CHECK-NEXT:    [[NOT:%.*]] = or <3 x i5> [[AND]], [[TMP1]]
606; CHECK-NEXT:    ret <3 x i5> [[NOT]]
607;
608  %or = or <3 x i5> %b, %c
609  %and = and <3 x i5> %a, %c
610  %xor = xor <3 x i5> %or, %and
611  %not = xor <3 x i5> %xor, <i5 poison, i5 -1, i5 -1>
612  ret <3 x i5> %not
613}
614
615; negative test : not one use
616
617define i3 @not_xor_to_or_not_2use(i3 %a, i3 %b, i3 %c) {
618; CHECK-LABEL: @not_xor_to_or_not_2use(
619; CHECK-NEXT:    [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]
620; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[C]]
621; CHECK-NEXT:    [[XOR:%.*]] = xor i3 [[AND]], [[OR]]
622; CHECK-NEXT:    [[NOT:%.*]] = xor i3 [[XOR]], -1
623; CHECK-NEXT:    call void @use3(i3 [[XOR]])
624; CHECK-NEXT:    ret i3 [[NOT]]
625;
626  %or = or i3 %b, %c
627  %and = and i3 %a, %c
628  %xor = xor i3 %and, %or
629  %not = xor i3 %xor, -1
630  call void @use3(i3 %xor)
631  ret i3 %not
632}
633
634; Canonicalize ~(A & B) ^ (A | ?) -> (A & B) | ~(A | ?)
635
636define i3 @xor_notand_to_or_not1(i3 %a, i3 %b, i3 %c) {
637; CHECK-LABEL: @xor_notand_to_or_not1(
638; CHECK-NEXT:    [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]
639; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[C]]
640; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
641; CHECK-NEXT:    [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]
642; CHECK-NEXT:    ret i3 [[XOR]]
643;
644  %or = or i3 %b, %c
645  %and = and i3 %a, %c
646  %not = xor i3 %and, -1
647  %xor = xor i3 %not, %or
648  ret i3 %xor
649}
650
651define i3 @xor_notand_to_or_not2(i3 %a, i3 %b, i3 %c) {
652; CHECK-LABEL: @xor_notand_to_or_not2(
653; CHECK-NEXT:    [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]
654; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[C]]
655; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
656; CHECK-NEXT:    [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]
657; CHECK-NEXT:    ret i3 [[XOR]]
658;
659  %or = or i3 %c, %b
660  %and = and i3 %a, %c
661  %not = xor i3 %and, -1
662  %xor = xor i3 %not, %or
663  ret i3 %xor
664}
665
666define i3 @xor_notand_to_or_not3(i3 %a, i3 %b, i3 %c) {
667; CHECK-LABEL: @xor_notand_to_or_not3(
668; CHECK-NEXT:    [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]
669; CHECK-NEXT:    [[AND:%.*]] = and i3 [[C]], [[A:%.*]]
670; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
671; CHECK-NEXT:    [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]
672; CHECK-NEXT:    ret i3 [[XOR]]
673;
674  %or = or i3 %c, %b
675  %and = and i3 %c, %a
676  %not = xor i3 %and, -1
677  %xor = xor i3 %not, %or
678  ret i3 %xor
679}
680
681define i3 @xor_notand_to_or_not4(i3 %a, i3 %b, i3 %c) {
682; CHECK-LABEL: @xor_notand_to_or_not4(
683; CHECK-NEXT:    [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]
684; CHECK-NEXT:    [[AND:%.*]] = and i3 [[C]], [[A:%.*]]
685; CHECK-NEXT:    [[TMP1:%.*]] = xor i3 [[OR]], -1
686; CHECK-NEXT:    [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]
687; CHECK-NEXT:    ret i3 [[XOR]]
688;
689  %or = or i3 %b, %c
690  %and = and i3 %c, %a
691  %not = xor i3 %and, -1
692  %xor = xor i3 %not, %or
693  ret i3 %xor
694}
695
696define <3 x i5> @xor_notand_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {
697; CHECK-LABEL: @xor_notand_to_or_not_vector(
698; CHECK-NEXT:    [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]
699; CHECK-NEXT:    [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]
700; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)
701; CHECK-NEXT:    [[XOR:%.*]] = or <3 x i5> [[AND]], [[TMP1]]
702; CHECK-NEXT:    ret <3 x i5> [[XOR]]
703;
704  %or = or <3 x i5> %b, %c
705  %and = and <3 x i5> %a, %c
706  %not = xor <3 x i5> %and, <i5 -1, i5 -1, i5 -1>
707  %xor = xor <3 x i5> %not, %or
708  ret <3 x i5> %xor
709}
710
711define <3 x i5> @xor_notand_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {
712; CHECK-LABEL: @xor_notand_to_or_not_vector_poison(
713; CHECK-NEXT:    [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]
714; CHECK-NEXT:    [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]
715; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)
716; CHECK-NEXT:    [[XOR:%.*]] = or <3 x i5> [[AND]], [[TMP1]]
717; CHECK-NEXT:    ret <3 x i5> [[XOR]]
718;
719  %or = or <3 x i5> %b, %c
720  %and = and <3 x i5> %a, %c
721  %not = xor <3 x i5> %and, <i5 -1, i5 poison, i5 -1>
722  %xor = xor <3 x i5> %not, %or
723  ret <3 x i5> %xor
724}
725
726; negative test : not one use
727
728define i3 @xor_notand_to_or_not_2use(i3 %a, i3 %b, i3 %c) {
729; CHECK-LABEL: @xor_notand_to_or_not_2use(
730; CHECK-NEXT:    [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]
731; CHECK-NEXT:    [[AND:%.*]] = and i3 [[A:%.*]], [[C]]
732; CHECK-NEXT:    [[NOT:%.*]] = xor i3 [[AND]], -1
733; CHECK-NEXT:    [[XOR:%.*]] = xor i3 [[OR]], [[NOT]]
734; CHECK-NEXT:    call void @use3(i3 [[NOT]])
735; CHECK-NEXT:    ret i3 [[XOR]]
736;
737  %or = or i3 %b, %c
738  %and = and i3 %a, %c
739  %not = xor i3 %and, -1
740  %xor = xor i3 %not, %or
741  call void @use3(i3 %not)
742  ret i3 %xor
743}
744
745declare void @use3(i3)
746