1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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 %tmp1) {
37; CHECK-LABEL: @test2(
38; CHECK-NEXT:    [[OVM:%.*]] = and i32 [[TMP1:%.*]], 32
39; CHECK-NEXT:    [[OV1101:%.*]] = or i32 [[OVM]], 8
40; CHECK-NEXT:    ret i32 [[OV1101]]
41;
42  %ovm = and i32 %tmp1, 32
43  %ov3 = add i32 %ovm, 145
44  %ov110 = xor i32 %ov3, 153
45  ret i32 %ov110
46}
47
48define i32 @test3(i32 %tmp1) {
49; CHECK-LABEL: @test3(
50; CHECK-NEXT:    [[OVM:%.*]] = and i32 [[TMP1:%.*]], 32
51; CHECK-NEXT:    [[OV1101:%.*]] = or i32 [[OVM]], 8
52; CHECK-NEXT:    ret i32 [[OV1101]]
53;
54  %ovm = or i32 %tmp1, 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 [[B_NOT]], [[A:%.*]]
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 [[B_NOT]], [[A:%.*]]
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 [[FORCE]], [[A]]
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 [[FORCE]], [[A]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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 [[TMP1]], [[B:%.*]]
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, i32* %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]], i32* [[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, i32* %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, i32* %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]], i32* [[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, i32* %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, i32* %p1, i32* %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]], i32* [[P1:%.*]], align 4
476; CHECK-NEXT:    [[AB:%.*]] = or i32 [[A]], [[B:%.*]]
477; CHECK-NEXT:    store i32 [[AB]], i32* [[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, i32* %p1
483  %ab = or i32 %a, %b
484  store i32 %ab, i32* %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