xref: /llvm-project/llvm/test/Transforms/InstCombine/or-xor.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
4declare void @use(i8)
5
6; X | ~(X | Y) --> X | ~Y
7
8define i32 @test1(i32 %x, i32 %y) {
9; CHECK-LABEL: @test1(
10; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
11; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]]
12; CHECK-NEXT:    ret i32 [[Z]]
13;
14  %or = or i32 %x, %y
15  %not = xor i32 %or, -1
16  %z = or i32 %x, %not
17  ret i32 %z
18}
19
20; Commute (rename) the inner 'or' operands:
21; Y | ~(X | Y) --> ~X | Y
22
23define i32 @test2(i32 %x, i32 %y) {
24; CHECK-LABEL: @test2(
25; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
26; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]]
27; CHECK-NEXT:    ret i32 [[Z]]
28;
29  %or = or i32 %x, %y
30  %not = xor i32 %or, -1
31  %z = or i32 %y, %not
32  ret i32 %z
33}
34
35; X | ~(X ^ Y) --> X | ~Y
36
37define i32 @test3(i32 %x, i32 %y) {
38; CHECK-LABEL: @test3(
39; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
40; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]]
41; CHECK-NEXT:    ret i32 [[Z]]
42;
43  %xor = xor i32 %x, %y
44  %not = xor i32 %xor, -1
45  %z = or i32 %x, %not
46  ret i32 %z
47}
48
49; Commute (rename) the 'xor' operands:
50; Y | ~(X ^ Y) --> ~X | Y
51
52define i32 @test4(i32 %x, i32 %y) {
53; CHECK-LABEL: @test4(
54; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
55; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]]
56; CHECK-NEXT:    ret i32 [[Z]]
57;
58  %xor = xor i32 %x, %y
59  %not = xor i32 %xor, -1
60  %z = or i32 %y, %not
61  ret i32 %z
62}
63
64; (X ^ Y) | ~X  --> ~(X & Y)
65
66define i32 @test5(i32 %x, i32 %y) {
67; CHECK-LABEL: @test5(
68; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
69; CHECK-NEXT:    [[Z:%.*]] = xor i32 [[TMP1]], -1
70; CHECK-NEXT:    ret i32 [[Z]]
71;
72  %xor = xor i32 %x, %y
73  %notx = xor i32 %x, -1
74  %z = or i32 %xor, %notx
75  ret i32 %z
76}
77
78; Commute the 'or' operands
79; ~X | (X ^ Y) --> ~(X & Y)
80
81define <2 x i4> @test5_commuted(<2 x i4> %x, <2 x i4> %y) {
82; CHECK-LABEL: @test5_commuted(
83; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[X:%.*]], [[Y:%.*]]
84; CHECK-NEXT:    [[Z:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 -1)
85; CHECK-NEXT:    ret <2 x i4> [[Z]]
86;
87  %xor = xor <2 x i4> %x, %y
88  %notx = xor <2 x i4> %x, <i4 -1, i4 -1>
89  %z = or <2 x i4> %notx, %xor
90  ret <2 x i4> %z
91}
92
93; Commute the inner 'xor' operands
94; (Y ^ X) | ~X  --> ~(Y & X)
95
96define i64 @test5_commuted_x_y(i64 %x, i64 %y) {
97; CHECK-LABEL: @test5_commuted_x_y(
98; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[Y:%.*]], [[X:%.*]]
99; CHECK-NEXT:    [[Z:%.*]] = xor i64 [[TMP1]], -1
100; CHECK-NEXT:    ret i64 [[Z]]
101;
102  %xor = xor i64 %y, %x
103  %notx = xor i64 %x, -1
104  %z = or i64  %xor, %notx
105  ret i64 %z
106}
107
108
109define i8 @test5_extra_use_not(i8 %x, i8 %y, ptr %dst) {
110; CHECK-LABEL: @test5_extra_use_not(
111; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
112; CHECK-NEXT:    store i8 [[NOTX]], ptr [[DST:%.*]], align 1
113; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], [[Y:%.*]]
114; CHECK-NEXT:    [[Z:%.*]] = xor i8 [[TMP1]], -1
115; CHECK-NEXT:    ret i8 [[Z]]
116;
117  %xor = xor i8 %x, %y
118  %notx = xor i8 %x, -1
119  store i8 %notx, ptr %dst
120  %z = or i8 %notx, %xor
121  ret i8 %z
122}
123
124
125define i65 @test5_extra_use_xor(i65 %x, i65 %y, ptr %dst) {
126; CHECK-LABEL: @test5_extra_use_xor(
127; CHECK-NEXT:    [[XOR:%.*]] = xor i65 [[X:%.*]], [[Y:%.*]]
128; CHECK-NEXT:    store i65 [[XOR]], ptr [[DST:%.*]], align 4
129; CHECK-NEXT:    [[TMP1:%.*]] = and i65 [[X]], [[Y]]
130; CHECK-NEXT:    [[Z:%.*]] = xor i65 [[TMP1]], -1
131; CHECK-NEXT:    ret i65 [[Z]]
132;
133  %xor = xor i65 %x, %y
134  store i65 %xor, ptr %dst
135  %notx = xor i65 %x, -1
136  %z = or i65 %notx, %xor
137  ret i65 %z
138}
139
140define i16 @test5_extra_use_not_xor(i16 %x, i16 %y, ptr %dst_not, ptr %dst_xor) {
141; CHECK-LABEL: @test5_extra_use_not_xor(
142; CHECK-NEXT:    [[XOR:%.*]] = xor i16 [[X:%.*]], [[Y:%.*]]
143; CHECK-NEXT:    store i16 [[XOR]], ptr [[DST_XOR:%.*]], align 2
144; CHECK-NEXT:    [[NOTX:%.*]] = xor i16 [[X]], -1
145; CHECK-NEXT:    store i16 [[NOTX]], ptr [[DST_NOT:%.*]], align 2
146; CHECK-NEXT:    [[Z:%.*]] = or i16 [[XOR]], [[NOTX]]
147; CHECK-NEXT:    ret i16 [[Z]]
148;
149  %xor = xor i16 %x, %y
150  store i16 %xor, ptr %dst_xor
151  %notx = xor i16 %x, -1
152  store i16 %notx, ptr %dst_not
153  %z = or i16 %notx, %xor
154  ret i16 %z
155}
156
157define i8 @xor_common_op_commute0(i8 %x, i8 %y) {
158; CHECK-LABEL: @xor_common_op_commute0(
159; CHECK-NEXT:    [[Z:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
160; CHECK-NEXT:    ret i8 [[Z]]
161;
162  %xor = xor i8 %x, %y
163  %z = or i8 %xor, %x
164  ret i8 %z
165}
166
167define i8 @xor_common_op_commute1(i8 %x, i8 %y) {
168; CHECK-LABEL: @xor_common_op_commute1(
169; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X:%.*]]
170; CHECK-NEXT:    call void @use(i8 [[XOR]])
171; CHECK-NEXT:    [[Z:%.*]] = or i8 [[Y]], [[X]]
172; CHECK-NEXT:    ret i8 [[Z]]
173;
174  %xor = xor i8 %y, %x
175  call void @use(i8 %xor)
176  %z = or i8 %xor, %x
177  ret i8 %z
178}
179
180define i8 @xor_common_op_commute2(i8 %p, i8 %y) {
181; CHECK-LABEL: @xor_common_op_commute2(
182; CHECK-NEXT:    [[X:%.*]] = xor i8 [[P:%.*]], 5
183; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[Y:%.*]]
184; CHECK-NEXT:    ret i8 [[Z]]
185;
186  %x = xor i8 %p, 5 ; thwart complexity-based canonicalization
187  %xor = xor i8 %x, %y
188  %z = or i8 %x, %xor
189  ret i8 %z
190}
191
192define i8 @xor_common_op_commute3(i8 %p, i8 %q) {
193; CHECK-LABEL: @xor_common_op_commute3(
194; CHECK-NEXT:    [[X:%.*]] = xor i8 [[P:%.*]], 5
195; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]]
196; CHECK-NEXT:    [[Z:%.*]] = or i8 [[X]], [[Y]]
197; CHECK-NEXT:    ret i8 [[Z]]
198;
199  %x = xor i8 %p, 5  ; thwart complexity-based canonicalization
200  %y = mul i8 %q, %q ; thwart complexity-based canonicalization
201  %xor = xor i8 %y, %x
202  %z = or i8 %x, %xor
203  ret i8 %z
204}
205
206define i32 @test8(i32 %x, i32 %y) {
207; CHECK-LABEL: @test8(
208; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
209; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y:%.*]], [[TMP1]]
210; CHECK-NEXT:    ret i32 [[Z]]
211;
212  %not = xor i32 %y, -1
213  %xor = xor i32 %x, %not
214  %z = or i32 %y, %xor
215  ret i32 %z
216}
217
218define i32 @test9(i32 %x, i32 %y) {
219; CHECK-LABEL: @test9(
220; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -1
221; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[TMP1]]
222; CHECK-NEXT:    ret i32 [[Z]]
223;
224  %not = xor i32 %x, -1
225  %xor = xor i32 %not, %y
226  %z = or i32 %x, %xor
227  ret i32 %z
228}
229
230; (A ^ B) | (~A ^ B) --> -1
231
232define i32 @test10(i32 %A, i32 %B) {
233; CHECK-LABEL: @test10(
234; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
235; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
236; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
237; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]]
238; CHECK-NEXT:    ret i32 [[OR]]
239;
240  %xor1 = xor i32 %B, %A
241  %not = xor i32 %A, -1
242  %xor2 = xor i32 %not, %B
243  %or = or i32 %xor1, %xor2
244  ret i32 %or
245}
246
247define i32 @test10_commuted(i32 %A, i32 %B) {
248; CHECK-LABEL: @test10_commuted(
249; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
250; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[B]]
251; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[TMP1]], -1
252; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[XOR2]]
253; CHECK-NEXT:    ret i32 [[OR]]
254;
255  %xor1 = xor i32 %B, %A
256  %not = xor i32 %A, -1
257  %xor2 = xor i32 %not, %B
258  %or = or i32 %xor2, %xor1
259  ret i32 %or
260}
261
262define i32 @test10_extrause(i32 %A, i32 %B, ptr %dst) {
263; CHECK-LABEL: @test10_extrause(
264; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
265; CHECK-NEXT:    store i32 [[NOT]], ptr [[DST:%.*]], align 4
266; CHECK-NEXT:    ret i32 -1
267;
268  %xor1 = xor i32 %B, %A
269  %not = xor i32 %A, -1
270  store i32 %not, ptr %dst
271  %xor2 = xor i32 %not, %B
272  %or = or i32 %xor1, %xor2
273  ret i32 %or
274}
275
276define i32 @test10_commuted_extrause(i32 %A, i32 %B, ptr %dst) {
277; CHECK-LABEL: @test10_commuted_extrause(
278; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
279; CHECK-NEXT:    store i32 [[NOT]], ptr [[DST:%.*]], align 4
280; CHECK-NEXT:    ret i32 -1
281;
282  %xor1 = xor i32 %B, %A
283  %not = xor i32 %A, -1
284  store i32 %not, ptr %dst
285  %xor2 = xor i32 %not, %B
286  %or = or i32 %xor2, %xor1
287  ret i32 %or
288}
289
290; (A ^ B) | ~(A ^ B) --> -1
291define i32 @test10_canonical(i32 %A, i32 %B) {
292; CHECK-LABEL: @test10_canonical(
293; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
294; CHECK-NEXT:    [[XOR2:%.*]] = xor i32 [[A]], [[B]]
295; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[XOR2]], -1
296; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[NOT]]
297; CHECK-NEXT:    ret i32 [[OR]]
298;
299  %xor1 = xor i32 %B, %A
300  %xor2 = xor i32 %A, %B
301  %not = xor i32 %xor2, -1
302  %or = or i32 %xor1, %not
303  ret i32 %or
304}
305
306; (x | y) & ((~x) ^ y) -> (x & y)
307define i32 @test11(i32 %x, i32 %y) {
308; CHECK-LABEL: @test11(
309; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
310; CHECK-NEXT:    ret i32 [[AND]]
311;
312  %or = or i32 %x, %y
313  %neg = xor i32 %x, -1
314  %xor = xor i32 %neg, %y
315  %and = and i32 %or, %xor
316  ret i32 %and
317}
318
319; ((~x) ^ y) & (x | y) -> (x & y)
320define i32 @test12(i32 %x, i32 %y) {
321; CHECK-LABEL: @test12(
322; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
323; CHECK-NEXT:    ret i32 [[AND]]
324;
325  %neg = xor i32 %x, -1
326  %xor = xor i32 %neg, %y
327  %or = or i32 %x, %y
328  %and = and i32 %xor, %or
329  ret i32 %and
330}
331
332define i32 @test12_commuted(i32 %x, i32 %y) {
333; CHECK-LABEL: @test12_commuted(
334; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
335; CHECK-NEXT:    ret i32 [[AND]]
336;
337  %neg = xor i32 %x, -1
338  %xor = xor i32 %neg, %y
339  %or = or i32 %y, %x
340  %and = and i32 %xor, %or
341  ret i32 %and
342}
343
344; ((x | y) ^ (x ^ y)) -> (x & y)
345define i32 @test13(i32 %x, i32 %y) {
346; CHECK-LABEL: @test13(
347; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
348; CHECK-NEXT:    ret i32 [[TMP1]]
349;
350  %1 = xor i32 %y, %x
351  %2 = or i32 %y, %x
352  %3 = xor i32 %2, %1
353  ret i32 %3
354}
355
356; ((x | ~y) ^ (~x | y)) -> x ^ y
357define i32 @test14(i32 %x, i32 %y) {
358; CHECK-LABEL: @test14(
359; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
360; CHECK-NEXT:    ret i32 [[XOR]]
361;
362  %noty = xor i32 %y, -1
363  %notx = xor i32 %x, -1
364  %or1 = or i32 %x, %noty
365  %or2 = or i32 %notx, %y
366  %xor = xor i32 %or1, %or2
367  ret i32 %xor
368}
369
370define i32 @test14_commuted(i32 %x, i32 %y) {
371; CHECK-LABEL: @test14_commuted(
372; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
373; CHECK-NEXT:    ret i32 [[XOR]]
374;
375  %noty = xor i32 %y, -1
376  %notx = xor i32 %x, -1
377  %or1 = or i32 %noty, %x
378  %or2 = or i32 %notx, %y
379  %xor = xor i32 %or1, %or2
380  ret i32 %xor
381}
382
383; ((x & ~y) ^ (~x & y)) -> x ^ y
384define i32 @test15(i32 %x, i32 %y) {
385; CHECK-LABEL: @test15(
386; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
387; CHECK-NEXT:    ret i32 [[XOR]]
388;
389  %noty = xor i32 %y, -1
390  %notx = xor i32 %x, -1
391  %and1 = and i32 %x, %noty
392  %and2 = and i32 %notx, %y
393  %xor = xor i32 %and1, %and2
394  ret i32 %xor
395}
396
397define i32 @test15_commuted(i32 %x, i32 %y) {
398; CHECK-LABEL: @test15_commuted(
399; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
400; CHECK-NEXT:    ret i32 [[XOR]]
401;
402  %noty = xor i32 %y, -1
403  %notx = xor i32 %x, -1
404  %and1 = and i32 %noty, %x
405  %and2 = and i32 %notx, %y
406  %xor = xor i32 %and1, %and2
407  ret i32 %xor
408}
409
410; ((a ^ b) & C1) | (b & C2) -> (a & C1) ^ b iff C1 == ~C2
411
412define i32 @or_and_xor_not_constant_commute0(i32 %a, i32 %b) {
413; CHECK-LABEL: @or_and_xor_not_constant_commute0(
414; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 1
415; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]]
416; CHECK-NEXT:    ret i32 [[XOR]]
417;
418  %or = xor i32 %a, %b
419  %and1 = and i32 %or, 1
420  %and2 = and i32 %b, -2
421  %xor = or i32 %and1, %and2
422  ret i32 %xor
423}
424
425define i9 @or_and_xor_not_constant_commute1(i9 %a, i9 %b) {
426; CHECK-LABEL: @or_and_xor_not_constant_commute1(
427; CHECK-NEXT:    [[TMP1:%.*]] = and i9 [[A:%.*]], 42
428; CHECK-NEXT:    [[XOR:%.*]] = xor i9 [[TMP1]], [[B:%.*]]
429; CHECK-NEXT:    ret i9 [[XOR]]
430;
431  %or = xor i9 %b, %a
432  %and1 = and i9 %or, 42
433  %and2 = and i9 %b, -43
434  %xor = or i9 %and1, %and2
435  ret i9 %xor
436}
437
438define <2 x i9> @or_and_xor_not_constant_commute2_splat(<2 x i9> %a, <2 x i9> %b) {
439; CHECK-LABEL: @or_and_xor_not_constant_commute2_splat(
440; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i9> [[A:%.*]], splat (i9 42)
441; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i9> [[TMP1]], [[B:%.*]]
442; CHECK-NEXT:    ret <2 x i9> [[XOR]]
443;
444  %or = xor <2 x i9> %b, %a
445  %and1 = and <2 x i9> %or, <i9 42, i9 42>
446  %and2 = and <2 x i9> %b, <i9 -43, i9 -43>
447  %xor = or <2 x i9> %and2, %and1
448  ret <2 x i9> %xor
449}
450
451define <2 x i9> @or_and_xor_not_constant_commute3_splat(<2 x i9> %a, <2 x i9> %b) {
452; CHECK-LABEL: @or_and_xor_not_constant_commute3_splat(
453; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i9> [[A:%.*]], splat (i9 42)
454; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i9> [[TMP1]], [[B:%.*]]
455; CHECK-NEXT:    ret <2 x i9> [[XOR]]
456;
457  %or = xor <2 x i9> %a, %b
458  %and1 = and <2 x i9> %or, <i9 42, i9 42>
459  %and2 = and <2 x i9> %b, <i9 -43, i9 -43>
460  %xor = or <2 x i9> %and2, %and1
461  ret <2 x i9> %xor
462}
463
464define i8 @not_or(i8 %x) {
465; CHECK-LABEL: @not_or(
466; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
467; CHECK-NEXT:    [[OR:%.*]] = or i8 [[NOTX]], 7
468; CHECK-NEXT:    ret i8 [[OR]]
469;
470  %notx = xor i8 %x, -1
471  %or = or i8 %notx, 7
472  ret i8 %or
473}
474
475define i8 @not_or_xor(i8 %x) {
476; CHECK-LABEL: @not_or_xor(
477; CHECK-NEXT:    [[NOTX:%.*]] = and i8 [[X:%.*]], -8
478; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[NOTX]], -13
479; CHECK-NEXT:    ret i8 [[XOR]]
480;
481  %notx = xor i8 %x, -1
482  %or = or i8 %notx, 7
483  %xor = xor i8 %or, 12
484  ret i8 %xor
485}
486
487define i8 @xor_or(i8 %x) {
488; CHECK-LABEL: @xor_or(
489; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8
490; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 39
491; CHECK-NEXT:    ret i8 [[OR]]
492;
493  %xor = xor i8 %x, 32
494  %or = or i8 %xor, 7
495  ret i8 %or
496}
497
498define i8 @xor_or2(i8 %x) {
499; CHECK-LABEL: @xor_or2(
500; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8
501; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 39
502; CHECK-NEXT:    ret i8 [[OR]]
503;
504  %xor = xor i8 %x, 33
505  %or = or i8 %xor, 7
506  ret i8 %or
507}
508
509define i8 @xor_or_xor(i8 %x) {
510; CHECK-LABEL: @xor_or_xor(
511; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8
512; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 43
513; CHECK-NEXT:    ret i8 [[XOR2]]
514;
515  %xor1 = xor i8 %x, 33
516  %or = or i8 %xor1, 7
517  %xor2 = xor i8 %or, 12
518  ret i8 %xor2
519}
520
521define i8 @or_xor_or(i8 %x) {
522; CHECK-LABEL: @or_xor_or(
523; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -40
524; CHECK-NEXT:    [[OR2:%.*]] = xor i8 [[TMP1]], 47
525; CHECK-NEXT:    ret i8 [[OR2]]
526;
527  %or1 = or i8 %x, 33
528  %xor = xor i8 %or1, 12
529  %or2 = or i8 %xor, 7
530  ret i8 %or2
531}
532
533define i8 @test17(i8 %A, i8 %B) {
534; CHECK-LABEL: @test17(
535; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
536; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[A]], [[B]]
537; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 33
538; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR1]], [[XOR2]]
539; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
540; CHECK-NEXT:    ret i8 [[RES]]
541;
542  %xor1 = xor i8 %B, %A
543  %not = xor i8 %A, 33
544  %xor2 = xor i8 %not, %B
545  %or = or i8 %xor1, %xor2
546  %res = mul i8 %or, %xor2 ; to increase the use count for the xor
547  ret i8 %res
548}
549
550define i8 @test18(i8 %A, i8 %B) {
551; CHECK-LABEL: @test18(
552; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
553; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[A]], [[B]]
554; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 33
555; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR2]], [[XOR1]]
556; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
557; CHECK-NEXT:    ret i8 [[RES]]
558;
559  %xor1 = xor i8 %B, %A
560  %not = xor i8 %A, 33
561  %xor2 = xor i8 %not, %B
562  %or = or i8 %xor2, %xor1
563  %res = mul i8 %or, %xor2 ; to increase the use count for the xor
564  ret i8 %res
565}
566
567; ((x | y) ^ (~x | ~y)) -> ~(x ^ y)
568define i32 @test19(i32 %x, i32 %y) {
569; CHECK-LABEL: @test19(
570; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
571; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
572; CHECK-NEXT:    ret i32 [[XOR]]
573;
574  %noty = xor i32 %y, -1
575  %notx = xor i32 %x, -1
576  %or1 = or i32 %x, %y
577  %or2 = or i32 %notx, %noty
578  %xor = xor i32 %or1, %or2
579  ret i32 %xor
580}
581
582; ((x | y) ^ (~y | ~x)) -> ~(x ^ y)
583define i32 @test20(i32 %x, i32 %y) {
584; CHECK-LABEL: @test20(
585; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
586; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
587; CHECK-NEXT:    ret i32 [[XOR]]
588;
589  %noty = xor i32 %y, -1
590  %notx = xor i32 %x, -1
591  %or1 = or i32 %x, %y
592  %or2 = or i32 %noty, %notx
593  %xor = xor i32 %or1, %or2
594  ret i32 %xor
595}
596
597; ((~x | ~y) ^ (x | y)) -> ~(x ^ y)
598define i32 @test21(i32 %x, i32 %y) {
599; CHECK-LABEL: @test21(
600; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
601; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
602; CHECK-NEXT:    ret i32 [[XOR]]
603;
604  %noty = xor i32 %y, -1
605  %notx = xor i32 %x, -1
606  %or1 = or i32 %notx, %noty
607  %or2 = or i32 %x, %y
608  %xor = xor i32 %or1, %or2
609  ret i32 %xor
610}
611
612; ((~x | ~y) ^ (y | x)) -> ~(x ^ y)
613define i32 @test22(i32 %x, i32 %y) {
614; CHECK-LABEL: @test22(
615; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
616; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
617; CHECK-NEXT:    ret i32 [[XOR]]
618;
619  %noty = xor i32 %y, -1
620  %notx = xor i32 %x, -1
621  %or1 = or i32 %notx, %noty
622  %or2 = or i32 %y, %x
623  %xor = xor i32 %or1, %or2
624  ret i32 %xor
625}
626
627; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
628define i8 @test23(i8 %A) {
629; CHECK-LABEL: @test23(
630; CHECK-NEXT:    ret i8 -1
631;
632  %B = or i8 %A, -2
633  %C = xor i8 %B, 13
634  %D = or i8 %C, 1
635  %E = xor i8 %D, 12
636  ret i8 %E
637}
638
639define i8 @test23v(<2 x i8> %A) {
640; CHECK-LABEL: @test23v(
641; CHECK-NEXT:    ret i8 -1
642;
643  %B = or <2 x i8> %A, <i8 -2, i8 0>
644  %CV = xor <2 x i8> %B, <i8 13, i8 13>
645  %C = extractelement <2 x i8> %CV, i32 0
646  %D = or i8 %C, 1
647  %E = xor i8 %D, 12
648  ret i8 %E
649}
650
651; ~(a | b) | (~a & b);
652define i32 @PR45977_f1(i32 %a, i32 %b) {
653; CHECK-LABEL: @PR45977_f1(
654; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A:%.*]], -1
655; CHECK-NEXT:    ret i32 [[NOT]]
656;
657  %not = xor i32 %a, -1
658  %andnot = and i32 %not, %b
659  %or = or i32 %a, %b
660  %notor = xor i32 %or, -1
661  %res = or i32 %notor, %andnot
662  ret i32 %res
663}
664
665; (a | b) ^ (a | ~b)
666define i32 @PR45977_f2(i32 %a, i32 %b) {
667; CHECK-LABEL: @PR45977_f2(
668; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], -1
669; CHECK-NEXT:    ret i32 [[TMP1]]
670;
671  %or = or i32 %a, %b
672  %not = xor i32 %b, -1
673  %ornot = or i32 %a, %not
674  %res = xor i32 %or, %ornot
675  ret i32 %res
676}
677
678define i8 @or_xor_common_op_commute0(i8 %x, i8 %y, i8 %z) {
679; CHECK-LABEL: @or_xor_common_op_commute0(
680; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
681; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z:%.*]]
682; CHECK-NEXT:    ret i8 [[R]]
683;
684  %or = or i8 %x, %y
685  %xor = xor i8 %x, %z
686  %r = or i8 %or, %xor
687  ret i8 %r
688}
689
690define i8 @or_xor_common_op_commute1(i8 %x, i8 %y, i8 %z) {
691; CHECK-LABEL: @or_xor_common_op_commute1(
692; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
693; CHECK-NEXT:    call void @use(i8 [[OR]])
694; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z:%.*]]
695; CHECK-NEXT:    ret i8 [[R]]
696;
697  %or = or i8 %y, %x
698  call void @use(i8 %or)
699  %xor = xor i8 %x, %z
700  %r = or i8 %or, %xor
701  ret i8 %r
702}
703
704define i8 @or_xor_common_op_commute2(i8 %x, i8 %y, i8 %z) {
705; CHECK-LABEL: @or_xor_common_op_commute2(
706; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
707; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Z:%.*]], [[X]]
708; CHECK-NEXT:    call void @use(i8 [[XOR]])
709; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z]]
710; CHECK-NEXT:    ret i8 [[R]]
711;
712  %or = or i8 %x, %y
713  %xor = xor i8 %z, %x
714  call void @use(i8 %xor)
715  %r = or i8 %or, %xor
716  ret i8 %r
717}
718
719define i8 @or_xor_common_op_commute3(i8 %x, i8 %y, i8 %z) {
720; CHECK-LABEL: @or_xor_common_op_commute3(
721; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
722; CHECK-NEXT:    call void @use(i8 [[OR]])
723; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Z:%.*]], [[X]]
724; CHECK-NEXT:    call void @use(i8 [[XOR]])
725; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z]]
726; CHECK-NEXT:    ret i8 [[R]]
727;
728  %or = or i8 %y, %x
729  call void @use(i8 %or)
730  %xor = xor i8 %z, %x
731  call void @use(i8 %xor)
732  %r = or i8 %or, %xor
733  ret i8 %r
734}
735
736define <2 x i8> @or_xor_common_op_commute4(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
737; CHECK-LABEL: @or_xor_common_op_commute4(
738; CHECK-NEXT:    [[OR:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
739; CHECK-NEXT:    [[R:%.*]] = or <2 x i8> [[OR]], [[Z:%.*]]
740; CHECK-NEXT:    ret <2 x i8> [[R]]
741;
742  %or = or <2 x i8> %x, %y
743  %xor = xor <2 x i8> %x, %z
744  %r = or <2 x i8> %xor, %or
745  ret <2 x i8> %r
746}
747
748define i8 @or_xor_common_op_commute5(i8 %x, i8 %y, i8 %z) {
749; CHECK-LABEL: @or_xor_common_op_commute5(
750; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
751; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z:%.*]]
752; CHECK-NEXT:    ret i8 [[R]]
753;
754  %or = or i8 %y, %x
755  %xor = xor i8 %x, %z
756  %r = or i8 %xor, %or
757  ret i8 %r
758}
759
760define i8 @or_xor_common_op_commute6(i8 %x, i8 %y, i8 %z) {
761; CHECK-LABEL: @or_xor_common_op_commute6(
762; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
763; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z:%.*]]
764; CHECK-NEXT:    ret i8 [[R]]
765;
766  %or = or i8 %x, %y
767  %xor = xor i8 %z, %x
768  %r = or i8 %xor, %or
769  ret i8 %r
770}
771
772define i8 @or_xor_common_op_commute7(i8 %x, i8 %y, i8 %z) {
773; CHECK-LABEL: @or_xor_common_op_commute7(
774; CHECK-NEXT:    [[OR:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
775; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[Z:%.*]]
776; CHECK-NEXT:    ret i8 [[R]]
777;
778  %or = or i8 %y, %x
779  %xor = xor i8 %z, %x
780  %r = or i8 %xor, %or
781  ret i8 %r
782}
783
784; negative test - need common operand
785
786define i8 @or_xor_notcommon_op(i8 %x, i8 %y, i8 %z, i8 %q) {
787; CHECK-LABEL: @or_xor_notcommon_op(
788; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
789; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Q:%.*]], [[Z:%.*]]
790; CHECK-NEXT:    [[R:%.*]] = or i8 [[OR]], [[XOR]]
791; CHECK-NEXT:    ret i8 [[R]]
792;
793  %or = or i8 %x, %y
794  %xor = xor i8 %q, %z
795  %r = or i8 %or, %xor
796  ret i8 %r
797}
798
799define i4 @or_not_xor_common_op_commute0(i4 %x, i4 %y, i4 %z) {
800; CHECK-LABEL: @or_not_xor_common_op_commute0(
801; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[X:%.*]], [[Y:%.*]]
802; CHECK-NEXT:    [[NAND:%.*]] = xor i4 [[TMP1]], -1
803; CHECK-NEXT:    [[O2:%.*]] = or i4 [[Z:%.*]], [[NAND]]
804; CHECK-NEXT:    ret i4 [[O2]]
805;
806  %notx = xor i4 %x, -1
807  %xor = xor i4 %x, %y
808  %o1 = or i4 %notx, %z
809  %o2 = or i4 %o1, %xor
810  ret i4 %o2
811}
812
813define i8 @or_not_xor_common_op_commute1(i8 %x, i8 %y, i8 %z) {
814; CHECK-LABEL: @or_not_xor_common_op_commute1(
815; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
816; CHECK-NEXT:    call void @use(i8 [[NOTX]])
817; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], [[Y:%.*]]
818; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1
819; CHECK-NEXT:    [[O2:%.*]] = or i8 [[Z:%.*]], [[NAND]]
820; CHECK-NEXT:    ret i8 [[O2]]
821;
822  %notx = xor i8 %x, -1
823  call void @use(i8 %notx)
824  %xor = xor i8 %x, %y
825  %o1 = or i8 %notx, %z
826  %o2 = or i8 %xor, %o1
827  ret i8 %o2
828}
829
830define i8 @or_not_xor_common_op_commute2(i8 %x, i8 %y, i8 %p) {
831; CHECK-LABEL: @or_not_xor_common_op_commute2(
832; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[P:%.*]]
833; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
834; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1
835; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]
836; CHECK-NEXT:    ret i8 [[O2]]
837;
838  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion
839  %notx = xor i8 %x, -1
840  %xor = xor i8 %x, %y
841  %o1 = or i8 %z, %notx
842  %o2 = or i8 %xor, %o1
843  ret i8 %o2
844}
845
846define i8 @or_not_xor_common_op_commute3(i8 %x, i8 %y, i8 %p) {
847; CHECK-LABEL: @or_not_xor_common_op_commute3(
848; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[P:%.*]]
849; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
850; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1
851; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]
852; CHECK-NEXT:    ret i8 [[O2]]
853;
854  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion
855  %notx = xor i8 %x, -1
856  %xor = xor i8 %x, %y
857  %o1 = or i8 %z, %notx
858  %o2 = or i8 %o1, %xor
859  ret i8 %o2
860}
861
862define <2 x i4> @or_not_xor_common_op_commute4(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
863; CHECK-LABEL: @or_not_xor_common_op_commute4(
864; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[Y:%.*]], [[X:%.*]]
865; CHECK-NEXT:    [[NAND:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 -1)
866; CHECK-NEXT:    [[O2:%.*]] = or <2 x i4> [[Z:%.*]], [[NAND]]
867; CHECK-NEXT:    ret <2 x i4> [[O2]]
868;
869  %notx = xor <2 x i4> %x, <i4 -1, i4 -1>
870  %xor = xor <2 x i4> %y, %x
871  %o1 = or <2 x i4> %notx, %z
872  %o2 = or <2 x i4> %o1, %xor
873  ret <2 x i4> %o2
874}
875
876define i8 @or_not_xor_common_op_commute5(i8 %x, i8 %y, i8 %z) {
877; CHECK-LABEL: @or_not_xor_common_op_commute5(
878; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
879; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1
880; CHECK-NEXT:    [[O2:%.*]] = or i8 [[Z:%.*]], [[NAND]]
881; CHECK-NEXT:    ret i8 [[O2]]
882;
883  %notx = xor i8 %x, -1
884  %xor = xor i8 %y, %x
885  %o1 = or i8 %notx, %z
886  %o2 = or i8 %xor, %o1
887  ret i8 %o2
888}
889
890define i8 @or_not_xor_common_op_commute6(i8 %x, i8 %y, i8 %p) {
891; CHECK-LABEL: @or_not_xor_common_op_commute6(
892; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[P:%.*]]
893; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
894; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1
895; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]
896; CHECK-NEXT:    ret i8 [[O2]]
897;
898  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion
899  %notx = xor i8 %x, -1
900  %xor = xor i8 %y, %x
901  %o1 = or i8 %z, %notx
902  %o2 = or i8 %xor, %o1
903  ret i8 %o2
904}
905
906define i8 @or_not_xor_common_op_commute7(i8 %x, i8 %y, i8 %p) {
907; CHECK-LABEL: @or_not_xor_common_op_commute7(
908; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[P:%.*]]
909; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
910; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[TMP1]], -1
911; CHECK-NEXT:    [[O2:%.*]] = or i8 [[NAND]], [[Z]]
912; CHECK-NEXT:    ret i8 [[O2]]
913;
914  %z = sub i8 0, %p ; thwart complexity-based canonicalizaion
915  %notx = xor i8 %x, -1
916  %xor = xor i8 %y, %x
917  %o1 = or i8 %z, %notx
918  %o2 = or i8 %o1, %xor
919  ret i8 %o2
920}
921
922; negative test - too many uses for basic check (but this could be enhanced)
923
924define i8 @or_not_xor_common_op_use1(i8 %x, i8 %y, i8 %z) {
925; CHECK-LABEL: @or_not_xor_common_op_use1(
926; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
927; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X]], [[Y:%.*]]
928; CHECK-NEXT:    call void @use(i8 [[XOR]])
929; CHECK-NEXT:    [[O1:%.*]] = or i8 [[Z:%.*]], [[NOTX]]
930; CHECK-NEXT:    [[O2:%.*]] = or i8 [[XOR]], [[O1]]
931; CHECK-NEXT:    ret i8 [[O2]]
932;
933  %notx = xor i8 %x, -1
934  %xor = xor i8 %x, %y
935  call void @use(i8 %xor)
936  %o1 = or i8 %notx, %z
937  %o2 = or i8 %xor, %o1
938  ret i8 %o2
939}
940
941; negative test - too many uses
942
943define i8 @or_not_xor_common_op_use2(i8 %x, i8 %y, i8 %z) {
944; CHECK-LABEL: @or_not_xor_common_op_use2(
945; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
946; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X]], [[Y:%.*]]
947; CHECK-NEXT:    [[O1:%.*]] = or i8 [[Z:%.*]], [[NOTX]]
948; CHECK-NEXT:    call void @use(i8 [[O1]])
949; CHECK-NEXT:    [[O2:%.*]] = or i8 [[XOR]], [[O1]]
950; CHECK-NEXT:    ret i8 [[O2]]
951;
952  %notx = xor i8 %x, -1
953  %xor = xor i8 %x, %y
954  %o1 = or i8 %notx, %z
955  call void @use(i8 %o1)
956  %o2 = or i8 %xor, %o1
957  ret i8 %o2
958}
959
960define i4 @or_nand_xor_common_op_commute0(i4 %x, i4 %y, i4 %z) {
961; CHECK-LABEL: @or_nand_xor_common_op_commute0(
962; CHECK-NEXT:    [[AND:%.*]] = and i4 [[X:%.*]], [[Z:%.*]]
963; CHECK-NEXT:    [[TMP1:%.*]] = and i4 [[AND]], [[Y:%.*]]
964; CHECK-NEXT:    [[R:%.*]] = xor i4 [[TMP1]], -1
965; CHECK-NEXT:    ret i4 [[R]]
966;
967  %and = and i4 %x, %z
968  %nand = xor i4 %and, -1
969  %xor = xor i4 %x, %y
970  %r = or i4 %nand, %xor
971  ret i4 %r
972}
973
974define <2 x i4> @or_nand_xor_common_op_commute1(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
975; CHECK-LABEL: @or_nand_xor_common_op_commute1(
976; CHECK-NEXT:    [[AND:%.*]] = and <2 x i4> [[Z:%.*]], [[X:%.*]]
977; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i4> [[AND]], [[Y:%.*]]
978; CHECK-NEXT:    [[R:%.*]] = xor <2 x i4> [[TMP1]], splat (i4 -1)
979; CHECK-NEXT:    ret <2 x i4> [[R]]
980;
981  %and = and <2 x i4> %z, %x
982  %nand = xor <2 x i4> %and, <i4 poison, i4 -1>
983  %xor = xor <2 x i4> %x, %y
984  %r = or <2 x i4> %xor, %nand
985  ret <2 x i4> %r
986}
987
988define i8 @or_nand_xor_common_op_commute2(i8 %x, i8 %y, i8 %z) {
989; CHECK-LABEL: @or_nand_xor_common_op_commute2(
990; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Z:%.*]]
991; CHECK-NEXT:    call void @use(i8 [[AND]])
992; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[AND]], [[Y:%.*]]
993; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -1
994; CHECK-NEXT:    ret i8 [[R]]
995;
996  %and = and i8 %x, %z
997  call void @use(i8 %and)
998  %nand = xor i8 %and, -1
999  %xor = xor i8 %y, %x
1000  %r = or i8 %nand, %xor
1001  ret i8 %r
1002}
1003
1004define i8 @or_nand_xor_common_op_commute3(i8 %x, i8 %y, i8 %z) {
1005; CHECK-LABEL: @or_nand_xor_common_op_commute3(
1006; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Z:%.*]], [[X:%.*]]
1007; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[AND]], -1
1008; CHECK-NEXT:    call void @use(i8 [[NAND]])
1009; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[AND]], [[Y:%.*]]
1010; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -1
1011; CHECK-NEXT:    ret i8 [[R]]
1012;
1013  %and = and i8 %z, %x
1014  %nand = xor i8 %and, -1
1015  call void @use(i8 %nand)
1016  %xor = xor i8 %y, %x
1017  %r = or i8 %xor, %nand
1018  ret i8 %r
1019}
1020
1021define i8 @or_nand_xor_common_op_commute3_use2(i8 %x, i8 %y, i8 %z) {
1022; CHECK-LABEL: @or_nand_xor_common_op_commute3_use2(
1023; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Z:%.*]], [[X:%.*]]
1024; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X]]
1025; CHECK-NEXT:    call void @use(i8 [[XOR]])
1026; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[AND]], [[Y]]
1027; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP1]], -1
1028; CHECK-NEXT:    ret i8 [[R]]
1029;
1030  %and = and i8 %z, %x
1031  %nand = xor i8 %and, -1
1032  %xor = xor i8 %y, %x
1033  call void @use(i8 %xor)
1034  %r = or i8 %xor, %nand
1035  ret i8 %r
1036}
1037
1038; negative test - too many extra uses
1039
1040define i8 @or_nand_xor_common_op_commute3_use3(i8 %x, i8 %y, i8 %z) {
1041; CHECK-LABEL: @or_nand_xor_common_op_commute3_use3(
1042; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Z:%.*]], [[X:%.*]]
1043; CHECK-NEXT:    [[NAND:%.*]] = xor i8 [[AND]], -1
1044; CHECK-NEXT:    call void @use(i8 [[NAND]])
1045; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Y:%.*]], [[X]]
1046; CHECK-NEXT:    call void @use(i8 [[XOR]])
1047; CHECK-NEXT:    [[R:%.*]] = or i8 [[XOR]], [[NAND]]
1048; CHECK-NEXT:    ret i8 [[R]]
1049;
1050  %and = and i8 %z, %x
1051  %nand = xor i8 %and, -1
1052  call void @use(i8 %nand)
1053  %xor = xor i8 %y, %x
1054  call void @use(i8 %xor)
1055  %r = or i8 %xor, %nand
1056  ret i8 %r
1057}
1058
1059; (a ^ 4) & (a ^ ~4) -> -1
1060define i32 @PR75692_1(i32 %x) {
1061; CHECK-LABEL: @PR75692_1(
1062; CHECK-NEXT:    ret i32 -1
1063;
1064  %t2 = xor i32 %x, 4
1065  %t3 = xor i32 %x, -5
1066  %t4 = or i32 %t2, %t3
1067  ret i32 %t4
1068}
1069
1070; (a ^ 4) & (a ^ 3) is not -1
1071define i32 @PR75692_2(i32 %x) {
1072; CHECK-LABEL: @PR75692_2(
1073; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[X:%.*]], 4
1074; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[X]], -4
1075; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]
1076; CHECK-NEXT:    ret i32 [[T4]]
1077;
1078  %t2 = xor i32 %x, 4
1079  %t3 = xor i32 %x, -4
1080  %t4 = or i32 %t2, %t3
1081  ret i32 %t4
1082}
1083
1084; (a ^ 4) & (b ^ ~4) is not -1, since a != b is possible
1085define i32 @PR75692_3(i32 %x, i32 %y) {
1086; CHECK-LABEL: @PR75692_3(
1087; CHECK-NEXT:    [[T2:%.*]] = xor i32 [[X:%.*]], 4
1088; CHECK-NEXT:    [[T3:%.*]] = xor i32 [[Y:%.*]], -5
1089; CHECK-NEXT:    [[T4:%.*]] = or i32 [[T2]], [[T3]]
1090; CHECK-NEXT:    ret i32 [[T4]]
1091;
1092  %t2 = xor i32 %x, 4
1093  %t3 = xor i32 %y, -5
1094  %t4 = or i32 %t2, %t3
1095  ret i32 %t4
1096}
1097
1098define i32 @or_xor_not(i32 %x, i32 %y) {
1099; CHECK-LABEL: @or_xor_not(
1100; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
1101; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y:%.*]], [[TMP1]]
1102; CHECK-NEXT:    ret i32 [[OR1]]
1103;
1104  %not = xor i32 %y, -1
1105  %xor = xor i32 %x, %not
1106  %or1 = or i32 %xor, %y
1107  ret i32 %or1
1108}
1109
1110define i32 @or_xor_not_uses1(i32 %x, i32 %y) {
1111; CHECK-LABEL: @or_xor_not_uses1(
1112; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[Y:%.*]], -1
1113; CHECK-NEXT:    call void @use(i32 [[NOT]])
1114; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
1115; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[TMP1]]
1116; CHECK-NEXT:    ret i32 [[OR1]]
1117;
1118  %not = xor i32 %y, -1
1119  call void @use(i32 %not)
1120  %xor = xor i32 %x, %not
1121  %or1 = or i32 %xor, %y
1122  ret i32 %or1
1123}
1124
1125define i32 @or_xor_not_uses2(i32 %x, i32 %y) {
1126; CHECK-LABEL: @or_xor_not_uses2(
1127; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1128; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
1129; CHECK-NEXT:    call void @use(i32 [[XOR]])
1130; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[Y]], [[XOR]]
1131; CHECK-NEXT:    ret i32 [[OR1]]
1132;
1133  %not = xor i32 %y, -1
1134  %xor = xor i32 %x, %not
1135  call void @use(i32 %xor)
1136  %or1 = or i32 %xor, %y
1137  ret i32 %or1
1138}
1139
1140define i32 @or_xor_and_commuted1(i32 %x, i32 %y) {
1141; CHECK-LABEL: @or_xor_and_commuted1(
1142; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
1143; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], -1
1144; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
1145; CHECK-NEXT:    ret i32 [[OR1]]
1146;
1147  %yy = mul i32 %y, %y ; thwart complexity-based ordering
1148  %not = xor i32 %yy, -1
1149  %xor = xor i32 %not, %x
1150  %or1 = or i32 %yy, %xor
1151  ret i32 %or1
1152}
1153
1154define i32 @or_xor_and_commuted2(i32 %x, i32 %y) {
1155; CHECK-LABEL: @or_xor_and_commuted2(
1156; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
1157; CHECK-NEXT:    [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
1158; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[XX]], -1
1159; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
1160; CHECK-NEXT:    ret i32 [[OR1]]
1161;
1162  %yy = mul i32 %y, %y ; thwart complexity-based ordering
1163  %xx = mul i32 %x, %x ; thwart complexity-based ordering
1164  %not = xor i32 %yy, -1
1165  %xor = xor i32 %xx, %not
1166  %or1 = or i32 %xor, %yy
1167  ret i32 %or1
1168}
1169
1170; (A ^ B) | ((B ^ C) ^ A) -> (A ^ B) | C and commuted variants.
1171
1172define i32 @or_xor_tree_0000(i32 %ax, i32 %bx, i32 %cx) {
1173; CHECK-LABEL: @or_xor_tree_0000(
1174; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1175; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1176; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1177; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1178; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1179; CHECK-NEXT:    ret i32 [[OR]]
1180;
1181  %a = mul i32 %ax, 42
1182  %b = mul i32 %bx, 42
1183  %c = mul i32 %cx, 42
1184  %xor1 = xor i32 %a, %b
1185  %xor2 = xor i32 %b, %c
1186  %xor3 = xor i32 %xor2, %a
1187  %or = or i32 %xor1, %xor3
1188  ret i32 %or
1189}
1190
1191define i32 @or_xor_tree_0001(i32 %ax, i32 %bx, i32 %cx) {
1192; CHECK-LABEL: @or_xor_tree_0001(
1193; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1194; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1195; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1196; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1197; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1198; CHECK-NEXT:    ret i32 [[OR]]
1199;
1200  %a = mul i32 %ax, 42
1201  %b = mul i32 %bx, 42
1202  %c = mul i32 %cx, 42
1203  %xor1 = xor i32 %b, %a
1204  %xor2 = xor i32 %b, %c
1205  %xor3 = xor i32 %xor2, %a
1206  %or = or i32 %xor1, %xor3
1207  ret i32 %or
1208}
1209
1210define i32 @or_xor_tree_0010(i32 %ax, i32 %bx, i32 %cx) {
1211; CHECK-LABEL: @or_xor_tree_0010(
1212; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1213; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1214; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1215; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1216; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1217; CHECK-NEXT:    ret i32 [[OR]]
1218;
1219  %a = mul i32 %ax, 42
1220  %b = mul i32 %bx, 42
1221  %c = mul i32 %cx, 42
1222  %xor1 = xor i32 %a, %b
1223  %xor2 = xor i32 %c, %b
1224  %xor3 = xor i32 %xor2, %a
1225  %or = or i32 %xor1, %xor3
1226  ret i32 %or
1227}
1228
1229define i32 @or_xor_tree_0011(i32 %ax, i32 %bx, i32 %cx) {
1230; CHECK-LABEL: @or_xor_tree_0011(
1231; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1232; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1233; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1234; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1235; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1236; CHECK-NEXT:    ret i32 [[OR]]
1237;
1238  %a = mul i32 %ax, 42
1239  %b = mul i32 %bx, 42
1240  %c = mul i32 %cx, 42
1241  %xor1 = xor i32 %b, %a
1242  %xor2 = xor i32 %c, %b
1243  %xor3 = xor i32 %xor2, %a
1244  %or = or i32 %xor1, %xor3
1245  ret i32 %or
1246}
1247
1248define i32 @or_xor_tree_0100(i32 %ax, i32 %bx, i32 %cx) {
1249; CHECK-LABEL: @or_xor_tree_0100(
1250; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1251; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1252; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1253; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1254; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1255; CHECK-NEXT:    ret i32 [[OR]]
1256;
1257  %a = mul i32 %ax, 42
1258  %b = mul i32 %bx, 42
1259  %c = mul i32 %cx, 42
1260  %xor1 = xor i32 %a, %b
1261  %xor2 = xor i32 %b, %c
1262  %xor3 = xor i32 %a, %xor2
1263  %or = or i32 %xor1, %xor3
1264  ret i32 %or
1265}
1266
1267define i32 @or_xor_tree_0101(i32 %ax, i32 %bx, i32 %cx) {
1268; CHECK-LABEL: @or_xor_tree_0101(
1269; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1270; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1271; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1272; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1273; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1274; CHECK-NEXT:    ret i32 [[OR]]
1275;
1276  %a = mul i32 %ax, 42
1277  %b = mul i32 %bx, 42
1278  %c = mul i32 %cx, 42
1279  %xor1 = xor i32 %b, %a
1280  %xor2 = xor i32 %b, %c
1281  %xor3 = xor i32 %a, %xor2
1282  %or = or i32 %xor1, %xor3
1283  ret i32 %or
1284}
1285
1286define i32 @or_xor_tree_0110(i32 %ax, i32 %bx, i32 %cx) {
1287; CHECK-LABEL: @or_xor_tree_0110(
1288; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1289; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1290; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1291; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1292; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1293; CHECK-NEXT:    ret i32 [[OR]]
1294;
1295  %a = mul i32 %ax, 42
1296  %b = mul i32 %bx, 42
1297  %c = mul i32 %cx, 42
1298  %xor1 = xor i32 %a, %b
1299  %xor2 = xor i32 %c, %b
1300  %xor3 = xor i32 %a, %xor2
1301  %or = or i32 %xor1, %xor3
1302  ret i32 %or
1303}
1304
1305define i32 @or_xor_tree_0111(i32 %ax, i32 %bx, i32 %cx) {
1306; CHECK-LABEL: @or_xor_tree_0111(
1307; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1308; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1309; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1310; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1311; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1312; CHECK-NEXT:    ret i32 [[OR]]
1313;
1314  %a = mul i32 %ax, 42
1315  %b = mul i32 %bx, 42
1316  %c = mul i32 %cx, 42
1317  %xor1 = xor i32 %b, %a
1318  %xor2 = xor i32 %c, %b
1319  %xor3 = xor i32 %a, %xor2
1320  %or = or i32 %xor1, %xor3
1321  ret i32 %or
1322}
1323
1324define i32 @or_xor_tree_1000(i32 %ax, i32 %bx, i32 %cx) {
1325; CHECK-LABEL: @or_xor_tree_1000(
1326; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1327; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1328; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1329; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1330; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1331; CHECK-NEXT:    ret i32 [[OR]]
1332;
1333  %a = mul i32 %ax, 42
1334  %b = mul i32 %bx, 42
1335  %c = mul i32 %cx, 42
1336  %xor1 = xor i32 %a, %b
1337  %xor2 = xor i32 %b, %c
1338  %xor3 = xor i32 %xor2, %a
1339  %or = or i32 %xor3, %xor1
1340  ret i32 %or
1341}
1342
1343define i32 @or_xor_tree_1001(i32 %ax, i32 %bx, i32 %cx) {
1344; CHECK-LABEL: @or_xor_tree_1001(
1345; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1346; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1347; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1348; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1349; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1350; CHECK-NEXT:    ret i32 [[OR]]
1351;
1352  %a = mul i32 %ax, 42
1353  %b = mul i32 %bx, 42
1354  %c = mul i32 %cx, 42
1355  %xor1 = xor i32 %b, %a
1356  %xor2 = xor i32 %b, %c
1357  %xor3 = xor i32 %xor2, %a
1358  %or = or i32 %xor3, %xor1
1359  ret i32 %or
1360}
1361
1362define i32 @or_xor_tree_1010(i32 %ax, i32 %bx, i32 %cx) {
1363; CHECK-LABEL: @or_xor_tree_1010(
1364; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1365; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1366; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1367; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1368; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1369; CHECK-NEXT:    ret i32 [[OR]]
1370;
1371  %a = mul i32 %ax, 42
1372  %b = mul i32 %bx, 42
1373  %c = mul i32 %cx, 42
1374  %xor1 = xor i32 %a, %b
1375  %xor2 = xor i32 %c, %b
1376  %xor3 = xor i32 %xor2, %a
1377  %or = or i32 %xor3, %xor1
1378  ret i32 %or
1379}
1380
1381define i32 @or_xor_tree_1011(i32 %ax, i32 %bx, i32 %cx) {
1382; CHECK-LABEL: @or_xor_tree_1011(
1383; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1384; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1385; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1386; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1387; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1388; CHECK-NEXT:    ret i32 [[OR]]
1389;
1390  %a = mul i32 %ax, 42
1391  %b = mul i32 %bx, 42
1392  %c = mul i32 %cx, 42
1393  %xor1 = xor i32 %b, %a
1394  %xor2 = xor i32 %c, %b
1395  %xor3 = xor i32 %xor2, %a
1396  %or = or i32 %xor3, %xor1
1397  ret i32 %or
1398}
1399
1400define i32 @or_xor_tree_1100(i32 %ax, i32 %bx, i32 %cx) {
1401; CHECK-LABEL: @or_xor_tree_1100(
1402; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1403; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1404; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1405; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1406; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1407; CHECK-NEXT:    ret i32 [[OR]]
1408;
1409  %a = mul i32 %ax, 42
1410  %b = mul i32 %bx, 42
1411  %c = mul i32 %cx, 42
1412  %xor1 = xor i32 %a, %b
1413  %xor2 = xor i32 %b, %c
1414  %xor3 = xor i32 %a, %xor2
1415  %or = or i32 %xor3, %xor1
1416  ret i32 %or
1417}
1418
1419define i32 @or_xor_tree_1101(i32 %ax, i32 %bx, i32 %cx) {
1420; CHECK-LABEL: @or_xor_tree_1101(
1421; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1422; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1423; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1424; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1425; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1426; CHECK-NEXT:    ret i32 [[OR]]
1427;
1428  %a = mul i32 %ax, 42
1429  %b = mul i32 %bx, 42
1430  %c = mul i32 %cx, 42
1431  %xor1 = xor i32 %b, %a
1432  %xor2 = xor i32 %b, %c
1433  %xor3 = xor i32 %a, %xor2
1434  %or = or i32 %xor3, %xor1
1435  ret i32 %or
1436}
1437
1438define i32 @or_xor_tree_1110(i32 %ax, i32 %bx, i32 %cx) {
1439; CHECK-LABEL: @or_xor_tree_1110(
1440; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1441; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1442; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1443; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[A]], [[B]]
1444; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1445; CHECK-NEXT:    ret i32 [[OR]]
1446;
1447  %a = mul i32 %ax, 42
1448  %b = mul i32 %bx, 42
1449  %c = mul i32 %cx, 42
1450  %xor1 = xor i32 %a, %b
1451  %xor2 = xor i32 %c, %b
1452  %xor3 = xor i32 %a, %xor2
1453  %or = or i32 %xor3, %xor1
1454  ret i32 %or
1455}
1456
1457define i32 @or_xor_tree_1111(i32 %ax, i32 %bx, i32 %cx) {
1458; CHECK-LABEL: @or_xor_tree_1111(
1459; CHECK-NEXT:    [[A:%.*]] = mul i32 [[AX:%.*]], 42
1460; CHECK-NEXT:    [[B:%.*]] = mul i32 [[BX:%.*]], 42
1461; CHECK-NEXT:    [[C:%.*]] = mul i32 [[CX:%.*]], 42
1462; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[A]]
1463; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR1]], [[C]]
1464; CHECK-NEXT:    ret i32 [[OR]]
1465;
1466  %a = mul i32 %ax, 42
1467  %b = mul i32 %bx, 42
1468  %c = mul i32 %cx, 42
1469  %xor1 = xor i32 %b, %a
1470  %xor2 = xor i32 %c, %b
1471  %xor3 = xor i32 %a, %xor2
1472  %or = or i32 %xor3, %xor1
1473  ret i32 %or
1474}
1475