• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4; X | ~(X | Y) --> X | ~Y
5
6define i32 @test1(i32 %x, i32 %y) {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
9; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
10; CHECK-NEXT:    ret i32 [[Z]]
11;
12  %or = or i32 %x, %y
13  %not = xor i32 %or, -1
14  %z = or i32 %x, %not
15  ret i32 %z
16}
17
18; Commute (rename) the inner 'or' operands:
19; Y | ~(X | Y) --> ~X | Y
20
21define i32 @test2(i32 %x, i32 %y) {
22; CHECK-LABEL: @test2(
23; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
24; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
25; CHECK-NEXT:    ret i32 [[Z]]
26;
27  %or = or i32 %x, %y
28  %not = xor i32 %or, -1
29  %z = or i32 %y, %not
30  ret i32 %z
31}
32
33; X | ~(X ^ Y) --> X | ~Y
34
35define i32 @test3(i32 %x, i32 %y) {
36; CHECK-LABEL: @test3(
37; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
38; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
39; CHECK-NEXT:    ret i32 [[Z]]
40;
41  %xor = xor i32 %x, %y
42  %not = xor i32 %xor, -1
43  %z = or i32 %x, %not
44  ret i32 %z
45}
46
47; Commute (rename) the 'xor' operands:
48; Y | ~(X ^ Y) --> ~X | Y
49
50define i32 @test4(i32 %x, i32 %y) {
51; CHECK-LABEL: @test4(
52; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
53; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
54; CHECK-NEXT:    ret i32 [[Z]]
55;
56  %xor = xor i32 %x, %y
57  %not = xor i32 %xor, -1
58  %z = or i32 %y, %not
59  ret i32 %z
60}
61
62define i32 @test7(i32 %x, i32 %y) {
63; CHECK-LABEL: @test7(
64; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
65; CHECK-NEXT:    ret i32 [[Z]]
66;
67  %xor = xor i32 %x, %y
68  %z = or i32 %y, %xor
69  ret i32 %z
70}
71
72define i32 @test8(i32 %x, i32 %y) {
73; CHECK-LABEL: @test8(
74; CHECK-NEXT:    [[X_NOT:%.*]] = xor i32 [[X:%.*]], -1
75; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X_NOT]], [[Y:%.*]]
76; CHECK-NEXT:    ret i32 [[Z]]
77;
78  %not = xor i32 %y, -1
79  %xor = xor i32 %x, %not
80  %z = or i32 %y, %xor
81  ret i32 %z
82}
83
84define i32 @test9(i32 %x, i32 %y) {
85; CHECK-LABEL: @test9(
86; CHECK-NEXT:    [[Y_NOT:%.*]] = xor i32 [[Y:%.*]], -1
87; CHECK-NEXT:    [[Z:%.*]] = or i32 [[Y_NOT]], [[X:%.*]]
88; CHECK-NEXT:    ret i32 [[Z]]
89;
90  %not = xor i32 %x, -1
91  %xor = xor i32 %not, %y
92  %z = or i32 %x, %xor
93  ret i32 %z
94}
95
96define i32 @test10(i32 %A, i32 %B) {
97; CHECK-LABEL: @test10(
98; CHECK-NEXT:    ret i32 -1
99;
100  %xor1 = xor i32 %B, %A
101  %not = xor i32 %A, -1
102  %xor2 = xor i32 %not, %B
103  %or = or i32 %xor1, %xor2
104  ret i32 %or
105}
106
107define i32 @test10_commuted(i32 %A, i32 %B) {
108; CHECK-LABEL: @test10_commuted(
109; CHECK-NEXT:    ret i32 -1
110;
111  %xor1 = xor i32 %B, %A
112  %not = xor i32 %A, -1
113  %xor2 = xor i32 %not, %B
114  %or = or i32 %xor2, %xor1
115  ret i32 %or
116}
117
118; (x | y) & ((~x) ^ y) -> (x & y)
119define i32 @test11(i32 %x, i32 %y) {
120; CHECK-LABEL: @test11(
121; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
122; CHECK-NEXT:    ret i32 [[AND]]
123;
124  %or = or i32 %x, %y
125  %neg = xor i32 %x, -1
126  %xor = xor i32 %neg, %y
127  %and = and i32 %or, %xor
128  ret i32 %and
129}
130
131; ((~x) ^ y) & (x | y) -> (x & y)
132define i32 @test12(i32 %x, i32 %y) {
133; CHECK-LABEL: @test12(
134; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
135; CHECK-NEXT:    ret i32 [[AND]]
136;
137  %neg = xor i32 %x, -1
138  %xor = xor i32 %neg, %y
139  %or = or i32 %x, %y
140  %and = and i32 %xor, %or
141  ret i32 %and
142}
143
144define i32 @test12_commuted(i32 %x, i32 %y) {
145; CHECK-LABEL: @test12_commuted(
146; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
147; CHECK-NEXT:    ret i32 [[AND]]
148;
149  %neg = xor i32 %x, -1
150  %xor = xor i32 %neg, %y
151  %or = or i32 %y, %x
152  %and = and i32 %xor, %or
153  ret i32 %and
154}
155
156; ((x | y) ^ (x ^ y)) -> (x & y)
157define i32 @test13(i32 %x, i32 %y) {
158; CHECK-LABEL: @test13(
159; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
160; CHECK-NEXT:    ret i32 [[TMP1]]
161;
162  %1 = xor i32 %y, %x
163  %2 = or i32 %y, %x
164  %3 = xor i32 %2, %1
165  ret i32 %3
166}
167
168; ((x | ~y) ^ (~x | y)) -> x ^ y
169define i32 @test14(i32 %x, i32 %y) {
170; CHECK-LABEL: @test14(
171; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
172; CHECK-NEXT:    ret i32 [[XOR]]
173;
174  %noty = xor i32 %y, -1
175  %notx = xor i32 %x, -1
176  %or1 = or i32 %x, %noty
177  %or2 = or i32 %notx, %y
178  %xor = xor i32 %or1, %or2
179  ret i32 %xor
180}
181
182define i32 @test14_commuted(i32 %x, i32 %y) {
183; CHECK-LABEL: @test14_commuted(
184; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
185; CHECK-NEXT:    ret i32 [[XOR]]
186;
187  %noty = xor i32 %y, -1
188  %notx = xor i32 %x, -1
189  %or1 = or i32 %noty, %x
190  %or2 = or i32 %notx, %y
191  %xor = xor i32 %or1, %or2
192  ret i32 %xor
193}
194
195; ((x & ~y) ^ (~x & y)) -> x ^ y
196define i32 @test15(i32 %x, i32 %y) {
197; CHECK-LABEL: @test15(
198; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
199; CHECK-NEXT:    ret i32 [[XOR]]
200;
201  %noty = xor i32 %y, -1
202  %notx = xor i32 %x, -1
203  %and1 = and i32 %x, %noty
204  %and2 = and i32 %notx, %y
205  %xor = xor i32 %and1, %and2
206  ret i32 %xor
207}
208
209define i32 @test15_commuted(i32 %x, i32 %y) {
210; CHECK-LABEL: @test15_commuted(
211; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
212; CHECK-NEXT:    ret i32 [[XOR]]
213;
214  %noty = xor i32 %y, -1
215  %notx = xor i32 %x, -1
216  %and1 = and i32 %noty, %x
217  %and2 = and i32 %notx, %y
218  %xor = xor i32 %and1, %and2
219  ret i32 %xor
220}
221
222define i32 @test16(i32 %a, i32 %b) {
223; CHECK-LABEL: @test16(
224; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 1
225; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], [[B:%.*]]
226; CHECK-NEXT:    ret i32 [[XOR]]
227;
228  %or = xor i32 %a, %b
229  %and1 = and i32 %or, 1
230  %and2 = and i32 %b, -2
231  %xor = or i32 %and1, %and2
232  ret i32 %xor
233}
234
235define i8 @not_or(i8 %x) {
236; CHECK-LABEL: @not_or(
237; CHECK-NEXT:    [[NOTX:%.*]] = xor i8 [[X:%.*]], -1
238; CHECK-NEXT:    [[OR:%.*]] = or i8 [[NOTX]], 7
239; CHECK-NEXT:    ret i8 [[OR]]
240;
241  %notx = xor i8 %x, -1
242  %or = or i8 %notx, 7
243  ret i8 %or
244}
245
246define i8 @not_or_xor(i8 %x) {
247; CHECK-LABEL: @not_or_xor(
248; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], -8
249; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[TMP1]], -13
250; CHECK-NEXT:    ret i8 [[XOR]]
251;
252  %notx = xor i8 %x, -1
253  %or = or i8 %notx, 7
254  %xor = xor i8 %or, 12
255  ret i8 %xor
256}
257
258define i8 @xor_or(i8 %x) {
259; CHECK-LABEL: @xor_or(
260; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 7
261; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 32
262; CHECK-NEXT:    ret i8 [[OR]]
263;
264  %xor = xor i8 %x, 32
265  %or = or i8 %xor, 7
266  ret i8 %or
267}
268
269define i8 @xor_or2(i8 %x) {
270; CHECK-LABEL: @xor_or2(
271; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 7
272; CHECK-NEXT:    [[OR:%.*]] = xor i8 [[TMP1]], 32
273; CHECK-NEXT:    ret i8 [[OR]]
274;
275  %xor = xor i8 %x, 33
276  %or = or i8 %xor, 7
277  ret i8 %or
278}
279
280define i8 @xor_or_xor(i8 %x) {
281; CHECK-LABEL: @xor_or_xor(
282; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 7
283; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[TMP1]], 44
284; CHECK-NEXT:    ret i8 [[XOR2]]
285;
286  %xor1 = xor i8 %x, 33
287  %or = or i8 %xor1, 7
288  %xor2 = xor i8 %or, 12
289  ret i8 %xor2
290}
291
292define i8 @or_xor_or(i8 %x) {
293; CHECK-LABEL: @or_xor_or(
294; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], 39
295; CHECK-NEXT:    [[OR2:%.*]] = xor i8 [[TMP1]], 8
296; CHECK-NEXT:    ret i8 [[OR2]]
297;
298  %or1 = or i8 %x, 33
299  %xor = xor i8 %or1, 12
300  %or2 = or i8 %xor, 7
301  ret i8 %or2
302}
303
304define i8 @test17(i8 %A, i8 %B) {
305; CHECK-LABEL: @test17(
306; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
307; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[A]], 33
308; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[NOT]], [[B]]
309; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR1]], 33
310; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
311; CHECK-NEXT:    ret i8 [[RES]]
312;
313  %xor1 = xor i8 %B, %A
314  %not = xor i8 %A, 33
315  %xor2 = xor i8 %not, %B
316  %or = or i8 %xor1, %xor2
317  %res = mul i8 %or, %xor2 ; to increase the use count for the xor
318  ret i8 %res
319}
320
321define i8 @test18(i8 %A, i8 %B) {
322; CHECK-LABEL: @test18(
323; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]
324; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[A]], 33
325; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[NOT]], [[B]]
326; CHECK-NEXT:    [[OR:%.*]] = or i8 [[XOR1]], 33
327; CHECK-NEXT:    [[RES:%.*]] = mul i8 [[OR]], [[XOR2]]
328; CHECK-NEXT:    ret i8 [[RES]]
329;
330  %xor1 = xor i8 %B, %A
331  %not = xor i8 %A, 33
332  %xor2 = xor i8 %not, %B
333  %or = or i8 %xor2, %xor1
334  %res = mul i8 %or, %xor2 ; to increase the use count for the xor
335  ret i8 %res
336}
337
338; ((x | y) ^ (~x | ~y)) -> ~(x ^ y)
339define i32 @test19(i32 %x, i32 %y) {
340; CHECK-LABEL: @test19(
341; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
342; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
343; CHECK-NEXT:    ret i32 [[XOR]]
344;
345  %noty = xor i32 %y, -1
346  %notx = xor i32 %x, -1
347  %or1 = or i32 %x, %y
348  %or2 = or i32 %notx, %noty
349  %xor = xor i32 %or1, %or2
350  ret i32 %xor
351}
352
353; ((x | y) ^ (~y | ~x)) -> ~(x ^ y)
354define i32 @test20(i32 %x, i32 %y) {
355; CHECK-LABEL: @test20(
356; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
357; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
358; CHECK-NEXT:    ret i32 [[XOR]]
359;
360  %noty = xor i32 %y, -1
361  %notx = xor i32 %x, -1
362  %or1 = or i32 %x, %y
363  %or2 = or i32 %noty, %notx
364  %xor = xor i32 %or1, %or2
365  ret i32 %xor
366}
367
368; ((~x | ~y) ^ (x | y)) -> ~(x ^ y)
369define i32 @test21(i32 %x, i32 %y) {
370; CHECK-LABEL: @test21(
371; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
372; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
373; CHECK-NEXT:    ret i32 [[XOR]]
374;
375  %noty = xor i32 %y, -1
376  %notx = xor i32 %x, -1
377  %or1 = or i32 %notx, %noty
378  %or2 = or i32 %x, %y
379  %xor = xor i32 %or1, %or2
380  ret i32 %xor
381}
382
383; ((~x | ~y) ^ (y | x)) -> ~(x ^ y)
384define i32 @test22(i32 %x, i32 %y) {
385; CHECK-LABEL: @test22(
386; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
387; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[TMP1]], -1
388; CHECK-NEXT:    ret i32 [[XOR]]
389;
390  %noty = xor i32 %y, -1
391  %notx = xor i32 %x, -1
392  %or1 = or i32 %notx, %noty
393  %or2 = or i32 %y, %x
394  %xor = xor i32 %or1, %or2
395  ret i32 %xor
396}
397
398; (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
399define i8 @test23(i8 %A) {
400; CHECK-LABEL: @test23(
401; CHECK-NEXT:    ret i8 -1
402;
403  %B = or i8 %A, -2
404  %C = xor i8 %B, 13
405  %D = or i8 %C, 1
406  %E = xor i8 %D, 12
407  ret i8 %E
408}
409
410define i8 @test23v(<2 x i8> %A) {
411; CHECK-LABEL: @test23v(
412; CHECK-NEXT:    ret i8 -1
413;
414  %B = or <2 x i8> %A, <i8 -2, i8 0>
415  %CV = xor <2 x i8> %B, <i8 13, i8 13>
416  %C = extractelement <2 x i8> %CV, i32 0
417  %D = or i8 %C, 1
418  %E = xor i8 %D, 12
419  ret i8 %E
420}
421