xref: /llvm-project/llvm/test/Transforms/AggressiveInstCombine/logic-combine.ll (revision 76df706bca14affdcf0dd91561c8e6805035608f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
3
4define i8 @leaf1_and_aa(i8 %a)  {
5; CHECK-LABEL: @leaf1_and_aa(
6; CHECK-NEXT:    [[AND_AA:%.*]] = and i8 [[A:%.*]], [[A]]
7; CHECK-NEXT:    ret i8 [[AND_AA]]
8;
9  %and.aa = and i8 %a, %a
10  ret i8 %and.aa
11}
12
13define i8 @leaf1_and_a_false(i8 %a)  {
14; CHECK-LABEL: @leaf1_and_a_false(
15; CHECK-NEXT:    [[AND_AA:%.*]] = and i8 [[A:%.*]], 0
16; CHECK-NEXT:    ret i8 [[AND_AA]]
17;
18  %and.aa = and i8 %a, 0
19  ret i8 %and.aa
20}
21
22define i8 @leaf1_xor_aa(i8 %a)  {
23; CHECK-LABEL: @leaf1_xor_aa(
24; CHECK-NEXT:    [[XOR_AA:%.*]] = xor i8 [[A:%.*]], [[A]]
25; CHECK-NEXT:    ret i8 [[XOR_AA]]
26;
27  %xor.aa = xor i8 %a, %a
28  ret i8 %xor.aa
29}
30
31define i8 @leaf1_and_not(i8 %a)  {
32; CHECK-LABEL: @leaf1_and_not(
33; CHECK-NEXT:    [[NOT_A:%.*]] = xor i8 [[A:%.*]], -1
34; CHECK-NEXT:    [[AND:%.*]] = and i8 [[A]], [[NOT_A]]
35; CHECK-NEXT:    ret i8 [[AND]]
36;
37  %not.a = xor i8 %a, -1
38  %and = and i8 %a, %not.a
39  ret i8 %and
40}
41
42define i8 @leaf1_or_not(i8 %a)  {
43; CHECK-LABEL: @leaf1_or_not(
44; CHECK-NEXT:    [[NOT_A:%.*]] = xor i8 [[A:%.*]], -1
45; CHECK-NEXT:    [[OR:%.*]] = or i8 [[A]], [[NOT_A]]
46; CHECK-NEXT:    ret i8 [[OR]]
47;
48  %not.a = xor i8 %a, -1
49  %or = or i8 %a, %not.a
50  ret i8 %or
51}
52
53define i8 @leaf2_xor(i8 %a, i8 %b)  {
54; CHECK-LABEL: @leaf2_xor(
55; CHECK-NEXT:    [[AB:%.*]] = xor i8 [[A:%.*]], [[B:%.*]]
56; CHECK-NEXT:    [[XOR_AB_A:%.*]] = xor i8 [[AB]], [[A]]
57; CHECK-NEXT:    ret i8 [[XOR_AB_A]]
58;
59  %ab = xor i8 %a, %b
60  %xor.ab.a = xor i8 %ab, %a
61  ret i8 %xor.ab.a
62}
63
64define i8 @leaf2_xor_ret_const_false(i8 %a, i8 %b)  {
65; CHECK-LABEL: @leaf2_xor_ret_const_false(
66; CHECK-NEXT:    [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B:%.*]]
67; CHECK-NEXT:    [[XOR_AB_A:%.*]] = xor i8 [[XOR_AB]], [[A]]
68; CHECK-NEXT:    [[XOR_AB_A_B:%.*]] = xor i8 [[XOR_AB_A]], [[B]]
69; CHECK-NEXT:    ret i8 [[XOR_AB_A_B]]
70;
71  %xor.ab = xor i8 %a, %b
72  %xor.ab.a = xor i8 %xor.ab, %a
73  %xor.ab.a.b = xor i8 %xor.ab.a, %b
74  ret i8 %xor.ab.a.b
75}
76
77define i8 @leaf2_or_ret_leaf(i8 %a, i8 %b)  {
78; CHECK-LABEL: @leaf2_or_ret_leaf(
79; CHECK-NEXT:    [[OR_AB:%.*]] = or i8 [[A:%.*]], [[B:%.*]]
80; CHECK-NEXT:    [[AND_AB:%.*]] = and i8 [[A]], [[B]]
81; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[OR_AB]], [[AND_AB]]
82; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[XOR1]], [[A]]
83; CHECK-NEXT:    ret i8 [[XOR2]]
84;
85  %or.ab = or i8 %a, %b
86  %and.ab = and i8 %a, %b
87  %xor1 = xor i8 %or.ab, %and.ab
88  %xor2 = xor i8 %xor1, %a
89  ret i8 %xor2
90}
91
92define i8 @leaf2_or_ret_const_false(i8 %a, i8 %b)  {
93; CHECK-LABEL: @leaf2_or_ret_const_false(
94; CHECK-NEXT:    [[OR_AB:%.*]] = or i8 [[A:%.*]], [[B:%.*]]
95; CHECK-NEXT:    [[AND_AB:%.*]] = and i8 [[A]], [[B]]
96; CHECK-NEXT:    [[XOR1:%.*]] = xor i8 [[OR_AB]], [[AND_AB]]
97; CHECK-NEXT:    [[XOR2:%.*]] = xor i8 [[XOR1]], [[A]]
98; CHECK-NEXT:    [[XOR3:%.*]] = xor i8 [[XOR1]], [[B]]
99; CHECK-NEXT:    ret i8 [[XOR3]]
100;
101  %or.ab = or i8 %a, %b
102  %and.ab = and i8 %a, %b
103  %xor1 = xor i8 %or.ab, %and.ab
104  %xor2 = xor i8 %xor1, %a
105  %xor3 = xor i8 %xor1, %b
106  ret i8 %xor3
107}
108
109define i1 @leaf2_type_is_i1(i1 %a, i1 %b) {
110; CHECK-LABEL: @leaf2_type_is_i1(
111; CHECK-NEXT:    [[XOR_AB:%.*]] = xor i1 [[A:%.*]], [[B:%.*]]
112; CHECK-NEXT:    [[NOT_A:%.*]] = xor i1 [[A]], true
113; CHECK-NEXT:    [[XOR2:%.*]] = xor i1 [[NOT_A]], [[B]]
114; CHECK-NEXT:    [[OR:%.*]] = or i1 [[XOR2]], [[XOR_AB]]
115; CHECK-NEXT:    ret i1 [[OR]]
116;
117  %xor.ab = xor i1 %a, %b
118  %not.a = xor i1 %a, true
119  %xor2 = xor i1 %not.a, %b
120  %or = or i1 %xor2, %xor.ab
121  ret i1 %or
122}
123
124define i8 @leaf3_complex_ret_const_false(i8 %a, i8 %b, i8 %c)  {
125; CHECK-LABEL: @leaf3_complex_ret_const_false(
126; CHECK-NEXT:    [[AB:%.*]] = or i8 [[A:%.*]], [[B:%.*]]
127; CHECK-NEXT:    [[ABC:%.*]] = or i8 [[AB]], [[C:%.*]]
128; CHECK-NEXT:    [[NOT_ABC:%.*]] = xor i8 [[ABC]], -1
129; CHECK-NEXT:    [[R:%.*]] = and i8 [[NOT_ABC]], [[A]]
130; CHECK-NEXT:    ret i8 [[R]]
131;
132  %ab = or i8 %a, %b
133  %abc = or i8 %ab, %c
134  %not.abc = xor i8 %abc, -1
135  %r = and i8 %not.abc, %a
136  ret i8 %r
137}
138
139define i8 @leaf3_complex_ret_leaf(i8 %a, i8 %b, i8 %c) {
140; CHECK-LABEL: @leaf3_complex_ret_leaf(
141; CHECK-NEXT:    [[AB:%.*]] = and i8 [[A:%.*]], [[B:%.*]]
142; CHECK-NEXT:    [[BC:%.*]] = and i8 [[B]], [[C:%.*]]
143; CHECK-NEXT:    [[XOR_AC:%.*]] = xor i8 [[A]], [[C]]
144; CHECK-NEXT:    [[OR:%.*]] = or i8 [[AB]], [[XOR_AC]]
145; CHECK-NEXT:    [[NOT_BC:%.*]] = xor i8 [[BC]], -1
146; CHECK-NEXT:    [[AND:%.*]] = and i8 [[NOT_BC]], [[A]]
147; CHECK-NEXT:    [[COND:%.*]] = xor i8 [[AND]], [[OR]]
148; CHECK-NEXT:    ret i8 [[COND]]
149;
150  %ab = and i8 %a, %b
151  %bc = and i8 %b, %c
152  %xor.ac = xor i8 %a, %c
153  %or = or i8 %ab, %xor.ac
154  %not.bc = xor i8 %bc, -1
155  %and = and i8 %not.bc, %a
156  %cond = xor i8 %and, %or
157  ret i8 %cond
158}
159
160define i8 @leaf4_ret_const_true(i8 %a, i8 %b, i8 %c, i8 %d)  {
161; CHECK-LABEL: @leaf4_ret_const_true(
162; CHECK-NEXT:    [[BD:%.*]] = and i8 [[B:%.*]], [[D:%.*]]
163; CHECK-NEXT:    [[NOT_BD:%.*]] = xor i8 [[BD]], -1
164; CHECK-NEXT:    [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B]]
165; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[XOR_AB]], [[C:%.*]]
166; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[OR1]], [[NOT_BD]]
167; CHECK-NEXT:    [[OR3:%.*]] = or i8 [[OR2]], [[A]]
168; CHECK-NEXT:    ret i8 [[OR3]]
169;
170  %bd = and i8 %b, %d
171  %not.bd = xor i8 %bd, -1
172  %xor.ab = xor i8 %a, %b
173  %or1 = or i8 %xor.ab, %c
174  %or2 = or i8 %or1, %not.bd
175  %or3 = or i8 %or2, %a
176  ret i8 %or3
177}
178
179define i8 @leaf4_ret_leaf(i8 %a, i8 %b, i8 %c, i8 %d)  {
180; CHECK-LABEL: @leaf4_ret_leaf(
181; CHECK-NEXT:    [[BD:%.*]] = and i8 [[B:%.*]], [[D:%.*]]
182; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[BD]], [[C:%.*]]
183; CHECK-NEXT:    [[NOT_BD:%.*]] = xor i8 [[XOR]], -1
184; CHECK-NEXT:    [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B]]
185; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[XOR_AB]], [[C]]
186; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[OR1]], [[NOT_BD]]
187; CHECK-NEXT:    [[OR3:%.*]] = or i8 [[OR2]], [[A]]
188; CHECK-NEXT:    [[AND:%.*]] = and i8 [[OR3]], [[B]]
189; CHECK-NEXT:    ret i8 [[AND]]
190;
191  %bd = and i8 %b, %d
192  %xor = xor i8 %bd, %c
193  %not.bd = xor i8 %xor, -1
194  %xor.ab = xor i8 %a, %b
195  %or1 = or i8 %xor.ab, %c
196  %or2 = or i8 %or1, %not.bd
197  %or3 = or i8 %or2, %a
198  %and = and i8 %or3, %b
199  ret i8 %and
200}
201
202define i8 @leaf4_ret_leaf2(i8 %a, i8 %b, i8 %c, i8 %d)  {
203; CHECK-LABEL: @leaf4_ret_leaf2(
204; CHECK-NEXT:    [[BD:%.*]] = and i8 [[B:%.*]], [[D:%.*]]
205; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[BD]], [[C:%.*]]
206; CHECK-NEXT:    [[NOT_BD:%.*]] = xor i8 [[XOR]], -1
207; CHECK-NEXT:    [[XOR_AB:%.*]] = xor i8 [[A:%.*]], [[B]]
208; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[XOR_AB]], [[C]]
209; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[OR1]], [[NOT_BD]]
210; CHECK-NEXT:    [[OR3:%.*]] = or i8 [[OR2]], [[A]]
211; CHECK-NEXT:    [[AND:%.*]] = and i8 [[OR3]], [[B]]
212; CHECK-NEXT:    ret i8 [[AND]]
213;
214  %bd = and i8 %b, %d
215  %xor = xor i8 %bd, %c
216  %not.bd = xor i8 %xor, -1
217  %xor.ab = xor i8 %a, %b
218  %or1 = or i8 %xor.ab, %c
219  %or2 = or i8 %or1, %not.bd
220  %or3 = or i8 %or2, %a
221  %and = and i8 %or3, %b
222  ret i8 %and
223}
224