xref: /llvm-project/llvm/test/Transforms/InstCombine/and-xor-or.ll (revision b8337dc4b20bfd7cde8cf37df6c12df4f751201b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use(i32)
5declare void @use_i8(i8)
6declare void @use_i1(i1)
7
8; a & (a ^ b) --> a & ~b
9
10define i32 @and_xor_common_op(i32 %pa, i32 %pb) {
11; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op
12; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
13; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA]]
14; CHECK-NEXT:    [[B:%.*]] = udiv i32 43, [[PB]]
15; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
16; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
17; CHECK-NEXT:    ret i32 [[R]]
18;
19  %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
20  %b = udiv i32 43, %pb ; thwart complexity-based canonicalization
21  %xor = xor i32 %a, %b
22  %r = and i32 %a, %xor
23  ret i32 %r
24}
25
26; a & (b ^ a) --> a & ~b
27
28define i32 @and_xor_common_op_commute1(i32 %pa, i32 %pb) {
29; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute1
30; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
31; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA]]
32; CHECK-NEXT:    [[B:%.*]] = udiv i32 43, [[PB]]
33; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
34; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
35; CHECK-NEXT:    ret i32 [[R]]
36;
37  %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
38  %b = udiv i32 43, %pb ; thwart complexity-based canonicalization
39  %xor = xor i32 %b, %a
40  %r = and i32 %a, %xor
41  ret i32 %r
42}
43
44; (b ^ a) & a --> a & ~b
45
46define i32 @and_xor_common_op_commute2(i32 %pa, i32 %pb) {
47; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute2
48; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
49; CHECK-NEXT:    [[A:%.*]] = udiv i32 42, [[PA]]
50; CHECK-NEXT:    [[B:%.*]] = udiv i32 43, [[PB]]
51; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
52; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], [[TMP1]]
53; CHECK-NEXT:    ret i32 [[R]]
54;
55  %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
56  %b = udiv i32 43, %pb ; thwart complexity-based canonicalization
57  %xor = xor i32 %b, %a
58  %r = and i32 %xor, %a
59  ret i32 %r
60}
61
62; (a ^ b) & a --> a & ~b
63
64define <2 x i32> @and_xor_common_op_commute3(<2 x i32> %pa, <2 x i32> %pb) {
65; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute3
66; CHECK-SAME: (<2 x i32> [[PA:%.*]], <2 x i32> [[PB:%.*]]) {
67; CHECK-NEXT:    [[A:%.*]] = udiv <2 x i32> <i32 42, i32 43>, [[PA]]
68; CHECK-NEXT:    [[B:%.*]] = udiv <2 x i32> <i32 43, i32 42>, [[PB]]
69; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[B]], splat (i32 -1)
70; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[A]], [[TMP1]]
71; CHECK-NEXT:    ret <2 x i32> [[R]]
72;
73  %a = udiv <2 x i32> <i32 42, i32 43>, %pa ; thwart complexity-based canonicalization
74  %b = udiv <2 x i32> <i32 43, i32 42>, %pb ; thwart complexity-based canonicalization
75  %xor = xor <2 x i32> %a, %b
76  %r = and <2 x i32> %xor, %a
77  ret <2 x i32> %r
78}
79
80; It's ok to match a common constant.
81; The xor should be a 'not' op (-1 constant).
82
83define <4 x i32> @and_xor_common_op_constant(<4 x i32> %A) {
84; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_constant
85; CHECK-SAME: (<4 x i32> [[A:%.*]]) {
86; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i32> [[A]], splat (i32 -1)
87; CHECK-NEXT:    [[TMP2:%.*]] = and <4 x i32> [[TMP1]], <i32 1, i32 2, i32 3, i32 4>
88; CHECK-NEXT:    ret <4 x i32> [[TMP2]]
89;
90  %1 = xor <4 x i32> %A, <i32 1, i32 2, i32 3, i32 4>
91  %2 = and <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %1
92  ret <4 x i32> %2
93}
94
95; a & (a ^ ~b) --> a & b
96
97define i32 @and_xor_not_common_op(i32 %a, i32 %b) {
98; CHECK-LABEL: define {{[^@]+}}@and_xor_not_common_op
99; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
100; CHECK-NEXT:    [[T4:%.*]] = and i32 [[A]], [[B]]
101; CHECK-NEXT:    ret i32 [[T4]]
102;
103  %b2 = xor i32 %b, -1
104  %t2 = xor i32 %a, %b2
105  %t4 = and i32 %t2, %a
106  ret i32 %t4
107}
108
109; a & (a ^ ~b) --> a & b
110
111define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, ptr %dst) {
112; CHECK-LABEL: define {{[^@]+}}@and_xor_not_common_op_extrause
113; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], ptr [[DST:%.*]]) {
114; CHECK-NEXT:    [[B2:%.*]] = xor i32 [[B]], -1
115; CHECK-NEXT:    store i32 [[B2]], ptr [[DST]], align 4
116; CHECK-NEXT:    [[T4:%.*]] = and i32 [[B]], [[A]]
117; CHECK-NEXT:    ret i32 [[T4]]
118;
119  %b2 = xor i32 %b, -1
120  store i32 %b2, ptr %dst
121  %t2 = xor i32 %a, %b2
122  %t4 = and i32 %t2, %a
123  ret i32 %t4
124}
125
126; a & ~(a ^ b) --> a & b
127
128define i32 @and_not_xor_common_op(i32 %a, i32 %b) {
129; CHECK-LABEL: define {{[^@]+}}@and_not_xor_common_op
130; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
131; CHECK-NEXT:    [[T4:%.*]] = and i32 [[A]], [[B]]
132; CHECK-NEXT:    ret i32 [[T4]]
133;
134  %b2 = xor i32 %b, %a
135  %t2 = xor i32 %b2, -1
136  %t4 = and i32 %t2, %a
137  ret i32 %t4
138}
139
140declare i32 @gen32()
141define i32 @and_not_xor_common_op_commutative(i32 %b) {
142; CHECK-LABEL: define {{[^@]+}}@and_not_xor_common_op_commutative
143; CHECK-SAME: (i32 [[B:%.*]]) {
144; CHECK-NEXT:    [[A:%.*]] = call i32 @gen32()
145; CHECK-NEXT:    [[T4:%.*]] = and i32 [[A]], [[B]]
146; CHECK-NEXT:    ret i32 [[T4]]
147;
148  %a = call i32 @gen32()
149  %b2 = xor i32 %a, %b ; swapped order
150  %t2 = xor i32 %b2, -1
151  %t4 = and i32 %a, %t2 ; swapped order
152  ret i32 %t4
153}
154
155; rdar://10770603
156; (x & y) | (x ^ y) -> x | y
157
158define i64 @or(i64 %x, i64 %y) {
159; CHECK-LABEL: define {{[^@]+}}@or
160; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
161; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Y]], [[X]]
162; CHECK-NEXT:    ret i64 [[TMP1]]
163;
164  %1 = and i64 %y, %x
165  %2 = xor i64 %y, %x
166  %3 = add i64 %1, %2
167  ret i64 %3
168}
169
170; (x & y) + (x ^ y) -> x | y
171
172define i64 @or2(i64 %x, i64 %y) {
173; CHECK-LABEL: define {{[^@]+}}@or2
174; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
175; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Y]], [[X]]
176; CHECK-NEXT:    ret i64 [[TMP1]]
177;
178  %1 = and i64 %y, %x
179  %2 = xor i64 %y, %x
180  %3 = or i64 %1, %2
181  ret i64 %3
182}
183
184; ((x & y) ^ z) | y -> (z | y)
185
186define i64 @and_xor_or1(i64 %px, i64 %py, i64 %pz) {
187; CHECK-LABEL: define {{[^@]+}}@and_xor_or1
188; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
189; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
190; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
191; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Z]], [[Y]]
192; CHECK-NEXT:    ret i64 [[TMP1]]
193;
194  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
195  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
196  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
197  %1 = and i64 %x, %y
198  %2 = xor i64 %1, %z
199  %3 = or i64 %2, %y
200  ret i64 %3
201}
202
203; ((y & x) ^ z) | y -> (z | y)
204
205define i64 @and_xor_or2(i64 %px, i64 %py, i64 %pz) {
206; CHECK-LABEL: define {{[^@]+}}@and_xor_or2
207; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
208; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
209; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
210; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Z]], [[Y]]
211; CHECK-NEXT:    ret i64 [[TMP1]]
212;
213  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
214  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
215  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
216  %1 = and i64 %y, %x
217  %2 = xor i64 %1, %z
218  %3 = or i64 %2, %y
219  ret i64 %3
220}
221
222; (z ^ (x & y)) | y -> (z | y)
223
224define i64 @and_xor_or3(i64 %px, i64 %py, i64 %pz) {
225; CHECK-LABEL: define {{[^@]+}}@and_xor_or3
226; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
227; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
228; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
229; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Z]], [[Y]]
230; CHECK-NEXT:    ret i64 [[TMP1]]
231;
232  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
233  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
234  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
235  %1 = and i64 %x, %y
236  %2 = xor i64 %z, %1
237  %3 = or i64 %2, %y
238  ret i64 %3
239}
240
241; (z ^ (y & x)) | y -> (z | y)
242
243define i64 @and_xor_or4(i64 %px, i64 %py, i64 %pz) {
244; CHECK-LABEL: define {{[^@]+}}@and_xor_or4
245; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
246; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
247; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
248; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Z]], [[Y]]
249; CHECK-NEXT:    ret i64 [[TMP1]]
250;
251  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
252  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
253  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
254  %1 = and i64 %y, %x
255  %2 = xor i64 %z, %1
256  %3 = or i64 %2, %y
257  ret i64 %3
258}
259
260; y | ((x & y) ^ z) -> (y | z)
261
262define i64 @and_xor_or5(i64 %px, i64 %py, i64 %pz) {
263; CHECK-LABEL: define {{[^@]+}}@and_xor_or5
264; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
265; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
266; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
267; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Y]], [[Z]]
268; CHECK-NEXT:    ret i64 [[TMP1]]
269;
270  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
271  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
272  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
273  %1 = and i64 %x, %y
274  %2 = xor i64 %1, %z
275  %3 = or i64 %y, %2
276  ret i64 %3
277}
278
279; y | ((y & x) ^ z) -> (y | z)
280
281define i64 @and_xor_or6(i64 %px, i64 %py, i64 %pz) {
282; CHECK-LABEL: define {{[^@]+}}@and_xor_or6
283; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
284; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
285; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
286; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Y]], [[Z]]
287; CHECK-NEXT:    ret i64 [[TMP1]]
288;
289  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
290  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
291  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
292  %1 = and i64 %y, %x
293  %2 = xor i64 %1, %z
294  %3 = or i64 %y, %2
295  ret i64 %3
296}
297
298; y | (z ^ (x & y)) -> (y | z)
299
300define i64 @and_xor_or7(i64 %px, i64 %py, i64 %pz) {
301; CHECK-LABEL: define {{[^@]+}}@and_xor_or7
302; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
303; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
304; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
305; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Y]], [[Z]]
306; CHECK-NEXT:    ret i64 [[TMP1]]
307;
308  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
309  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
310  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
311  %1 = and i64 %x, %y
312  %2 = xor i64 %z, %1
313  %3 = or i64 %y, %2
314  ret i64 %3
315}
316
317; y | (z ^ (y & x)) -> (y | z)
318
319define i64 @and_xor_or8(i64 %px, i64 %py, i64 %pz) {
320; CHECK-LABEL: define {{[^@]+}}@and_xor_or8
321; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {
322; CHECK-NEXT:    [[Y:%.*]] = udiv i64 42, [[PY]]
323; CHECK-NEXT:    [[Z:%.*]] = udiv i64 42, [[PZ]]
324; CHECK-NEXT:    [[TMP1:%.*]] = or i64 [[Y]], [[Z]]
325; CHECK-NEXT:    ret i64 [[TMP1]]
326;
327  %x = udiv i64 42, %px ; thwart complexity-based canonicalization
328  %y = udiv i64 42, %py ; thwart complexity-based canonicalization
329  %z = udiv i64 42, %pz ; thwart complexity-based canonicalization
330  %1 = and i64 %y, %x
331  %2 = xor i64 %z, %1
332  %3 = or i64 %y, %2
333  ret i64 %3
334}
335
336; w | (z ^ (y & x))
337
338define i64 @and_xor_or_negative(i64 %x, i64 %y, i64 %z, i64 %w) {
339; CHECK-LABEL: define {{[^@]+}}@and_xor_or_negative
340; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]], i64 [[W:%.*]]) {
341; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[Y]], [[X]]
342; CHECK-NEXT:    [[TMP2:%.*]] = xor i64 [[Z]], [[TMP1]]
343; CHECK-NEXT:    [[TMP3:%.*]] = or i64 [[W]], [[TMP2]]
344; CHECK-NEXT:    ret i64 [[TMP3]]
345;
346  %1 = and i64 %y, %x
347  %2 = xor i64 %z, %1
348  %3 = or i64 %w, %2
349  ret i64 %3
350}
351
352; PR37098 - https://bugs.llvm.org/show_bug.cgi?id=37098
353; Reassociate bitwise logic to eliminate a shift.
354; There are 4 commuted * 3 shift ops * 3 logic ops = 36 potential variations of this fold.
355; Mix the commutation options to provide coverage using less tests.
356
357define i8 @and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
358; CHECK-LABEL: define {{[^@]+}}@and_shl
359; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
360; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], [[Y]]
361; CHECK-NEXT:    [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]]
362; CHECK-NEXT:    [[R:%.*]] = and i8 [[TMP2]], [[Z]]
363; CHECK-NEXT:    ret i8 [[R]]
364;
365  %sx = shl i8 %x, %shamt
366  %sy = shl i8 %y, %shamt
367  %a = and i8 %sx, %z
368  %r = and i8 %sy, %a
369  ret i8 %r
370}
371
372define i8 @or_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
373; CHECK-LABEL: define {{[^@]+}}@or_shl
374; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
375; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X]], [[Y]]
376; CHECK-NEXT:    [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]]
377; CHECK-NEXT:    [[R:%.*]] = or i8 [[TMP2]], [[Z]]
378; CHECK-NEXT:    ret i8 [[R]]
379;
380  %sx = shl i8 %x, %shamt
381  %sy = shl i8 %y, %shamt
382  %a = or i8 %sx, %z
383  %r = or i8 %a, %sy
384  ret i8 %r
385}
386
387define i8 @xor_shl(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
388; CHECK-LABEL: define {{[^@]+}}@xor_shl
389; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
390; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
391; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], [[Y]]
392; CHECK-NEXT:    [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]]
393; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP2]], [[Z]]
394; CHECK-NEXT:    ret i8 [[R]]
395;
396  %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
397  %sx = shl i8 %x, %shamt
398  %sy = shl i8 %y, %shamt
399  %a = xor i8 %z, %sx
400  %r = xor i8 %a, %sy
401  ret i8 %r
402}
403
404define i8 @and_lshr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
405; CHECK-LABEL: define {{[^@]+}}@and_lshr
406; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
407; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
408; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], [[Y]]
409; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
410; CHECK-NEXT:    [[R:%.*]] = and i8 [[TMP2]], [[Z]]
411; CHECK-NEXT:    ret i8 [[R]]
412;
413  %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
414  %sx = lshr i8 %x, %shamt
415  %sy = lshr i8 %y, %shamt
416  %a = and i8 %z, %sx
417  %r = and i8 %sy, %a
418  ret i8 %r
419}
420
421define i8 @or_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {
422; CHECK-LABEL: define {{[^@]+}}@or_lshr
423; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
424; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X]], [[Y]]
425; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
426; CHECK-NEXT:    [[R:%.*]] = or i8 [[TMP2]], [[Z]]
427; CHECK-NEXT:    ret i8 [[R]]
428;
429  %sx = lshr i8 %x, %shamt
430  %sy = lshr i8 %y, %shamt
431  %a = or i8 %sx, %z
432  %r = or i8 %sy, %a
433  ret i8 %r
434}
435
436define i8 @or_lshr_commuted1(i8 %x, i8 %y, i8 %z, i8 %shamt) {
437; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted1
438; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
439; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X]], [[Y]]
440; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
441; CHECK-NEXT:    [[R:%.*]] = or i8 [[TMP2]], [[Z]]
442; CHECK-NEXT:    ret i8 [[R]]
443;
444  %sx = lshr i8 %x, %shamt
445  %sy = lshr i8 %y, %shamt
446  %a = or i8 %z, %sx
447  %r = or i8 %sy, %a
448  ret i8 %r
449}
450
451define i8 @or_lshr_commuted2(i8 %x, i8 %y, i8 %z, i8 %shamt) {
452; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted2
453; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
454; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X]], [[Y]]
455; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
456; CHECK-NEXT:    [[R:%.*]] = or i8 [[TMP2]], [[Z]]
457; CHECK-NEXT:    ret i8 [[R]]
458;
459  %sx = lshr i8 %x, %shamt
460  %sy = lshr i8 %y, %shamt
461  %a = or i8 %z, %sx
462  %r = or i8 %a, %sy
463  ret i8 %r
464}
465
466define i8 @or_lshr_commuted3(i8 %x, i8 %y, i8 %z, i8 %shamt) {
467; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted3
468; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
469; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X]], [[Y]]
470; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
471; CHECK-NEXT:    [[R:%.*]] = or i8 [[TMP2]], [[Z]]
472; CHECK-NEXT:    ret i8 [[R]]
473;
474  %sx = lshr i8 %x, %shamt
475  %sy = lshr i8 %y, %shamt
476  %a = or i8 %sx, %z
477  %r = or i8 %a, %sy
478  ret i8 %r
479}
480
481define i8 @xor_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {
482; CHECK-LABEL: define {{[^@]+}}@xor_lshr
483; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
484; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], [[Y]]
485; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
486; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP2]], [[Z]]
487; CHECK-NEXT:    ret i8 [[R]]
488;
489  %sx = lshr i8 %x, %shamt
490  %sy = lshr i8 %y, %shamt
491  %a = xor i8 %sx, %z
492  %r = xor i8 %a, %sy
493  ret i8 %r
494}
495
496define i8 @and_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
497; CHECK-LABEL: define {{[^@]+}}@and_ashr
498; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
499; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
500; CHECK-NEXT:    [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]]
501; CHECK-NEXT:    [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]]
502; CHECK-NEXT:    [[A:%.*]] = and i8 [[Z]], [[SX]]
503; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], [[SY]]
504; CHECK-NEXT:    ret i8 [[R]]
505;
506  %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
507  %sx = ashr i8 %x, %shamt
508  %sy = ashr i8 %y, %shamt
509  %a = and i8 %z, %sx
510  %r = and i8 %a, %sy
511  ret i8 %r
512}
513
514define i8 @or_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
515; CHECK-LABEL: define {{[^@]+}}@or_ashr
516; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
517; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
518; CHECK-NEXT:    [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]]
519; CHECK-NEXT:    [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]]
520; CHECK-NEXT:    [[A:%.*]] = or i8 [[Z]], [[SX]]
521; CHECK-NEXT:    [[R:%.*]] = or i8 [[SY]], [[A]]
522; CHECK-NEXT:    ret i8 [[R]]
523;
524  %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
525  %sx = ashr i8 %x, %shamt
526  %sy = ashr i8 %y, %shamt
527  %a = or i8 %z, %sx
528  %r = or i8 %sy, %a
529  ret i8 %r
530}
531
532define <2 x i8> @xor_ashr(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z, <2 x i8> %shamt) {
533; CHECK-LABEL: define {{[^@]+}}@xor_ashr
534; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]], <2 x i8> [[SHAMT:%.*]]) {
535; CHECK-NEXT:    [[SX:%.*]] = ashr <2 x i8> [[X]], [[SHAMT]]
536; CHECK-NEXT:    [[SY:%.*]] = ashr <2 x i8> [[Y]], [[SHAMT]]
537; CHECK-NEXT:    [[A:%.*]] = xor <2 x i8> [[SX]], [[Z]]
538; CHECK-NEXT:    [[R:%.*]] = xor <2 x i8> [[A]], [[SY]]
539; CHECK-NEXT:    ret <2 x i8> [[R]]
540;
541  %sx = ashr <2 x i8> %x, %shamt
542  %sy = ashr <2 x i8> %y, %shamt
543  %a = xor <2 x i8> %sx, %z
544  %r = xor <2 x i8> %a, %sy
545  ret <2 x i8> %r
546}
547
548; Negative test - different logic ops
549
550define i8 @or_and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
551; CHECK-LABEL: define {{[^@]+}}@or_and_shl
552; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
553; CHECK-NEXT:    [[SX:%.*]] = shl i8 [[X]], [[SHAMT]]
554; CHECK-NEXT:    [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]
555; CHECK-NEXT:    [[A:%.*]] = or i8 [[SX]], [[Z]]
556; CHECK-NEXT:    [[R:%.*]] = and i8 [[SY]], [[A]]
557; CHECK-NEXT:    ret i8 [[R]]
558;
559  %sx = shl i8 %x, %shamt
560  %sy = shl i8 %y, %shamt
561  %a = or i8 %sx, %z
562  %r = and i8 %sy, %a
563  ret i8 %r
564}
565
566; Negative test - different shift ops
567
568define i8 @or_lshr_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
569; CHECK-LABEL: define {{[^@]+}}@or_lshr_shl
570; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
571; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]
572; CHECK-NEXT:    [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]
573; CHECK-NEXT:    [[A:%.*]] = or i8 [[SX]], [[Z]]
574; CHECK-NEXT:    [[R:%.*]] = or i8 [[A]], [[SY]]
575; CHECK-NEXT:    ret i8 [[R]]
576;
577  %sx = lshr i8 %x, %shamt
578  %sy = shl i8 %y, %shamt
579  %a = or i8 %sx, %z
580  %r = or i8 %a, %sy
581  ret i8 %r
582}
583
584; Negative test - different shift amounts
585
586define i8 @or_lshr_shamt2(i8 %x, i8 %y, i8 %z, i8 %shamt) {
587; CHECK-LABEL: define {{[^@]+}}@or_lshr_shamt2
588; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
589; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], 5
590; CHECK-NEXT:    [[SY:%.*]] = lshr i8 [[Y]], [[SHAMT]]
591; CHECK-NEXT:    [[A:%.*]] = or i8 [[SX]], [[Z]]
592; CHECK-NEXT:    [[R:%.*]] = or i8 [[SY]], [[A]]
593; CHECK-NEXT:    ret i8 [[R]]
594;
595  %sx = lshr i8 %x, 5
596  %sy = lshr i8 %y, %shamt
597  %a = or i8 %sx, %z
598  %r = or i8 %sy, %a
599  ret i8 %r
600}
601
602; Negative test - multi-use
603
604define i8 @xor_lshr_multiuse(i8 %x, i8 %y, i8 %z, i8 %shamt) {
605; CHECK-LABEL: define {{[^@]+}}@xor_lshr_multiuse
606; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
607; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]
608; CHECK-NEXT:    [[A:%.*]] = xor i8 [[SX]], [[Z]]
609; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], [[Y]]
610; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
611; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP2]], [[Z]]
612; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[A]], [[R]]
613; CHECK-NEXT:    ret i8 [[R2]]
614;
615  %sx = lshr i8 %x, %shamt
616  %sy = lshr i8 %y, %shamt
617  %a = xor i8 %sx, %z
618  %r = xor i8 %a, %sy
619  %r2 = sdiv i8 %a, %r
620  ret i8 %r2
621}
622
623; Reassociate chains of extend(X) | (extend(Y) | Z).
624; Check that logical op is performed on a smaller type and then extended.
625
626define i64 @sext_or_chain(i64 %a, i16 %b, i16 %c) {
627; CHECK-LABEL: define {{[^@]+}}@sext_or_chain
628; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
629; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
630; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
631; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
632; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
633; CHECK-NEXT:    ret i64 [[OR2]]
634;
635  %conv = sext i16 %b to i64
636  %conv2 = sext i16 %c to i64
637  %or = or i64 %a, %conv
638  %or2 = or i64 %or, %conv2
639  ret i64 %or2
640}
641
642define i64 @zext_or_chain(i64 %a, i16 %b, i16 %c) {
643; CHECK-LABEL: define {{[^@]+}}@zext_or_chain
644; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
645; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[B]] to i64
646; CHECK-NEXT:    [[CONV2:%.*]] = zext i16 [[C]] to i64
647; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
648; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
649; CHECK-NEXT:    ret i64 [[OR2]]
650;
651  %conv = zext i16 %b to i64
652  %conv2 = zext i16 %c to i64
653  %or = or i64 %a, %conv
654  %or2 = or i64 %or, %conv2
655  ret i64 %or2
656}
657
658define i64 @sext_and_chain(i64 %a, i16 %b, i16 %c) {
659; CHECK-LABEL: define {{[^@]+}}@sext_and_chain
660; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
661; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
662; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
663; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A]], [[CONV]]
664; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]
665; CHECK-NEXT:    ret i64 [[AND2]]
666;
667  %conv = sext i16 %b to i64
668  %conv2 = sext i16 %c to i64
669  %and = and i64 %a, %conv
670  %and2 = and i64 %and, %conv2
671  ret i64 %and2
672}
673
674define i64 @zext_and_chain(i64 %a, i16 %b, i16 %c) {
675; CHECK-LABEL: define {{[^@]+}}@zext_and_chain
676; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
677; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[B]] to i64
678; CHECK-NEXT:    [[CONV2:%.*]] = zext i16 [[C]] to i64
679; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A]], [[CONV]]
680; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]
681; CHECK-NEXT:    ret i64 [[AND2]]
682;
683  %conv = zext i16 %b to i64
684  %conv2 = zext i16 %c to i64
685  %and = and i64 %a, %conv
686  %and2 = and i64 %and, %conv2
687  ret i64 %and2
688}
689
690define i64 @sext_xor_chain(i64 %a, i16 %b, i16 %c) {
691; CHECK-LABEL: define {{[^@]+}}@sext_xor_chain
692; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
693; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
694; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
695; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[A]], [[CONV]]
696; CHECK-NEXT:    [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]
697; CHECK-NEXT:    ret i64 [[XOR2]]
698;
699  %conv = sext i16 %b to i64
700  %conv2 = sext i16 %c to i64
701  %xor = xor i64 %a, %conv
702  %xor2 = xor i64 %xor, %conv2
703  ret i64 %xor2
704}
705
706define i64 @zext_xor_chain(i64 %a, i16 %b, i16 %c) {
707; CHECK-LABEL: define {{[^@]+}}@zext_xor_chain
708; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
709; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[B]] to i64
710; CHECK-NEXT:    [[CONV2:%.*]] = zext i16 [[C]] to i64
711; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[A]], [[CONV]]
712; CHECK-NEXT:    [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]
713; CHECK-NEXT:    ret i64 [[XOR2]]
714;
715  %conv = zext i16 %b to i64
716  %conv2 = zext i16 %c to i64
717  %xor = xor i64 %a, %conv
718  %xor2 = xor i64 %xor, %conv2
719  ret i64 %xor2
720}
721
722; Negative test with more uses.
723define i64 @sext_or_chain_two_uses1(i64 %a, i16 %b, i16 %c, i64 %d) {
724; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses1
725; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) {
726; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
727; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
728; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
729; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
730; CHECK-NEXT:    [[USE:%.*]] = udiv i64 [[OR]], [[D]]
731; CHECK-NEXT:    [[RETVAL:%.*]] = udiv i64 [[OR2]], [[USE]]
732; CHECK-NEXT:    ret i64 [[RETVAL]]
733;
734  %conv = sext i16 %b to i64
735  %conv2 = sext i16 %c to i64
736  ; %or has two uses
737  %or = or i64 %a, %conv
738  %or2 = or i64 %or, %conv2
739  %use = udiv i64 %or, %d
740  %retval = udiv i64 %or2, %use
741  ret i64 %retval
742}
743define i64 @sext_or_chain_two_uses2(i64 %a, i16 %b, i16 %c, i64 %d) {
744; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses2
745; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) {
746; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
747; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
748; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
749; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
750; CHECK-NEXT:    [[USE1:%.*]] = udiv i64 [[OR2]], [[D]]
751; CHECK-NEXT:    [[USE2:%.*]] = udiv i64 [[OR2]], [[USE1]]
752; CHECK-NEXT:    ret i64 [[USE2]]
753;
754  %conv = sext i16 %b to i64
755  %conv2 = sext i16 %c to i64
756  %or = or i64 %a, %conv
757  ; %or2 has two uses
758  %or2 = or i64 %or, %conv2
759  %use1 = udiv i64 %or2, %d
760  %use2 = udiv i64 %or2, %use1
761  ret i64 %use2
762}
763
764; (a & ~b) & ~c --> a & ~(b | c)
765
766define i32 @not_and_and_not(i32 %a0, i32 %b, i32 %c) {
767; CHECK-LABEL: define {{[^@]+}}@not_and_and_not
768; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
769; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
770; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B]], [[C]]
771; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
772; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
773; CHECK-NEXT:    ret i32 [[AND2]]
774;
775  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
776  %not1 = xor i32 %b, -1
777  %not2 = xor i32 %c, -1
778  %and1 = and i32 %a, %not1
779  %and2 = and i32 %and1, %not2
780  ret i32 %and2
781}
782
783define <4 x i64> @not_and_and_not_4i64(<4 x i64> %a0, <4 x i64> %b, <4 x i64> %c) {
784; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_4i64
785; CHECK-SAME: (<4 x i64> [[A0:%.*]], <4 x i64> [[B:%.*]], <4 x i64> [[C:%.*]]) {
786; CHECK-NEXT:    [[A:%.*]] = sdiv <4 x i64> splat (i64 42), [[A0]]
787; CHECK-NEXT:    [[TMP1:%.*]] = or <4 x i64> [[B]], [[C]]
788; CHECK-NEXT:    [[TMP2:%.*]] = xor <4 x i64> [[TMP1]], splat (i64 -1)
789; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i64> [[A]], [[TMP2]]
790; CHECK-NEXT:    ret <4 x i64> [[AND2]]
791;
792  %a = sdiv <4 x i64> <i64 42, i64 42, i64 42, i64 42>, %a0 ; thwart complexity-based canonicalization
793  %not1 = xor <4 x i64> %b, <i64 -1, i64 -1, i64 -1, i64 -1>
794  %not2 = xor <4 x i64> %c, <i64 -1, i64 -1, i64 -1, i64 -1>
795  %and1 = and <4 x i64> %a, %not1
796  %and2 = and <4 x i64> %and1, %not2
797  ret <4 x i64> %and2
798}
799
800; (~b & a) & ~c --> a & ~(b | c)
801
802define i32 @not_and_and_not_commute1(i32 %a, i32 %b, i32 %c) {
803; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute1
804; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
805; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B]], [[C]]
806; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
807; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
808; CHECK-NEXT:    ret i32 [[AND2]]
809;
810  %not1 = xor i32 %b, -1
811  %not2 = xor i32 %c, -1
812  %and1 = and i32 %not1, %a
813  %and2 = and i32 %and1, %not2
814  ret i32 %and2
815}
816
817; ~c & (a & ~b) --> a & ~(b | c)
818
819define i32 @not_and_and_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {
820; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute2_extra_not_use
821; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
822; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
823; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
824; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B]], [[C]]
825; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
826; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
827; CHECK-NEXT:    call void @use(i32 [[NOT2]])
828; CHECK-NEXT:    ret i32 [[AND2]]
829;
830  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
831  %not1 = xor i32 %b, -1
832  %not2 = xor i32 %c, -1
833  %and1 = and i32 %a, %not1
834  %and2 = and i32 %not2, %and1
835  call void @use(i32 %not2)
836  ret i32 %and2
837}
838
839define i32 @not_and_and_not_extra_and1_use(i32 %a0, i32 %b, i32 %c) {
840; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_extra_and1_use
841; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
842; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
843; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[B]], -1
844; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
845; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
846; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[NOT2]]
847; CHECK-NEXT:    call void @use(i32 [[AND1]])
848; CHECK-NEXT:    ret i32 [[AND2]]
849;
850  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
851  %not1 = xor i32 %b, -1
852  %not2 = xor i32 %c, -1
853  %and1 = and i32 %a, %not1
854  %and2 = and i32 %and1, %not2
855  call void @use(i32 %and1)
856  ret i32 %and2
857}
858
859; (a | ~b) | ~c --> a | ~(b & c)
860
861define i32 @not_or_or_not(i32 %a0, i32 %b, i32 %c) {
862; CHECK-LABEL: define {{[^@]+}}@not_or_or_not
863; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
864; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
865; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C]]
866; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
867; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
868; CHECK-NEXT:    ret i32 [[OR2]]
869;
870  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
871  %not1 = xor i32 %b, -1
872  %not2 = xor i32 %c, -1
873  %or1 = or i32 %a, %not1
874  %or2 = or i32 %or1, %not2
875  ret i32 %or2
876}
877
878define <2 x i6> @not_or_or_not_2i6(<2 x i6> %a0, <2 x i6> %b, <2 x i6> %c) {
879; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_2i6
880; CHECK-SAME: (<2 x i6> [[A0:%.*]], <2 x i6> [[B:%.*]], <2 x i6> [[C:%.*]]) {
881; CHECK-NEXT:    [[A:%.*]] = sdiv <2 x i6> splat (i6 3), [[A0]]
882; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i6> [[B]], [[C]]
883; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i6> [[TMP1]], splat (i6 -1)
884; CHECK-NEXT:    [[OR2:%.*]] = or <2 x i6> [[A]], [[TMP2]]
885; CHECK-NEXT:    ret <2 x i6> [[OR2]]
886;
887  %a = sdiv <2 x i6> <i6 3, i6 3>, %a0 ; thwart complexity-based canonicalization
888  %not1 = xor <2 x i6> %b, <i6 -1, i6 -1>
889  %not2 = xor <2 x i6> %c, <i6 -1, i6 poison>
890  %or1 = or <2 x i6> %a, %not1
891  %or2 = or <2 x i6> %or1, %not2
892  ret <2 x i6> %or2
893}
894
895; (~b | a) | ~c --> a | ~(b & c)
896
897define i32 @not_or_or_not_commute1(i32 %a, i32 %b, i32 %c) {
898; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute1
899; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
900; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C]]
901; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
902; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
903; CHECK-NEXT:    ret i32 [[OR2]]
904;
905  %not1 = xor i32 %b, -1
906  %not2 = xor i32 %c, -1
907  %or1 = or i32 %not1, %a
908  %or2 = or i32 %or1, %not2
909  ret i32 %or2
910}
911
912; ~c | (a | ~b) --> a | ~(b & c)
913
914define i32 @not_or_or_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {
915; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute2_extra_not_use
916; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
917; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
918; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
919; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C]]
920; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
921; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
922; CHECK-NEXT:    call void @use(i32 [[NOT2]])
923; CHECK-NEXT:    ret i32 [[OR2]]
924;
925  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
926  %not1 = xor i32 %b, -1
927  %not2 = xor i32 %c, -1
928  %or1 = or i32 %a, %not1
929  %or2 = or i32 %not2, %or1
930  call void @use(i32 %not2)
931  ret i32 %or2
932}
933
934define i32 @not_or_or_not_extra_or1_use(i32 %a0, i32 %b, i32 %c) {
935; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_extra_or1_use
936; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
937; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
938; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[B]], -1
939; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
940; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
941; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[NOT2]]
942; CHECK-NEXT:    call void @use(i32 [[OR1]])
943; CHECK-NEXT:    ret i32 [[OR2]]
944;
945  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
946  %not1 = xor i32 %b, -1
947  %not2 = xor i32 %c, -1
948  %or1 = or i32 %a, %not1
949  %or2 = or i32 %or1, %not2
950  call void @use(i32 %or1)
951  ret i32 %or2
952}
953
954; (c & ~(a | b)) | (b & ~(a | c)) --> ~a & (b ^ c)
955
956define i32 @or_not_and(i32 %a, i32 %b, i32 %c) {
957; CHECK-LABEL: define {{[^@]+}}@or_not_and
958; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
959; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
960; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
961; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
962; CHECK-NEXT:    ret i32 [[OR3]]
963;
964  %or1 = or i32 %a, %b
965  %not1 = xor i32 %or1, -1
966  %and1 = and i32 %not1, %c
967  %or2 = or i32 %a, %c
968  %not2 = xor i32 %or2, -1
969  %and2 = and i32 %not2, %b
970  %or3 = or i32 %and1, %and2
971  ret i32 %or3
972}
973
974define i32 @or_not_and_commute1(i32 %a, i32 %b0, i32 %c) {
975; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute1
976; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
977; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
978; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
979; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
980; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
981; CHECK-NEXT:    ret i32 [[OR3]]
982;
983  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
984  %or1 = or i32 %a, %b
985  %not1 = xor i32 %or1, -1
986  %and1 = and i32 %not1, %c
987  %or2 = or i32 %a, %c
988  %not2 = xor i32 %or2, -1
989  %and2 = and i32 %b, %not2
990  %or3 = or i32 %and1, %and2
991  ret i32 %or3
992}
993
994define i32 @or_not_and_commute2(i32 %a, i32 %b0, i32 %c) {
995; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute2
996; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
997; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
998; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
999; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1000; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1001; CHECK-NEXT:    ret i32 [[OR3]]
1002;
1003  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1004  %or1 = or i32 %a, %b
1005  %not1 = xor i32 %or1, -1
1006  %and1 = and i32 %not1, %c
1007  %or2 = or i32 %a, %c
1008  %not2 = xor i32 %or2, -1
1009  %and2 = and i32 %b, %not2
1010  %or3 = or i32 %and2, %and1
1011  ret i32 %or3
1012}
1013
1014define i32 @or_not_and_commute3(i32 %a, i32 %b, i32 %c) {
1015; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute3
1016; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1017; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1018; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1019; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1020; CHECK-NEXT:    ret i32 [[OR3]]
1021;
1022  %or1 = or i32 %b, %a
1023  %not1 = xor i32 %or1, -1
1024  %and1 = and i32 %not1, %c
1025  %or2 = or i32 %c, %a
1026  %not2 = xor i32 %or2, -1
1027  %and2 = and i32 %not2, %b
1028  %or3 = or i32 %and1, %and2
1029  ret i32 %or3
1030}
1031
1032define i32 @or_not_and_commute4(i32 %a, i32 %b, i32 %c0) {
1033; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute4
1034; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1035; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1036; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1037; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1038; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1039; CHECK-NEXT:    ret i32 [[OR3]]
1040;
1041  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1042  %or1 = or i32 %a, %b
1043  %not1 = xor i32 %or1, -1
1044  %and1 = and i32 %c, %not1
1045  %or2 = or i32 %a, %c
1046  %not2 = xor i32 %or2, -1
1047  %and2 = and i32 %not2, %b
1048  %or3 = or i32 %and1, %and2
1049  ret i32 %or3
1050}
1051
1052define i32 @or_not_and_commute5(i32 %a0, i32 %b, i32 %c0) {
1053; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute5
1054; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1055; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1056; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1057; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1058; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1059; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1060; CHECK-NEXT:    ret i32 [[OR3]]
1061;
1062  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1063  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1064  %or1 = or i32 %a, %b
1065  %not1 = xor i32 %or1, -1
1066  %and1 = and i32 %c, %not1
1067  %or2 = or i32 %a, %c
1068  %not2 = xor i32 %or2, -1
1069  %and2 = and i32 %not2, %b
1070  %or3 = or i32 %and1, %and2
1071  ret i32 %or3
1072}
1073
1074define i32 @or_not_and_commute6(i32 %a, i32 %b, i32 %c) {
1075; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute6
1076; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1077; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1078; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1079; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1080; CHECK-NEXT:    ret i32 [[OR3]]
1081;
1082  %or1 = or i32 %a, %b
1083  %not1 = xor i32 %or1, -1
1084  %and1 = and i32 %not1, %c
1085  %or2 = or i32 %c, %a
1086  %not2 = xor i32 %or2, -1
1087  %and2 = and i32 %not2, %b
1088  %or3 = or i32 %and1, %and2
1089  ret i32 %or3
1090}
1091
1092define i32 @or_not_and_commute7(i32 %a, i32 %b, i32 %c) {
1093; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute7
1094; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1095; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1096; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1097; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1098; CHECK-NEXT:    ret i32 [[OR3]]
1099;
1100  %or1 = or i32 %b, %a
1101  %not1 = xor i32 %or1, -1
1102  %and1 = and i32 %not1, %c
1103  %or2 = or i32 %a, %c
1104  %not2 = xor i32 %or2, -1
1105  %and2 = and i32 %not2, %b
1106  %or3 = or i32 %and1, %and2
1107  ret i32 %or3
1108}
1109
1110define i32 @or_not_and_commute8(i32 %a0, i32 %b0, i32 %c) {
1111; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute8
1112; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1113; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1114; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1115; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1116; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1117; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1118; CHECK-NEXT:    ret i32 [[OR3]]
1119;
1120  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1121  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1122  %or1 = or i32 %a, %b
1123  %not1 = xor i32 %or1, -1
1124  %and1 = and i32 %not1, %c
1125  %or2 = or i32 %c, %a
1126  %not2 = xor i32 %or2, -1
1127  %and2 = and i32 %b, %not2
1128  %or3 = or i32 %and1, %and2
1129  ret i32 %or3
1130}
1131
1132define i32 @or_not_and_commute9(i32 %a0, i32 %b0, i32 %c0) {
1133; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute9
1134; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) {
1135; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1136; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1137; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1138; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1139; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1140; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1141; CHECK-NEXT:    ret i32 [[OR3]]
1142;
1143  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1144  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1145  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1146  %or1 = or i32 %a, %b
1147  %not1 = xor i32 %or1, -1
1148  %and1 = and i32 %not1, %c
1149  %or2 = or i32 %a, %c
1150  %not2 = xor i32 %or2, -1
1151  %and2 = and i32 %b, %not2
1152  %or3 = or i32 %and1, %and2
1153  ret i32 %or3
1154}
1155
1156define i32 @or_not_and_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1157; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use1
1158; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1159; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1160; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1161; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1162; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1163; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1164; CHECK-NEXT:    call void @use(i32 [[NOT1]])
1165; CHECK-NEXT:    ret i32 [[OR3]]
1166;
1167  %or1 = or i32 %a, %b
1168  %not1 = xor i32 %or1, -1
1169  %and1 = and i32 %not1, %c
1170  %or2 = or i32 %a, %c
1171  %not2 = xor i32 %or2, -1
1172  %and2 = and i32 %not2, %b
1173  %or3 = or i32 %and1, %and2
1174  call void @use(i32 %not1)
1175  ret i32 %or3
1176}
1177
1178define i32 @or_not_and_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1179; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use2
1180; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1181; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1182; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1183; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1184; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1185; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1186; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[B]], [[NOT2]]
1187; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1188; CHECK-NEXT:    call void @use(i32 [[NOT2]])
1189; CHECK-NEXT:    ret i32 [[OR3]]
1190;
1191  %or1 = or i32 %a, %b
1192  %not1 = xor i32 %or1, -1
1193  %and1 = and i32 %not1, %c
1194  %or2 = or i32 %a, %c
1195  %not2 = xor i32 %or2, -1
1196  %and2 = and i32 %not2, %b
1197  %or3 = or i32 %and1, %and2
1198  call void @use(i32 %not2)
1199  ret i32 %or3
1200}
1201
1202define i32 @or_not_and_extra_and_use1(i32 %a, i32 %b, i32 %c) {
1203; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use1
1204; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1205; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1206; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1207; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1208; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1209; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1210; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1211; CHECK-NEXT:    call void @use(i32 [[AND1]])
1212; CHECK-NEXT:    ret i32 [[OR3]]
1213;
1214  %or1 = or i32 %a, %b
1215  %not1 = xor i32 %or1, -1
1216  %and1 = and i32 %not1, %c
1217  %or2 = or i32 %a, %c
1218  %not2 = xor i32 %or2, -1
1219  %and2 = and i32 %not2, %b
1220  %or3 = or i32 %and1, %and2
1221  call void @use(i32 %and1)
1222  ret i32 %or3
1223}
1224
1225define i32 @or_not_and_extra_and_use2(i32 %a, i32 %b, i32 %c) {
1226; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use2
1227; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1228; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1229; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1230; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1231; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1232; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1233; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[B]], [[NOT2]]
1234; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1235; CHECK-NEXT:    call void @use(i32 [[AND2]])
1236; CHECK-NEXT:    ret i32 [[OR3]]
1237;
1238  %or1 = or i32 %a, %b
1239  %not1 = xor i32 %or1, -1
1240  %and1 = and i32 %not1, %c
1241  %or2 = or i32 %a, %c
1242  %not2 = xor i32 %or2, -1
1243  %and2 = and i32 %not2, %b
1244  %or3 = or i32 %and1, %and2
1245  call void @use(i32 %and2)
1246  ret i32 %or3
1247}
1248
1249define i32 @or_not_and_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1250; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use1
1251; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1252; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1253; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1254; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1255; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1256; CHECK-NEXT:    call void @use(i32 [[OR1]])
1257; CHECK-NEXT:    ret i32 [[OR3]]
1258;
1259  %or1 = or i32 %a, %b
1260  %not1 = xor i32 %or1, -1
1261  %and1 = and i32 %not1, %c
1262  %or2 = or i32 %a, %c
1263  %not2 = xor i32 %or2, -1
1264  %and2 = and i32 %not2, %b
1265  %or3 = or i32 %and1, %and2
1266  call void @use(i32 %or1)
1267  ret i32 %or3
1268}
1269
1270define i32 @or_not_and_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1271; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use2
1272; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1273; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1274; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1275; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1276; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1277; CHECK-NEXT:    call void @use(i32 [[OR2]])
1278; CHECK-NEXT:    ret i32 [[OR3]]
1279;
1280  %or1 = or i32 %a, %b
1281  %not1 = xor i32 %or1, -1
1282  %and1 = and i32 %not1, %c
1283  %or2 = or i32 %a, %c
1284  %not2 = xor i32 %or2, -1
1285  %and2 = and i32 %not2, %b
1286  %or3 = or i32 %and1, %and2
1287  call void @use(i32 %or2)
1288  ret i32 %or3
1289}
1290
1291define i32 @or_not_and_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {
1292; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_c
1293; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1294; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1295; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1296; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1297; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[D]]
1298; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1299; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[B]], [[NOT2]]
1300; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1301; CHECK-NEXT:    ret i32 [[OR3]]
1302;
1303  %or1 = or i32 %a, %b
1304  %not1 = xor i32 %or1, -1
1305  %and1 = and i32 %not1, %c
1306  %or2 = or i32 %a, %d
1307  %not2 = xor i32 %or2, -1
1308  %and2 = and i32 %not2, %b
1309  %or3 = or i32 %and1, %and2
1310  ret i32 %or3
1311}
1312
1313define i32 @or_not_and_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1314; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_b
1315; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1316; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1317; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1318; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1319; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1320; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1321; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[D]], [[NOT2]]
1322; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1323; CHECK-NEXT:    ret i32 [[OR3]]
1324;
1325  %or1 = or i32 %a, %b
1326  %not1 = xor i32 %or1, -1
1327  %and1 = and i32 %not1, %c
1328  %or2 = or i32 %a, %c
1329  %not2 = xor i32 %or2, -1
1330  %and2 = and i32 %not2, %d
1331  %or3 = or i32 %and1, %and2
1332  ret i32 %or3
1333}
1334
1335; (c | ~(a & b)) & (b | ~(a & c)) --> ~(a & (b ^ c))
1336
1337define i32 @and_not_or(i32 %a, i32 %b, i32 %c) {
1338; CHECK-LABEL: define {{[^@]+}}@and_not_or
1339; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1340; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1341; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1342; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1343; CHECK-NEXT:    ret i32 [[AND3]]
1344;
1345  %and1 = and i32 %a, %b
1346  %not1 = xor i32 %and1, -1
1347  %or1 = or i32 %not1, %c
1348  %and2 = and i32 %a, %c
1349  %not2 = xor i32 %and2, -1
1350  %or2 = or i32 %not2, %b
1351  %and3 = and i32 %or1, %or2
1352  ret i32 %and3
1353}
1354
1355define i32 @and_not_or_commute1(i32 %a, i32 %b0, i32 %c) {
1356; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute1
1357; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1358; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1359; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1360; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1361; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1362; CHECK-NEXT:    ret i32 [[AND3]]
1363;
1364  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1365  %and1 = and i32 %a, %b
1366  %not1 = xor i32 %and1, -1
1367  %or1 = or i32 %not1, %c
1368  %and2 = and i32 %a, %c
1369  %not2 = xor i32 %and2, -1
1370  %or2 = or i32 %b, %not2
1371  %and3 = and i32 %or1, %or2
1372  ret i32 %and3
1373}
1374
1375define i32 @and_not_or_commute2(i32 %a, i32 %b0, i32 %c) {
1376; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute2
1377; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1378; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1379; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
1380; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1381; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1382; CHECK-NEXT:    ret i32 [[AND3]]
1383;
1384  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1385  %and1 = and i32 %a, %b
1386  %not1 = xor i32 %and1, -1
1387  %or1 = or i32 %not1, %c
1388  %and2 = and i32 %a, %c
1389  %not2 = xor i32 %and2, -1
1390  %or2 = or i32 %b, %not2
1391  %and3 = and i32 %or2, %or1
1392  ret i32 %and3
1393}
1394
1395define i32 @and_not_or_commute3(i32 %a, i32 %b, i32 %c) {
1396; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute3
1397; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1398; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1399; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1400; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1401; CHECK-NEXT:    ret i32 [[AND3]]
1402;
1403  %and1 = and i32 %b, %a
1404  %not1 = xor i32 %and1, -1
1405  %or1 = or i32 %not1, %c
1406  %and2 = and i32 %c, %a
1407  %not2 = xor i32 %and2, -1
1408  %or2 = or i32 %not2, %b
1409  %and3 = and i32 %or1, %or2
1410  ret i32 %and3
1411}
1412
1413define i32 @and_not_or_commute4(i32 %a, i32 %b, i32 %c0) {
1414; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute4
1415; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1416; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1417; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1418; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1419; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1420; CHECK-NEXT:    ret i32 [[AND3]]
1421;
1422  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1423  %and1 = and i32 %a, %b
1424  %not1 = xor i32 %and1, -1
1425  %or1 = or i32 %c, %not1
1426  %and2 = and i32 %a, %c
1427  %not2 = xor i32 %and2, -1
1428  %or2 = or i32 %not2, %b
1429  %and3 = and i32 %or1, %or2
1430  ret i32 %and3
1431}
1432
1433define i32 @and_not_or_commute5(i32 %a0, i32 %b, i32 %c0) {
1434; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute5
1435; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1436; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1437; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1438; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1439; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1440; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1441; CHECK-NEXT:    ret i32 [[AND3]]
1442;
1443  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1444  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1445  %and1 = and i32 %a, %b
1446  %not1 = xor i32 %and1, -1
1447  %or1 = or i32 %c, %not1
1448  %and2 = and i32 %a, %c
1449  %not2 = xor i32 %and2, -1
1450  %or2 = or i32 %not2, %b
1451  %and3 = and i32 %or1, %or2
1452  ret i32 %and3
1453}
1454
1455define i32 @and_not_or_commute6(i32 %a, i32 %b, i32 %c) {
1456; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute6
1457; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1458; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1459; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1460; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1461; CHECK-NEXT:    ret i32 [[AND3]]
1462;
1463  %and1 = and i32 %a, %b
1464  %not1 = xor i32 %and1, -1
1465  %or1 = or i32 %not1, %c
1466  %and2 = and i32 %c, %a
1467  %not2 = xor i32 %and2, -1
1468  %or2 = or i32 %not2, %b
1469  %and3 = and i32 %or1, %or2
1470  ret i32 %and3
1471}
1472
1473define i32 @and_not_or_commute7(i32 %a, i32 %b, i32 %c) {
1474; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute7
1475; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1476; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1477; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1478; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1479; CHECK-NEXT:    ret i32 [[AND3]]
1480;
1481  %and1 = and i32 %b, %a
1482  %not1 = xor i32 %and1, -1
1483  %or1 = or i32 %not1, %c
1484  %and2 = and i32 %a, %c
1485  %not2 = xor i32 %and2, -1
1486  %or2 = or i32 %not2, %b
1487  %and3 = and i32 %or1, %or2
1488  ret i32 %and3
1489}
1490
1491define i32 @and_not_or_commute8(i32 %a0, i32 %b0, i32 %c) {
1492; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute8
1493; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1494; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1495; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1496; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1497; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1498; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1499; CHECK-NEXT:    ret i32 [[AND3]]
1500;
1501  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1502  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1503  %and1 = and i32 %a, %b
1504  %not1 = xor i32 %and1, -1
1505  %or1 = or i32 %not1, %c
1506  %and2 = and i32 %c, %a
1507  %not2 = xor i32 %and2, -1
1508  %or2 = or i32 %b, %not2
1509  %and3 = and i32 %or1, %or2
1510  ret i32 %and3
1511}
1512
1513define i32 @and_not_or_commute9(i32 %a0, i32 %b0, i32 %c0) {
1514; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute9
1515; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) {
1516; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1517; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1518; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1519; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1520; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1521; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1522; CHECK-NEXT:    ret i32 [[AND3]]
1523;
1524  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1525  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1526  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1527  %and1 = and i32 %a, %b
1528  %not1 = xor i32 %and1, -1
1529  %or1 = or i32 %not1, %c
1530  %and2 = and i32 %a, %c
1531  %not2 = xor i32 %and2, -1
1532  %or2 = or i32 %b, %not2
1533  %and3 = and i32 %or1, %or2
1534  ret i32 %and3
1535}
1536
1537define i32 @and_not_or_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1538; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use1
1539; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1540; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1541; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1542; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1543; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1544; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1545; CHECK-NEXT:    call void @use(i32 [[NOT1]])
1546; CHECK-NEXT:    ret i32 [[AND3]]
1547;
1548  %and1 = and i32 %a, %b
1549  %not1 = xor i32 %and1, -1
1550  %or1 = or i32 %not1, %c
1551  %and2 = and i32 %a, %c
1552  %not2 = xor i32 %and2, -1
1553  %or2 = or i32 %not2, %b
1554  %and3 = and i32 %or1, %or2
1555  call void @use(i32 %not1)
1556  ret i32 %and3
1557}
1558
1559define i32 @and_not_or_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1560; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use2
1561; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1562; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1563; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1564; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1565; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1566; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1567; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[B]], [[NOT2]]
1568; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1569; CHECK-NEXT:    call void @use(i32 [[NOT2]])
1570; CHECK-NEXT:    ret i32 [[AND3]]
1571;
1572  %and1 = and i32 %a, %b
1573  %not1 = xor i32 %and1, -1
1574  %or1 = or i32 %not1, %c
1575  %and2 = and i32 %a, %c
1576  %not2 = xor i32 %and2, -1
1577  %or2 = or i32 %not2, %b
1578  %and3 = and i32 %or1, %or2
1579  call void @use(i32 %not2)
1580  ret i32 %and3
1581}
1582
1583define i32 @and_not_or_extra_and_use1(i32 %a, i32 %b, i32 %c) {
1584; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use1
1585; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1586; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1587; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1588; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1589; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1590; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1591; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1592; CHECK-NEXT:    call void @use(i32 [[OR1]])
1593; CHECK-NEXT:    ret i32 [[AND3]]
1594;
1595  %and1 = and i32 %a, %b
1596  %not1 = xor i32 %and1, -1
1597  %or1 = or i32 %not1, %c
1598  %and2 = and i32 %a, %c
1599  %not2 = xor i32 %and2, -1
1600  %or2 = or i32 %not2, %b
1601  %and3 = and i32 %or1, %or2
1602  call void @use(i32 %or1)
1603  ret i32 %and3
1604}
1605
1606define i32 @and_not_or_extra_and_use2(i32 %a, i32 %b, i32 %c) {
1607; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use2
1608; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1609; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1610; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1611; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1612; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1613; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1614; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[B]], [[NOT2]]
1615; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1616; CHECK-NEXT:    call void @use(i32 [[OR2]])
1617; CHECK-NEXT:    ret i32 [[AND3]]
1618;
1619  %and1 = and i32 %a, %b
1620  %not1 = xor i32 %and1, -1
1621  %or1 = or i32 %not1, %c
1622  %and2 = and i32 %a, %c
1623  %not2 = xor i32 %and2, -1
1624  %or2 = or i32 %not2, %b
1625  %and3 = and i32 %or1, %or2
1626  call void @use(i32 %or2)
1627  ret i32 %and3
1628}
1629
1630define i32 @and_not_or_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1631; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use1
1632; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1633; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1634; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1635; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1636; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1637; CHECK-NEXT:    call void @use(i32 [[AND1]])
1638; CHECK-NEXT:    ret i32 [[AND3]]
1639;
1640  %and1 = and i32 %a, %b
1641  %not1 = xor i32 %and1, -1
1642  %or1 = or i32 %not1, %c
1643  %and2 = and i32 %a, %c
1644  %not2 = xor i32 %and2, -1
1645  %or2 = or i32 %not2, %b
1646  %and3 = and i32 %or1, %or2
1647  call void @use(i32 %and1)
1648  ret i32 %and3
1649}
1650
1651define i32 @and_not_or_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1652; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use2
1653; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1654; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1655; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1656; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1657; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1658; CHECK-NEXT:    call void @use(i32 [[AND2]])
1659; CHECK-NEXT:    ret i32 [[AND3]]
1660;
1661  %and1 = and i32 %a, %b
1662  %not1 = xor i32 %and1, -1
1663  %or1 = or i32 %not1, %c
1664  %and2 = and i32 %a, %c
1665  %not2 = xor i32 %and2, -1
1666  %or2 = or i32 %not2, %b
1667  %and3 = and i32 %or1, %or2
1668  call void @use(i32 %and2)
1669  ret i32 %and3
1670}
1671
1672define i32 @and_not_or_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {
1673; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_c
1674; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1675; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1676; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1677; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1678; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[D]]
1679; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1680; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[B]], [[NOT2]]
1681; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1682; CHECK-NEXT:    ret i32 [[AND3]]
1683;
1684  %and1 = and i32 %a, %b
1685  %not1 = xor i32 %and1, -1
1686  %or1 = or i32 %not1, %c
1687  %and2 = and i32 %a, %d
1688  %not2 = xor i32 %and2, -1
1689  %or2 = or i32 %not2, %b
1690  %and3 = and i32 %or1, %or2
1691  ret i32 %and3
1692}
1693
1694define i32 @and_not_or_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1695; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_b
1696; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1697; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1698; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1699; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1700; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1701; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1702; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[D]], [[NOT2]]
1703; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1704; CHECK-NEXT:    ret i32 [[AND3]]
1705;
1706  %and1 = and i32 %a, %b
1707  %not1 = xor i32 %and1, -1
1708  %or1 = or i32 %not1, %c
1709  %and2 = and i32 %a, %c
1710  %not2 = xor i32 %and2, -1
1711  %or2 = or i32 %not2, %d
1712  %and3 = and i32 %or1, %or2
1713  ret i32 %and3
1714}
1715
1716; (b & ~(a | c)) | ~(a | b) --> ~((b & c) | a)
1717
1718define i32 @or_and_not_not(i32 %a, i32 %b, i32 %c) {
1719; CHECK-LABEL: define {{[^@]+}}@or_and_not_not
1720; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1721; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1722; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1723; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1724; CHECK-NEXT:    ret i32 [[OR3]]
1725;
1726  %or1 = or i32 %b, %a
1727  %not1 = xor i32 %or1, -1
1728  %or2 = or i32 %a, %c
1729  %not2 = xor i32 %or2, -1
1730  %and = and i32 %not2, %b
1731  %or3 = or i32 %and, %not1
1732  ret i32 %or3
1733}
1734
1735define i32 @or_and_not_not_commute1(i32 %a, i32 %b0, i32 %c) {
1736; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute1
1737; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1738; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1739; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1740; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1741; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1742; CHECK-NEXT:    ret i32 [[OR3]]
1743;
1744  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1745  %or1 = or i32 %b, %a
1746  %not1 = xor i32 %or1, -1
1747  %or2 = or i32 %a, %c
1748  %not2 = xor i32 %or2, -1
1749  %and = and i32 %b, %not2
1750  %or3 = or i32 %and, %not1
1751  ret i32 %or3
1752}
1753
1754define i32 @or_and_not_not_commute2(i32 %a, i32 %b, i32 %c) {
1755; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute2
1756; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1757; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1758; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1759; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1760; CHECK-NEXT:    ret i32 [[OR3]]
1761;
1762  %or1 = or i32 %b, %a
1763  %not1 = xor i32 %or1, -1
1764  %or2 = or i32 %a, %c
1765  %not2 = xor i32 %or2, -1
1766  %and = and i32 %not2, %b
1767  %or3 = or i32 %and, %not1
1768  ret i32 %or3
1769}
1770
1771define i32 @or_and_not_not_commute3(i32 %a, i32 %b, i32 %c) {
1772; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute3
1773; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1774; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1775; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1776; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1777; CHECK-NEXT:    ret i32 [[OR3]]
1778;
1779  %or1 = or i32 %b, %a
1780  %not1 = xor i32 %or1, -1
1781  %or2 = or i32 %c, %a
1782  %not2 = xor i32 %or2, -1
1783  %and = and i32 %not2, %b
1784  %or3 = or i32 %and, %not1
1785  ret i32 %or3
1786}
1787
1788define i32 @or_and_not_not_commute4(i32 %a, i32 %b, i32 %c) {
1789; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute4
1790; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1791; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1792; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1793; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1794; CHECK-NEXT:    ret i32 [[OR3]]
1795;
1796  %or1 = or i32 %a, %b
1797  %not1 = xor i32 %or1, -1
1798  %or2 = or i32 %a, %c
1799  %not2 = xor i32 %or2, -1
1800  %and = and i32 %not2, %b
1801  %or3 = or i32 %and, %not1
1802  ret i32 %or3
1803}
1804
1805define i32 @or_and_not_not_commute5(i32 %a, i32 %b, i32 %c) {
1806; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute5
1807; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1808; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1809; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1810; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1811; CHECK-NEXT:    ret i32 [[OR3]]
1812;
1813  %or1 = or i32 %b, %a
1814  %not1 = xor i32 %or1, -1
1815  %or2 = or i32 %a, %c
1816  %not2 = xor i32 %or2, -1
1817  %and = and i32 %not2, %b
1818  %or3 = or i32 %not1, %and
1819  ret i32 %or3
1820}
1821
1822define i32 @or_and_not_not_commute6(i32 %a, i32 %b0, i32 %c) {
1823; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute6
1824; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1825; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1826; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1827; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1828; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1829; CHECK-NEXT:    ret i32 [[OR3]]
1830;
1831  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1832  %or1 = or i32 %b, %a
1833  %not1 = xor i32 %or1, -1
1834  %or2 = or i32 %c, %a
1835  %not2 = xor i32 %or2, -1
1836  %and = and i32 %b, %not2
1837  %or3 = or i32 %and, %not1
1838  ret i32 %or3
1839}
1840
1841define i32 @or_and_not_not_commute7(i32 %a, i32 %b, i32 %c) {
1842; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute7
1843; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1844; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1845; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1846; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1847; CHECK-NEXT:    ret i32 [[OR3]]
1848;
1849  %or1 = or i32 %a, %b
1850  %not1 = xor i32 %or1, -1
1851  %or2 = or i32 %c, %a
1852  %not2 = xor i32 %or2, -1
1853  %and = and i32 %not2, %b
1854  %or3 = or i32 %and, %not1
1855  ret i32 %or3
1856}
1857
1858define i32 @or_and_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1859; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use1
1860; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1861; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
1862; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1863; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1864; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1865; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1866; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1867; CHECK-NEXT:    call void @use(i32 [[NOT1]])
1868; CHECK-NEXT:    ret i32 [[OR3]]
1869;
1870  %or1 = or i32 %b, %a
1871  %not1 = xor i32 %or1, -1
1872  %or2 = or i32 %a, %c
1873  %not2 = xor i32 %or2, -1
1874  %and = and i32 %not2, %b
1875  %or3 = or i32 %and, %not1
1876  call void @use(i32 %not1)
1877  ret i32 %or3
1878}
1879
1880define i32 @or_and_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1881; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use2
1882; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1883; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1884; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1885; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1886; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1887; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1888; CHECK-NEXT:    call void @use(i32 [[NOT2]])
1889; CHECK-NEXT:    ret i32 [[OR3]]
1890;
1891  %or1 = or i32 %b, %a
1892  %not1 = xor i32 %or1, -1
1893  %or2 = or i32 %a, %c
1894  %not2 = xor i32 %or2, -1
1895  %and = and i32 %not2, %b
1896  %or3 = or i32 %and, %not1
1897  call void @use(i32 %not2)
1898  ret i32 %or3
1899}
1900
1901define i32 @or_and_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {
1902; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_and_use
1903; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1904; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1905; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1906; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1907; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1908; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1909; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1910; CHECK-NEXT:    call void @use(i32 [[AND]])
1911; CHECK-NEXT:    ret i32 [[OR3]]
1912;
1913  %or1 = or i32 %b, %a
1914  %not1 = xor i32 %or1, -1
1915  %or2 = or i32 %a, %c
1916  %not2 = xor i32 %or2, -1
1917  %and = and i32 %not2, %b
1918  %or3 = or i32 %and, %not1
1919  call void @use(i32 %and)
1920  ret i32 %or3
1921}
1922
1923define i32 @or_and_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1924; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use1
1925; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1926; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
1927; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1928; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1929; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1930; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1931; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1932; CHECK-NEXT:    call void @use(i32 [[OR1]])
1933; CHECK-NEXT:    ret i32 [[OR3]]
1934;
1935  %or1 = or i32 %b, %a
1936  %not1 = xor i32 %or1, -1
1937  %or2 = or i32 %a, %c
1938  %not2 = xor i32 %or2, -1
1939  %and = and i32 %not2, %b
1940  %or3 = or i32 %and, %not1
1941  call void @use(i32 %or1)
1942  ret i32 %or3
1943}
1944
1945define i32 @or_and_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1946; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use2
1947; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1948; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1949; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1950; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1951; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1952; CHECK-NEXT:    call void @use(i32 [[OR2]])
1953; CHECK-NEXT:    ret i32 [[OR3]]
1954;
1955  %or1 = or i32 %b, %a
1956  %not1 = xor i32 %or1, -1
1957  %or2 = or i32 %a, %c
1958  %not2 = xor i32 %or2, -1
1959  %and = and i32 %not2, %b
1960  %or3 = or i32 %and, %not1
1961  call void @use(i32 %or2)
1962  ret i32 %or3
1963}
1964
1965; Check the use limit. It can be adjusted in the future in terms of
1966; LHS and RHS uses distribution to be more flexible.
1967define i32 @or_and_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {
1968; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_2_extra_uses
1969; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1970; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
1971; CHECK-NEXT:    call void @use(i32 [[OR1]])
1972; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1973; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1974; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1975; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1976; CHECK-NEXT:    call void @use(i32 [[AND]])
1977; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1978; CHECK-NEXT:    ret i32 [[OR3]]
1979;
1980  %or1 = or i32 %b, %a
1981  call void @use(i32 %or1)
1982  %not1 = xor i32 %or1, -1
1983  %or2 = or i32 %a, %c
1984  %not2 = xor i32 %or2, -1
1985  %and = and i32 %not2, %b
1986  call void @use(i32 %and)
1987  %or3 = or i32 %not1, %and
1988  ret i32 %or3
1989}
1990
1991define i32 @or_and_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {
1992; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_a
1993; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1994; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[D]]
1995; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1996; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1997; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1998; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1999; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
2000; CHECK-NEXT:    ret i32 [[OR3]]
2001;
2002  %or1 = or i32 %b, %d
2003  %not1 = xor i32 %or1, -1
2004  %or2 = or i32 %a, %c
2005  %not2 = xor i32 %or2, -1
2006  %and = and i32 %not2, %b
2007  %or3 = or i32 %and, %not1
2008  ret i32 %or3
2009}
2010
2011define i32 @or_and_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
2012; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_b
2013; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
2014; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[D]], [[A]]
2015; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
2016; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
2017; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
2018; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
2019; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
2020; CHECK-NEXT:    ret i32 [[OR3]]
2021;
2022  %or1 = or i32 %d, %a
2023  %not1 = xor i32 %or1, -1
2024  %or2 = or i32 %a, %c
2025  %not2 = xor i32 %or2, -1
2026  %and = and i32 %not2, %b
2027  %or3 = or i32 %and, %not1
2028  ret i32 %or3
2029}
2030
2031; (b | ~(a & c)) & ~(a & b) --> ~((b | c) & a)
2032
2033define i32 @and_or_not_not(i32 %a, i32 %b, i32 %c) {
2034; CHECK-LABEL: define {{[^@]+}}@and_or_not_not
2035; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2036; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2037; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2038; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2039; CHECK-NEXT:    ret i32 [[AND3]]
2040;
2041  %and1 = and i32 %b, %a
2042  %not1 = xor i32 %and1, -1
2043  %and2 = and i32 %a, %c
2044  %not2 = xor i32 %and2, -1
2045  %or = or i32 %not2, %b
2046  %and3 = and i32 %or, %not1
2047  ret i32 %and3
2048}
2049
2050define i32 @and_or_not_not_commute1(i32 %a, i32 %b0, i32 %c) {
2051; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute1
2052; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
2053; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
2054; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2055; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2056; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2057; CHECK-NEXT:    ret i32 [[AND3]]
2058;
2059  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2060  %and1 = and i32 %b, %a
2061  %not1 = xor i32 %and1, -1
2062  %and2 = and i32 %a, %c
2063  %not2 = xor i32 %and2, -1
2064  %or = or i32 %b, %not2
2065  %and3 = and i32 %or, %not1
2066  ret i32 %and3
2067}
2068
2069define i32 @and_or_not_not_commute2(i32 %a, i32 %b, i32 %c) {
2070; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute2
2071; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2072; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2073; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2074; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2075; CHECK-NEXT:    ret i32 [[AND3]]
2076;
2077  %and1 = and i32 %b, %a
2078  %not1 = xor i32 %and1, -1
2079  %and2 = and i32 %a, %c
2080  %not2 = xor i32 %and2, -1
2081  %or = or i32 %not2, %b
2082  %and3 = and i32 %or, %not1
2083  ret i32 %and3
2084}
2085
2086define i32 @and_or_not_not_commute3(i32 %a, i32 %b, i32 %c) {
2087; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute3
2088; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2089; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2090; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2091; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2092; CHECK-NEXT:    ret i32 [[AND3]]
2093;
2094  %and1 = and i32 %b, %a
2095  %not1 = xor i32 %and1, -1
2096  %and2 = and i32 %c, %a
2097  %not2 = xor i32 %and2, -1
2098  %or = or i32 %not2, %b
2099  %and3 = and i32 %or, %not1
2100  ret i32 %and3
2101}
2102
2103define i32 @and_or_not_not_commute4(i32 %a, i32 %b, i32 %c) {
2104; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute4
2105; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2106; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2107; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2108; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2109; CHECK-NEXT:    ret i32 [[AND3]]
2110;
2111  %and1 = and i32 %a, %b
2112  %not1 = xor i32 %and1, -1
2113  %and2 = and i32 %a, %c
2114  %not2 = xor i32 %and2, -1
2115  %or = or i32 %not2, %b
2116  %and3 = and i32 %or, %not1
2117  ret i32 %and3
2118}
2119
2120define i32 @and_or_not_not_commute5(i32 %a, i32 %b, i32 %c) {
2121; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute5
2122; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2123; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2124; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2125; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2126; CHECK-NEXT:    ret i32 [[AND3]]
2127;
2128  %and1 = and i32 %b, %a
2129  %not1 = xor i32 %and1, -1
2130  %and2 = and i32 %a, %c
2131  %not2 = xor i32 %and2, -1
2132  %or = or i32 %not2, %b
2133  %and3 = and i32 %not1, %or
2134  ret i32 %and3
2135}
2136
2137define i32 @and_or_not_not_commute6(i32 %a, i32 %b0, i32 %c) {
2138; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute6
2139; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
2140; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
2141; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2142; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2143; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2144; CHECK-NEXT:    ret i32 [[AND3]]
2145;
2146  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2147  %and1 = and i32 %b, %a
2148  %not1 = xor i32 %and1, -1
2149  %and2 = and i32 %c, %a
2150  %not2 = xor i32 %and2, -1
2151  %or = or i32 %b, %not2
2152  %and3 = and i32 %or, %not1
2153  ret i32 %and3
2154}
2155
2156define i32 @and_or_not_not_commute7(i32 %a, i32 %b, i32 %c) {
2157; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute7
2158; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2159; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2160; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2161; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2162; CHECK-NEXT:    ret i32 [[AND3]]
2163;
2164  %and1 = and i32 %a, %b
2165  %not1 = xor i32 %and1, -1
2166  %and2 = and i32 %c, %a
2167  %not2 = xor i32 %and2, -1
2168  %or = or i32 %not2, %b
2169  %and3 = and i32 %or, %not1
2170  ret i32 %and3
2171}
2172
2173define i32 @and_or_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {
2174; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use1
2175; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2176; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
2177; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2178; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2179; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2180; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2181; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2182; CHECK-NEXT:    call void @use(i32 [[NOT1]])
2183; CHECK-NEXT:    ret i32 [[AND3]]
2184;
2185  %and1 = and i32 %b, %a
2186  %not1 = xor i32 %and1, -1
2187  %and2 = and i32 %a, %c
2188  %not2 = xor i32 %and2, -1
2189  %or = or i32 %not2, %b
2190  %and3 = and i32 %or, %not1
2191  call void @use(i32 %not1)
2192  ret i32 %and3
2193}
2194
2195define i32 @and_or_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {
2196; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use2
2197; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2198; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2199; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2200; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2201; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2202; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2203; CHECK-NEXT:    call void @use(i32 [[NOT2]])
2204; CHECK-NEXT:    ret i32 [[AND3]]
2205;
2206  %and1 = and i32 %b, %a
2207  %not1 = xor i32 %and1, -1
2208  %and2 = and i32 %a, %c
2209  %not2 = xor i32 %and2, -1
2210  %or = or i32 %not2, %b
2211  %and3 = and i32 %or, %not1
2212  call void @use(i32 %not2)
2213  ret i32 %and3
2214}
2215
2216define i32 @and_or_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {
2217; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_and_use
2218; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2219; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2220; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2221; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2222; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2223; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2224; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2225; CHECK-NEXT:    call void @use(i32 [[OR]])
2226; CHECK-NEXT:    ret i32 [[AND3]]
2227;
2228  %and1 = and i32 %b, %a
2229  %not1 = xor i32 %and1, -1
2230  %and2 = and i32 %a, %c
2231  %not2 = xor i32 %and2, -1
2232  %or = or i32 %not2, %b
2233  %and3 = and i32 %or, %not1
2234  call void @use(i32 %or)
2235  ret i32 %and3
2236}
2237
2238define i32 @and_or_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {
2239; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use1
2240; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2241; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
2242; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2243; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2244; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2245; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2246; CHECK-NEXT:    call void @use(i32 [[AND1]])
2247; CHECK-NEXT:    ret i32 [[AND3]]
2248;
2249  %and1 = and i32 %b, %a
2250  %not1 = xor i32 %and1, -1
2251  %and2 = and i32 %a, %c
2252  %not2 = xor i32 %and2, -1
2253  %or = or i32 %not2, %b
2254  %and3 = and i32 %or, %not1
2255  call void @use(i32 %and1)
2256  ret i32 %and3
2257}
2258
2259define i32 @and_or_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {
2260; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use2
2261; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2262; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2263; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2264; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2265; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2266; CHECK-NEXT:    call void @use(i32 [[AND2]])
2267; CHECK-NEXT:    ret i32 [[AND3]]
2268;
2269  %and1 = and i32 %b, %a
2270  %not1 = xor i32 %and1, -1
2271  %and2 = and i32 %a, %c
2272  %not2 = xor i32 %and2, -1
2273  %or = or i32 %not2, %b
2274  %and3 = and i32 %or, %not1
2275  call void @use(i32 %and2)
2276  ret i32 %and3
2277}
2278
2279define i32 @and_or_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {
2280; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_2_extra_uses
2281; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2282; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
2283; CHECK-NEXT:    call void @use(i32 [[AND1]])
2284; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2285; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2286; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2287; CHECK-NEXT:    call void @use(i32 [[OR]])
2288; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2289; CHECK-NEXT:    ret i32 [[AND3]]
2290;
2291  %and1 = and i32 %b, %a
2292  call void @use(i32 %and1)
2293  %not1 = xor i32 %and1, -1
2294  %and2 = and i32 %a, %c
2295  %not2 = xor i32 %and2, -1
2296  %or = or i32 %not2, %b
2297  call void @use(i32 %or)
2298  %and3 = and i32 %not1, %or
2299  ret i32 %and3
2300}
2301
2302define i32 @and_or_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {
2303; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_a
2304; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
2305; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[D]]
2306; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2307; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2308; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2309; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2310; CHECK-NEXT:    ret i32 [[AND3]]
2311;
2312  %and1 = and i32 %b, %d
2313  %not1 = xor i32 %and1, -1
2314  %and2 = and i32 %a, %c
2315  %not2 = xor i32 %and2, -1
2316  %or = or i32 %not2, %b
2317  %and3 = and i32 %or, %not1
2318  ret i32 %and3
2319}
2320
2321define i32 @and_or_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
2322; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_b
2323; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
2324; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[D]], [[A]]
2325; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2326; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2327; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2328; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2329; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR]], [[NOT1]]
2330; CHECK-NEXT:    ret i32 [[AND3]]
2331;
2332  %and1 = and i32 %d, %a
2333  %not1 = xor i32 %and1, -1
2334  %and2 = and i32 %a, %c
2335  %not2 = xor i32 %and2, -1
2336  %or = or i32 %not2, %b
2337  %and3 = and i32 %or, %not1
2338  ret i32 %and3
2339}
2340
2341; (a & ~(b | c)) | ~(a | (b ^ c)) --> (~a & b & c) | ~(b | c)
2342
2343define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) {
2344; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor
2345; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2346; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2347; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2348; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2349; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2350; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2351; CHECK-NEXT:    ret i32 [[OR3]]
2352;
2353  %or1 = or i32 %b, %c
2354  %not1 = xor i32 %or1, -1
2355  %and1 = and i32 %not1, %a
2356  %xor1 = xor i32 %b, %c
2357  %or2 = or i32 %xor1, %a
2358  %not2 = xor i32 %or2, -1
2359  %or3 = or i32 %and1, %not2
2360  ret i32 %or3
2361}
2362
2363define i32 @and_not_or_or_not_or_xor_commute1(i32 %a, i32 %b, i32 %c) {
2364; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute1
2365; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2366; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[B]]
2367; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2368; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2369; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2370; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2371; CHECK-NEXT:    ret i32 [[OR3]]
2372;
2373  %or1 = or i32 %c, %b
2374  %not1 = xor i32 %or1, -1
2375  %and1 = and i32 %not1, %a
2376  %xor1 = xor i32 %b, %c
2377  %or2 = or i32 %xor1, %a
2378  %not2 = xor i32 %or2, -1
2379  %or3 = or i32 %and1, %not2
2380  ret i32 %or3
2381}
2382
2383define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) {
2384; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute2
2385; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2386; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2387; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2388; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2389; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2390; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2391; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2392; CHECK-NEXT:    ret i32 [[OR3]]
2393;
2394  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2395  %or1 = or i32 %b, %c
2396  %not1 = xor i32 %or1, -1
2397  %and1 = and i32 %a, %not1
2398  %xor1 = xor i32 %b, %c
2399  %or2 = or i32 %xor1, %a
2400  %not2 = xor i32 %or2, -1
2401  %or3 = or i32 %and1, %not2
2402  ret i32 %or3
2403}
2404
2405define i32 @and_not_or_or_not_or_xor_commute3(i32 %a, i32 %b, i32 %c) {
2406; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute3
2407; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2408; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2409; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C]], [[B]]
2410; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2411; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2412; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2413; CHECK-NEXT:    ret i32 [[OR3]]
2414;
2415  %or1 = or i32 %b, %c
2416  %not1 = xor i32 %or1, -1
2417  %and1 = and i32 %not1, %a
2418  %xor1 = xor i32 %c, %b
2419  %or2 = or i32 %xor1, %a
2420  %not2 = xor i32 %or2, -1
2421  %or3 = or i32 %and1, %not2
2422  ret i32 %or3
2423}
2424
2425define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) {
2426; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute4
2427; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2428; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2429; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2430; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2431; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[XOR1]]
2432; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2433; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2434; CHECK-NEXT:    ret i32 [[OR3]]
2435;
2436  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2437  %or1 = or i32 %b, %c
2438  %not1 = xor i32 %or1, -1
2439  %and1 = and i32 %a, %not1
2440  %xor1 = xor i32 %b, %c
2441  %or2 = or i32 %a, %xor1
2442  %not2 = xor i32 %or2, -1
2443  %or3 = or i32 %and1, %not2
2444  ret i32 %or3
2445}
2446
2447define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) {
2448; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute5
2449; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2450; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2451; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2452; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2453; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2454; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2455; CHECK-NEXT:    ret i32 [[OR3]]
2456;
2457  %or1 = or i32 %b, %c
2458  %not1 = xor i32 %or1, -1
2459  %and1 = and i32 %not1, %a
2460  %xor1 = xor i32 %b, %c
2461  %or2 = or i32 %xor1, %a
2462  %not2 = xor i32 %or2, -1
2463  %or3 = or i32 %not2, %and1
2464  ret i32 %or3
2465}
2466
2467define i32 @and_not_or_or_not_or_xor_use1(i32 %a, i32 %b, i32 %c) {
2468; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use1
2469; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2470; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2471; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2472; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2473; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2474; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2475; CHECK-NEXT:    call void @use(i32 [[OR1]])
2476; CHECK-NEXT:    ret i32 [[OR3]]
2477;
2478  %or1 = or i32 %b, %c
2479  %not1 = xor i32 %or1, -1
2480  %and1 = and i32 %not1, %a
2481  %xor1 = xor i32 %b, %c
2482  %or2 = or i32 %xor1, %a
2483  %not2 = xor i32 %or2, -1
2484  %or3 = or i32 %and1, %not2
2485  call void @use(i32 %or1)
2486  ret i32 %or3
2487}
2488
2489define i32 @and_not_or_or_not_or_xor_use2(i32 %a, i32 %b, i32 %c) {
2490; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use2
2491; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2492; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2493; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
2494; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2495; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2496; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2497; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2498; CHECK-NEXT:    call void @use(i32 [[NOT1]])
2499; CHECK-NEXT:    ret i32 [[OR3]]
2500;
2501  %or1 = or i32 %b, %c
2502  %not1 = xor i32 %or1, -1
2503  %and1 = and i32 %not1, %a
2504  %xor1 = xor i32 %b, %c
2505  %or2 = or i32 %xor1, %a
2506  %not2 = xor i32 %or2, -1
2507  %or3 = or i32 %and1, %not2
2508  call void @use(i32 %not1)
2509  ret i32 %or3
2510}
2511
2512define i32 @and_not_or_or_not_or_xor_use3(i32 %a, i32 %b, i32 %c) {
2513; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use3
2514; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2515; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2516; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
2517; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
2518; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2519; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2520; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
2521; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
2522; CHECK-NEXT:    call void @use(i32 [[AND1]])
2523; CHECK-NEXT:    ret i32 [[OR3]]
2524;
2525  %or1 = or i32 %b, %c
2526  %not1 = xor i32 %or1, -1
2527  %and1 = and i32 %not1, %a
2528  %xor1 = xor i32 %b, %c
2529  %or2 = or i32 %xor1, %a
2530  %not2 = xor i32 %or2, -1
2531  %or3 = or i32 %and1, %not2
2532  call void @use(i32 %and1)
2533  ret i32 %or3
2534}
2535
2536define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) {
2537; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use4
2538; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2539; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2540; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2541; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2542; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2543; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2544; CHECK-NEXT:    call void @use(i32 [[XOR1]])
2545; CHECK-NEXT:    ret i32 [[OR3]]
2546;
2547  %or1 = or i32 %b, %c
2548  %not1 = xor i32 %or1, -1
2549  %and1 = and i32 %not1, %a
2550  %xor1 = xor i32 %b, %c
2551  %or2 = or i32 %xor1, %a
2552  %not2 = xor i32 %or2, -1
2553  %or3 = or i32 %and1, %not2
2554  call void @use(i32 %xor1)
2555  ret i32 %or3
2556}
2557
2558define i32 @and_not_or_or_not_or_xor_use5(i32 %a, i32 %b, i32 %c) {
2559; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use5
2560; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2561; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2562; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2563; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2564; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2565; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2566; CHECK-NEXT:    call void @use(i32 [[OR2]])
2567; CHECK-NEXT:    ret i32 [[OR3]]
2568;
2569  %or1 = or i32 %b, %c
2570  %not1 = xor i32 %or1, -1
2571  %and1 = and i32 %not1, %a
2572  %xor1 = xor i32 %b, %c
2573  %or2 = or i32 %xor1, %a
2574  %not2 = xor i32 %or2, -1
2575  %or3 = or i32 %and1, %not2
2576  call void @use(i32 %or2)
2577  ret i32 %or3
2578}
2579
2580define i32 @and_not_or_or_not_or_xor_use6(i32 %a, i32 %b, i32 %c) {
2581; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use6
2582; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2583; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2584; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
2585; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
2586; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2587; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2588; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
2589; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
2590; CHECK-NEXT:    call void @use(i32 [[NOT2]])
2591; CHECK-NEXT:    ret i32 [[OR3]]
2592;
2593  %or1 = or i32 %b, %c
2594  %not1 = xor i32 %or1, -1
2595  %and1 = and i32 %not1, %a
2596  %xor1 = xor i32 %b, %c
2597  %or2 = or i32 %xor1, %a
2598  %not2 = xor i32 %or2, -1
2599  %or3 = or i32 %and1, %not2
2600  call void @use(i32 %not2)
2601  ret i32 %or3
2602}
2603
2604; (a | ~(b & c)) & ~(a & (b ^ c)) --> ~(a | b) | (a ^ b ^ c)
2605; This pattern is not handled because the result is more undefined than a source.
2606; It is invalid as is, but feezing %a and %b will make it valid.
2607
2608define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) {
2609; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor
2610; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2611; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2612; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2613; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2614; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2615; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2616; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2617; CHECK-NEXT:    ret i32 [[AND3]]
2618;
2619  %and1 = and i32 %b, %c
2620  %not1 = xor i32 %and1, -1
2621  %or1 = or i32 %not1, %a
2622  %xor1 = xor i32 %b, %c
2623  %and2 = and i32 %xor1, %a
2624  %not2 = xor i32 %and2, -1
2625  %and3 = and i32 %or1, %not2
2626  ret i32 %and3
2627}
2628
2629define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) {
2630; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute1
2631; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2632; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[B]]
2633; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2634; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2635; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2636; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2637; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2638; CHECK-NEXT:    ret i32 [[AND3]]
2639;
2640  %and1 = and i32 %c, %b
2641  %not1 = xor i32 %and1, -1
2642  %or1 = or i32 %not1, %a
2643  %xor1 = xor i32 %b, %c
2644  %and2 = and i32 %xor1, %a
2645  %not2 = xor i32 %and2, -1
2646  %and3 = and i32 %or1, %not2
2647  ret i32 %and3
2648}
2649
2650define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) {
2651; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute2
2652; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2653; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2654; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2655; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2656; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2657; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2658; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2659; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2660; CHECK-NEXT:    ret i32 [[AND3]]
2661;
2662  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2663  %and1 = and i32 %b, %c
2664  %not1 = xor i32 %and1, -1
2665  %or1 = or i32 %a, %not1
2666  %xor1 = xor i32 %b, %c
2667  %and2 = and i32 %xor1, %a
2668  %not2 = xor i32 %and2, -1
2669  %and3 = and i32 %or1, %not2
2670  ret i32 %and3
2671}
2672
2673define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) {
2674; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute3
2675; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2676; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2677; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2678; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2679; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C]], [[B]]
2680; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2681; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2682; CHECK-NEXT:    ret i32 [[AND3]]
2683;
2684  %and1 = and i32 %b, %c
2685  %not1 = xor i32 %and1, -1
2686  %or1 = or i32 %not1, %a
2687  %xor1 = xor i32 %c, %b
2688  %and2 = and i32 %xor1, %a
2689  %not2 = xor i32 %and2, -1
2690  %and3 = and i32 %or1, %not2
2691  ret i32 %and3
2692}
2693
2694define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) {
2695; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute4
2696; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2697; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2698; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2699; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2700; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2701; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2702; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[XOR1]]
2703; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2704; CHECK-NEXT:    ret i32 [[AND3]]
2705;
2706  %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2707  %and1 = and i32 %b, %c
2708  %not1 = xor i32 %and1, -1
2709  %or1 = or i32 %a, %not1
2710  %xor1 = xor i32 %b, %c
2711  %and2 = and i32 %a, %xor1
2712  %not2 = xor i32 %and2, -1
2713  %and3 = and i32 %or1, %not2
2714  ret i32 %and3
2715}
2716
2717define i32 @or_not_and_and_not_and_xor_commute5(i32 %a, i32 %b, i32 %c) {
2718; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute5
2719; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2720; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2721; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2722; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2723; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2724; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2725; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2726; CHECK-NEXT:    ret i32 [[AND3]]
2727;
2728  %and1 = and i32 %b, %c
2729  %not1 = xor i32 %and1, -1
2730  %or1 = or i32 %not1, %a
2731  %xor1 = xor i32 %b, %c
2732  %and2 = and i32 %xor1, %a
2733  %not2 = xor i32 %and2, -1
2734  %and3 = and i32 %not2, %or1
2735  ret i32 %and3
2736}
2737
2738define i32 @or_not_and_and_not_and_xor_use1(i32 %a, i32 %b, i32 %c) {
2739; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use1
2740; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2741; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2742; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2743; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2744; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2745; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2746; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2747; CHECK-NEXT:    call void @use(i32 [[AND1]])
2748; CHECK-NEXT:    ret i32 [[AND3]]
2749;
2750  %and1 = and i32 %b, %c
2751  %not1 = xor i32 %and1, -1
2752  %or1 = or i32 %not1, %a
2753  %xor1 = xor i32 %b, %c
2754  %and2 = and i32 %xor1, %a
2755  %not2 = xor i32 %and2, -1
2756  %and3 = and i32 %or1, %not2
2757  call void @use(i32 %and1)
2758  ret i32 %and3
2759}
2760
2761define i32 @or_not_and_and_not_and_xor_use2(i32 %a, i32 %b, i32 %c) {
2762; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use2
2763; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2764; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2765; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2766; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2767; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2768; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2769; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2770; CHECK-NEXT:    call void @use(i32 [[NOT1]])
2771; CHECK-NEXT:    ret i32 [[AND3]]
2772;
2773  %and1 = and i32 %b, %c
2774  %not1 = xor i32 %and1, -1
2775  %or1 = or i32 %not1, %a
2776  %xor1 = xor i32 %b, %c
2777  %and2 = and i32 %xor1, %a
2778  %not2 = xor i32 %and2, -1
2779  %and3 = and i32 %or1, %not2
2780  call void @use(i32 %not1)
2781  ret i32 %and3
2782}
2783
2784define i32 @or_not_and_and_not_and_xor_use3(i32 %a, i32 %b, i32 %c) {
2785; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use3
2786; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2787; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2788; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2789; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2790; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2791; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2792; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2793; CHECK-NEXT:    call void @use(i32 [[OR1]])
2794; CHECK-NEXT:    ret i32 [[AND3]]
2795;
2796  %and1 = and i32 %b, %c
2797  %not1 = xor i32 %and1, -1
2798  %or1 = or i32 %not1, %a
2799  %xor1 = xor i32 %b, %c
2800  %and2 = and i32 %xor1, %a
2801  %not2 = xor i32 %and2, -1
2802  %and3 = and i32 %or1, %not2
2803  call void @use(i32 %or1)
2804  ret i32 %and3
2805}
2806
2807define i32 @or_not_and_and_not_and_xor_use4(i32 %a, i32 %b, i32 %c) {
2808; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use4
2809; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2810; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2811; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2812; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2813; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2814; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2815; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2816; CHECK-NEXT:    call void @use(i32 [[XOR1]])
2817; CHECK-NEXT:    ret i32 [[AND3]]
2818;
2819  %and1 = and i32 %b, %c
2820  %not1 = xor i32 %and1, -1
2821  %or1 = or i32 %not1, %a
2822  %xor1 = xor i32 %b, %c
2823  %and2 = and i32 %xor1, %a
2824  %not2 = xor i32 %and2, -1
2825  %and3 = and i32 %or1, %not2
2826  call void @use(i32 %xor1)
2827  ret i32 %and3
2828}
2829
2830define i32 @or_not_and_and_not_and_xor_use5(i32 %a, i32 %b, i32 %c) {
2831; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use5
2832; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2833; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2834; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2835; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2836; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2837; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2838; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2839; CHECK-NEXT:    call void @use(i32 [[AND2]])
2840; CHECK-NEXT:    ret i32 [[AND3]]
2841;
2842  %and1 = and i32 %b, %c
2843  %not1 = xor i32 %and1, -1
2844  %or1 = or i32 %not1, %a
2845  %xor1 = xor i32 %b, %c
2846  %and2 = and i32 %xor1, %a
2847  %not2 = xor i32 %and2, -1
2848  %and3 = and i32 %or1, %not2
2849  call void @use(i32 %and2)
2850  ret i32 %and3
2851}
2852
2853define i32 @or_not_and_and_not_and_xor_use6(i32 %a, i32 %b, i32 %c) {
2854; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use6
2855; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2856; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2857; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2858; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2859; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2860; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2861; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2862; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2863; CHECK-NEXT:    call void @use(i32 [[NOT2]])
2864; CHECK-NEXT:    ret i32 [[AND3]]
2865;
2866  %and1 = and i32 %b, %c
2867  %not1 = xor i32 %and1, -1
2868  %or1 = or i32 %not1, %a
2869  %xor1 = xor i32 %b, %c
2870  %and2 = and i32 %xor1, %a
2871  %not2 = xor i32 %and2, -1
2872  %and3 = and i32 %or1, %not2
2873  call void @use(i32 %not2)
2874  ret i32 %and3
2875}
2876
2877; (~a & b & c) | ~(a | b | c) -> ~(a | (b ^ c))
2878
2879define i32 @not_and_and_or_not_or_or(i32 %a, i32 %b, i32 %c) {
2880; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or
2881; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2882; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2883; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2884; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2885; CHECK-NEXT:    ret i32 [[OR3]]
2886;
2887  %or1 = or i32 %b, %a
2888  %or2 = or i32 %or1, %c
2889  %not1 = xor i32 %or2, -1
2890  %not2 = xor i32 %a, -1
2891  %and1 = and i32 %not2, %b
2892  %and2 = and i32 %and1, %c
2893  %or3 = or i32 %and2, %not1
2894  ret i32 %or3
2895}
2896
2897define i32 @not_and_and_or_not_or_or_commute1_or(i32 %a, i32 %b, i32 %c) {
2898; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_or
2899; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2900; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2901; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2902; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2903; CHECK-NEXT:    ret i32 [[OR3]]
2904;
2905  %or1 = or i32 %c, %a
2906  %or2 = or i32 %or1, %b
2907  %not1 = xor i32 %or2, -1
2908  %not2 = xor i32 %a, -1
2909  %and1 = and i32 %not2, %b
2910  %and2 = and i32 %and1, %c
2911  %or3 = or i32 %and2, %not1
2912  ret i32 %or3
2913}
2914
2915define i32 @not_and_and_or_not_or_or_commute2_or(i32 %a, i32 %b, i32 %c) {
2916; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_or
2917; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2918; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2919; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2920; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2921; CHECK-NEXT:    ret i32 [[OR3]]
2922;
2923  %or1 = or i32 %b, %c
2924  %or2 = or i32 %or1, %a
2925  %not1 = xor i32 %or2, -1
2926  %not2 = xor i32 %a, -1
2927  %and1 = and i32 %not2, %b
2928  %and2 = and i32 %and1, %c
2929  %or3 = or i32 %and2, %not1
2930  ret i32 %or3
2931}
2932
2933define i32 @not_and_and_or_not_or_or_commute1_and(i32 %a, i32 %b, i32 %c) {
2934; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_and
2935; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2936; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
2937; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2938; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2939; CHECK-NEXT:    ret i32 [[OR3]]
2940;
2941  %or1 = or i32 %b, %a
2942  %or2 = or i32 %or1, %c
2943  %not1 = xor i32 %or2, -1
2944  %not2 = xor i32 %a, -1
2945  %and1 = and i32 %not2, %c
2946  %and2 = and i32 %and1, %b
2947  %or3 = or i32 %and2, %not1
2948  ret i32 %or3
2949}
2950
2951define i32 @not_and_and_or_not_or_or_commute2_and(i32 %a, i32 %b, i32 %c) {
2952; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_and
2953; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2954; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
2955; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2956; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2957; CHECK-NEXT:    ret i32 [[OR3]]
2958;
2959  %or1 = or i32 %b, %a
2960  %or2 = or i32 %or1, %c
2961  %not1 = xor i32 %or2, -1
2962  %not2 = xor i32 %a, -1
2963  %and1 = and i32 %b, %c
2964  %and2 = and i32 %and1, %not2
2965  %or3 = or i32 %and2, %not1
2966  ret i32 %or3
2967}
2968
2969define i32 @not_and_and_or_not_or_or_commute1(i32 %a, i32 %b, i32 %c) {
2970; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1
2971; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2972; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2973; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2974; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2975; CHECK-NEXT:    ret i32 [[OR3]]
2976;
2977  %or1 = or i32 %a, %b
2978  %or2 = or i32 %or1, %c
2979  %not1 = xor i32 %or2, -1
2980  %not2 = xor i32 %a, -1
2981  %and1 = and i32 %not2, %b
2982  %and2 = and i32 %and1, %c
2983  %or3 = or i32 %and2, %not1
2984  ret i32 %or3
2985}
2986
2987define i32 @not_and_and_or_not_or_or_commute2(i32 %a, i32 %b, i32 %c0) {
2988; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2
2989; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
2990; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
2991; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2992; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2993; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2994; CHECK-NEXT:    ret i32 [[OR3]]
2995;
2996  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2997  %or1 = or i32 %b, %a
2998  %or2 = or i32 %c, %or1
2999  %not1 = xor i32 %or2, -1
3000  %not2 = xor i32 %a, -1
3001  %and1 = and i32 %not2, %b
3002  %and2 = and i32 %and1, %c
3003  %or3 = or i32 %and2, %not1
3004  ret i32 %or3
3005}
3006
3007define i32 @not_and_and_or_not_or_or_commute3(i32 %a, i32 %b0, i32 %c) {
3008; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute3
3009; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3010; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3011; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3012; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3013; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3014; CHECK-NEXT:    ret i32 [[OR3]]
3015;
3016  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3017  %or1 = or i32 %b, %a
3018  %or2 = or i32 %or1, %c
3019  %not1 = xor i32 %or2, -1
3020  %not2 = xor i32 %a, -1
3021  %and1 = and i32 %b, %not2
3022  %and2 = and i32 %and1, %c
3023  %or3 = or i32 %and2, %not1
3024  ret i32 %or3
3025}
3026
3027define i32 @not_and_and_or_not_or_or_commute4(i32 %a, i32 %b, i32 %c0) {
3028; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute4
3029; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3030; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3031; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3032; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3033; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3034; CHECK-NEXT:    ret i32 [[OR3]]
3035;
3036  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3037  %or1 = or i32 %b, %a
3038  %or2 = or i32 %or1, %c
3039  %not1 = xor i32 %or2, -1
3040  %not2 = xor i32 %a, -1
3041  %and1 = and i32 %not2, %b
3042  %and2 = and i32 %c, %and1
3043  %or3 = or i32 %and2, %not1
3044  ret i32 %or3
3045}
3046
3047define i32 @not_and_and_or_not_or_or_use1(i32 %a, i32 %b, i32 %c) {
3048; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use1
3049; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3050; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3051; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3052; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3053; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3054; CHECK-NEXT:    call void @use(i32 [[OR1]])
3055; CHECK-NEXT:    ret i32 [[OR3]]
3056;
3057  %or1 = or i32 %b, %a
3058  %or2 = or i32 %or1, %c
3059  %not1 = xor i32 %or2, -1
3060  %not2 = xor i32 %a, -1
3061  %and1 = and i32 %not2, %b
3062  %and2 = and i32 %and1, %c
3063  %or3 = or i32 %and2, %not1
3064  call void @use(i32 %or1)
3065  ret i32 %or3
3066}
3067
3068define i32 @not_and_and_or_not_or_or_use2(i32 %a, i32 %b, i32 %c) {
3069; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use2
3070; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3071; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3072; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3073; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3074; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3075; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3076; CHECK-NEXT:    call void @use(i32 [[OR2]])
3077; CHECK-NEXT:    ret i32 [[OR3]]
3078;
3079  %or1 = or i32 %b, %a
3080  %or2 = or i32 %or1, %c
3081  %not1 = xor i32 %or2, -1
3082  %not2 = xor i32 %a, -1
3083  %and1 = and i32 %not2, %b
3084  %and2 = and i32 %and1, %c
3085  %or3 = or i32 %and2, %not1
3086  call void @use(i32 %or2)
3087  ret i32 %or3
3088}
3089
3090define i32 @not_and_and_or_not_or_or_use3(i32 %a, i32 %b, i32 %c) {
3091; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use3
3092; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3093; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3094; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3095; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR2]], -1
3096; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3097; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3098; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3099; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]
3100; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3101; CHECK-NEXT:    ret i32 [[OR3]]
3102;
3103  %or1 = or i32 %b, %a
3104  %or2 = or i32 %or1, %c
3105  %not1 = xor i32 %or2, -1
3106  %not2 = xor i32 %a, -1
3107  %and1 = and i32 %not2, %b
3108  %and2 = and i32 %and1, %c
3109  %or3 = or i32 %and2, %not1
3110  call void @use(i32 %not1)
3111  ret i32 %or3
3112}
3113
3114define i32 @not_and_and_or_not_or_or_use4(i32 %a, i32 %b, i32 %c) {
3115; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use4
3116; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3117; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3118; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3119; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3120; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3121; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3122; CHECK-NEXT:    ret i32 [[OR3]]
3123;
3124  %or1 = or i32 %b, %a
3125  %or2 = or i32 %or1, %c
3126  %not1 = xor i32 %or2, -1
3127  %not2 = xor i32 %a, -1
3128  %and1 = and i32 %not2, %b
3129  %and2 = and i32 %and1, %c
3130  %or3 = or i32 %and2, %not1
3131  call void @use(i32 %not2)
3132  ret i32 %or3
3133}
3134
3135define i32 @not_and_and_or_not_or_or_use5(i32 %a, i32 %b, i32 %c) {
3136; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use5
3137; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3138; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3139; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3140; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3141; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3142; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3143; CHECK-NEXT:    call void @use(i32 [[AND1]])
3144; CHECK-NEXT:    ret i32 [[OR3]]
3145;
3146  %or1 = or i32 %b, %a
3147  %or2 = or i32 %or1, %c
3148  %not1 = xor i32 %or2, -1
3149  %not2 = xor i32 %a, -1
3150  %and1 = and i32 %not2, %b
3151  %and2 = and i32 %and1, %c
3152  %or3 = or i32 %and2, %not1
3153  call void @use(i32 %and1)
3154  ret i32 %or3
3155}
3156
3157define i32 @not_and_and_or_not_or_or_use6(i32 %a, i32 %b, i32 %c) {
3158; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use6
3159; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3160; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3161; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3162; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR2]], -1
3163; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3164; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3165; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3166; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]
3167; CHECK-NEXT:    call void @use(i32 [[AND2]])
3168; CHECK-NEXT:    ret i32 [[OR3]]
3169;
3170  %or1 = or i32 %b, %a
3171  %or2 = or i32 %or1, %c
3172  %not1 = xor i32 %or2, -1
3173  %not2 = xor i32 %a, -1
3174  %and1 = and i32 %not2, %b
3175  %and2 = and i32 %and1, %c
3176  %or3 = or i32 %and2, %not1
3177  call void @use(i32 %and2)
3178  ret i32 %or3
3179}
3180
3181; (~a | b | c) & ~(a & b & c) -> ~a | (b ^ c)
3182
3183define i32 @not_or_or_and_not_and_and(i32 %a, i32 %b, i32 %c) {
3184; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and
3185; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3186; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3187; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3188; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3189; CHECK-NEXT:    ret i32 [[AND3]]
3190;
3191  %and1 = and i32 %b, %a
3192  %and2 = and i32 %and1, %c
3193  %not1 = xor i32 %and2, -1
3194  %not2 = xor i32 %a, -1
3195  %or1 = or i32 %not2, %b
3196  %or2 = or i32 %or1, %c
3197  %and3 = and i32 %or2, %not1
3198  ret i32 %and3
3199}
3200
3201define i32 @not_or_or_and_not_and_and_commute1_and(i32 %a, i32 %b, i32 %c) {
3202; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_and
3203; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3204; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3205; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3206; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3207; CHECK-NEXT:    ret i32 [[AND3]]
3208;
3209  %and1 = and i32 %c, %a
3210  %and2 = and i32 %and1, %b
3211  %not1 = xor i32 %and2, -1
3212  %not2 = xor i32 %a, -1
3213  %or1 = or i32 %not2, %b
3214  %or2 = or i32 %or1, %c
3215  %and3 = and i32 %or2, %not1
3216  ret i32 %and3
3217}
3218
3219define i32 @not_or_or_and_not_and_and_commute2_and(i32 %a, i32 %b, i32 %c) {
3220; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_and
3221; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3222; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3223; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3224; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3225; CHECK-NEXT:    ret i32 [[AND3]]
3226;
3227  %and1 = and i32 %b, %c
3228  %and2 = and i32 %and1, %a
3229  %not1 = xor i32 %and2, -1
3230  %not2 = xor i32 %a, -1
3231  %or1 = or i32 %not2, %b
3232  %or2 = or i32 %or1, %c
3233  %and3 = and i32 %or2, %not1
3234  ret i32 %and3
3235}
3236
3237define i32 @not_or_or_and_not_and_and_commute1_or(i32 %a, i32 %b, i32 %c) {
3238; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_or
3239; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3240; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3241; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
3242; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3243; CHECK-NEXT:    ret i32 [[AND3]]
3244;
3245  %and1 = and i32 %b, %a
3246  %and2 = and i32 %and1, %c
3247  %not1 = xor i32 %and2, -1
3248  %not2 = xor i32 %a, -1
3249  %or1 = or i32 %not2, %c
3250  %or2 = or i32 %or1, %b
3251  %and3 = and i32 %or2, %not1
3252  ret i32 %and3
3253}
3254
3255define i32 @not_or_or_and_not_and_and_commute2_or(i32 %a, i32 %b, i32 %c) {
3256; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_or
3257; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3258; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3259; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
3260; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3261; CHECK-NEXT:    ret i32 [[AND3]]
3262;
3263  %and1 = and i32 %b, %a
3264  %and2 = and i32 %and1, %c
3265  %not1 = xor i32 %and2, -1
3266  %not2 = xor i32 %a, -1
3267  %or1 = or i32 %b, %c
3268  %or2 = or i32 %or1, %not2
3269  %and3 = and i32 %or2, %not1
3270  ret i32 %and3
3271}
3272
3273define i32 @not_or_or_and_not_and_and_commute1(i32 %a, i32 %b, i32 %c) {
3274; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1
3275; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3276; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3277; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3278; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3279; CHECK-NEXT:    ret i32 [[AND3]]
3280;
3281  %and1 = and i32 %a, %b
3282  %and2 = and i32 %and1, %c
3283  %not1 = xor i32 %and2, -1
3284  %not2 = xor i32 %a, -1
3285  %or1 = or i32 %not2, %b
3286  %or2 = or i32 %or1, %c
3287  %and3 = and i32 %or2, %not1
3288  ret i32 %and3
3289}
3290
3291define i32 @not_or_or_and_not_and_and_commute2(i32 %a, i32 %b, i32 %c0) {
3292; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2
3293; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3294; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3295; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3296; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3297; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3298; CHECK-NEXT:    ret i32 [[AND3]]
3299;
3300  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3301  %and1 = and i32 %b, %a
3302  %and2 = and i32 %c, %and1
3303  %not1 = xor i32 %and2, -1
3304  %not2 = xor i32 %a, -1
3305  %or1 = or i32 %not2, %b
3306  %or2 = or i32 %or1, %c
3307  %and3 = and i32 %or2, %not1
3308  ret i32 %and3
3309}
3310
3311define i32 @not_or_or_and_not_and_and_commute3(i32 %a, i32 %b0, i32 %c) {
3312; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute3
3313; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3314; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3315; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3316; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3317; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3318; CHECK-NEXT:    ret i32 [[AND3]]
3319;
3320  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3321  %and1 = and i32 %b, %a
3322  %and2 = and i32 %and1, %c
3323  %not1 = xor i32 %and2, -1
3324  %not2 = xor i32 %a, -1
3325  %or1 = or i32 %b, %not2
3326  %or2 = or i32 %or1, %c
3327  %and3 = and i32 %or2, %not1
3328  ret i32 %and3
3329}
3330
3331define i32 @not_or_or_and_not_and_and_commute4(i32 %a, i32 %b, i32 %c0) {
3332; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute4
3333; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3334; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3335; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3336; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3337; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3338; CHECK-NEXT:    ret i32 [[AND3]]
3339;
3340  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3341  %and1 = and i32 %b, %a
3342  %and2 = and i32 %and1, %c
3343  %not1 = xor i32 %and2, -1
3344  %not2 = xor i32 %a, -1
3345  %or1 = or i32 %not2, %b
3346  %or2 = or i32 %c, %or1
3347  %and3 = and i32 %or2, %not1
3348  ret i32 %and3
3349}
3350
3351define i32 @not_or_or_and_not_and_and_use1(i32 %a, i32 %b, i32 %c) {
3352; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use1
3353; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3354; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3355; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3356; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3357; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3358; CHECK-NEXT:    call void @use(i32 [[AND1]])
3359; CHECK-NEXT:    ret i32 [[AND3]]
3360;
3361  %and1 = and i32 %b, %a
3362  %and2 = and i32 %and1, %c
3363  %not1 = xor i32 %and2, -1
3364  %not2 = xor i32 %a, -1
3365  %or1 = or i32 %not2, %b
3366  %or2 = or i32 %or1, %c
3367  %and3 = and i32 %or2, %not1
3368  call void @use(i32 %and1)
3369  ret i32 %and3
3370}
3371
3372define i32 @not_or_or_and_not_and_and_use2(i32 %a, i32 %b, i32 %c) {
3373; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use2
3374; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3375; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3376; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3377; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3378; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3379; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3380; CHECK-NEXT:    call void @use(i32 [[AND2]])
3381; CHECK-NEXT:    ret i32 [[AND3]]
3382;
3383  %and1 = and i32 %b, %a
3384  %and2 = and i32 %and1, %c
3385  %not1 = xor i32 %and2, -1
3386  %not2 = xor i32 %a, -1
3387  %or1 = or i32 %not2, %b
3388  %or2 = or i32 %or1, %c
3389  %and3 = and i32 %or2, %not1
3390  call void @use(i32 %and2)
3391  ret i32 %and3
3392}
3393
3394define i32 @not_or_or_and_not_and_and_use3(i32 %a, i32 %b, i32 %c) {
3395; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use3
3396; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3397; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3398; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3399; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND2]], -1
3400; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3401; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3402; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3403; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]
3404; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3405; CHECK-NEXT:    ret i32 [[AND3]]
3406;
3407  %and1 = and i32 %b, %a
3408  %and2 = and i32 %and1, %c
3409  %not1 = xor i32 %and2, -1
3410  %not2 = xor i32 %a, -1
3411  %or1 = or i32 %not2, %b
3412  %or2 = or i32 %or1, %c
3413  %and3 = and i32 %or2, %not1
3414  call void @use(i32 %not1)
3415  ret i32 %and3
3416}
3417
3418define i32 @not_or_or_and_not_and_and_use4(i32 %a, i32 %b, i32 %c) {
3419; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use4
3420; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3421; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3422; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3423; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3424; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3425; CHECK-NEXT:    ret i32 [[AND3]]
3426;
3427  %and1 = and i32 %b, %a
3428  %and2 = and i32 %and1, %c
3429  %not1 = xor i32 %and2, -1
3430  %not2 = xor i32 %a, -1
3431  %or1 = or i32 %not2, %b
3432  %or2 = or i32 %or1, %c
3433  %and3 = and i32 %or2, %not1
3434  call void @use(i32 %not2)
3435  ret i32 %and3
3436}
3437
3438define i32 @not_or_or_and_not_and_and_use5(i32 %a, i32 %b, i32 %c) {
3439; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use5
3440; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3441; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3442; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3443; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3444; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3445; CHECK-NEXT:    call void @use(i32 [[OR1]])
3446; CHECK-NEXT:    ret i32 [[AND3]]
3447;
3448  %and1 = and i32 %b, %a
3449  %and2 = and i32 %and1, %c
3450  %not1 = xor i32 %and2, -1
3451  %not2 = xor i32 %a, -1
3452  %or1 = or i32 %not2, %b
3453  %or2 = or i32 %or1, %c
3454  %and3 = and i32 %or2, %not1
3455  call void @use(i32 %or1)
3456  ret i32 %and3
3457}
3458
3459define i32 @not_or_or_and_not_and_and_use6(i32 %a, i32 %b, i32 %c) {
3460; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use6
3461; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3462; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3463; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3464; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3465; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3466; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3467; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]
3468; CHECK-NEXT:    call void @use(i32 [[OR2]])
3469; CHECK-NEXT:    ret i32 [[AND3]]
3470;
3471  %and1 = and i32 %b, %a
3472  %and2 = and i32 %and1, %c
3473  %not1 = xor i32 %and2, -1
3474  %not2 = xor i32 %a, -1
3475  %or1 = or i32 %not2, %b
3476  %or2 = or i32 %or1, %c
3477  %and3 = and i32 %or2, %not1
3478  call void @use(i32 %or2)
3479  ret i32 %and3
3480}
3481
3482; (~a & b & c) | ~(a | b) -> (c | ~b) & ~a
3483
3484define i32 @not_and_and_or_no_or(i32 %a, i32 %b, i32 %c) {
3485; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or
3486; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3487; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3488; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3489; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3490; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3491; CHECK-NEXT:    ret i32 [[OR2]]
3492;
3493  %or1 = or i32 %b, %a
3494  %not1 = xor i32 %or1, -1
3495  %not2 = xor i32 %a, -1
3496  %and1 = and i32 %not2, %b
3497  %and2 = and i32 %and1, %c
3498  %or2 = or i32 %and2, %not1
3499  ret i32 %or2
3500}
3501
3502define i32 @not_and_and_or_no_or_commute1_and(i32 %a, i32 %b, i32 %c) {
3503; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1_and
3504; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3505; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3506; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3507; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3508; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3509; CHECK-NEXT:    ret i32 [[OR2]]
3510;
3511  %or1 = or i32 %b, %a
3512  %not1 = xor i32 %or1, -1
3513  %not2 = xor i32 %a, -1
3514  %and1 = and i32 %c, %b
3515  %and2 = and i32 %and1, %not2
3516  %or2 = or i32 %and2, %not1
3517  ret i32 %or2
3518}
3519
3520define i32 @not_and_and_or_no_or_commute2_and(i32 %a, i32 %b, i32 %c) {
3521; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2_and
3522; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3523; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3524; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3525; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3526; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3527; CHECK-NEXT:    ret i32 [[OR2]]
3528;
3529  %or1 = or i32 %b, %a
3530  %not1 = xor i32 %or1, -1
3531  %not2 = xor i32 %a, -1
3532  %and1 = and i32 %not2, %c
3533  %and2 = and i32 %and1, %b
3534  %or2 = or i32 %and2, %not1
3535  ret i32 %or2
3536}
3537
3538define i32 @not_and_and_or_no_or_commute1(i32 %a, i32 %b, i32 %c) {
3539; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1
3540; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3541; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3542; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3543; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3544; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3545; CHECK-NEXT:    ret i32 [[OR2]]
3546;
3547  %or1 = or i32 %a, %b
3548  %not1 = xor i32 %or1, -1
3549  %not2 = xor i32 %a, -1
3550  %and1 = and i32 %not2, %b
3551  %and2 = and i32 %and1, %c
3552  %or2 = or i32 %and2, %not1
3553  ret i32 %or2
3554}
3555
3556define i32 @not_and_and_or_no_or_commute2(i32 %a, i32 %b0, i32 %c) {
3557; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2
3558; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3559; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3560; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3561; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3562; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3563; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3564; CHECK-NEXT:    ret i32 [[OR2]]
3565;
3566  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3567  %or1 = or i32 %b, %a
3568  %not1 = xor i32 %or1, -1
3569  %not2 = xor i32 %a, -1
3570  %and1 = and i32 %b, %not2
3571  %and2 = and i32 %and1, %c
3572  %or2 = or i32 %and2, %not1
3573  ret i32 %or2
3574}
3575
3576define i32 @not_and_and_or_no_or_commute3(i32 %a, i32 %b, i32 %c0) {
3577; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute3
3578; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3579; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3580; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3581; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3582; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3583; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3584; CHECK-NEXT:    ret i32 [[OR2]]
3585;
3586  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3587  %or1 = or i32 %b, %a
3588  %not1 = xor i32 %or1, -1
3589  %not2 = xor i32 %a, -1
3590  %and1 = and i32 %not2, %b
3591  %and2 = and i32 %c, %and1
3592  %or2 = or i32 %and2, %not1
3593  ret i32 %or2
3594}
3595
3596define i32 @not_and_and_or_no_or_use1(i32 %a, i32 %b, i32 %c) {
3597; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use1
3598; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3599; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3600; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3601; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3602; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3603; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3604; CHECK-NEXT:    ret i32 [[OR2]]
3605;
3606  %or1 = or i32 %b, %a
3607  %not1 = xor i32 %or1, -1
3608  %not2 = xor i32 %a, -1
3609  %and1 = and i32 %not2, %b
3610  %and2 = and i32 %and1, %c
3611  %or2 = or i32 %and2, %not1
3612  call void @use(i32 %not2)
3613  ret i32 %or2
3614}
3615
3616define i32 @not_and_and_or_no_or_use2(i32 %a, i32 %b, i32 %c) {
3617; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use2
3618; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3619; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3620; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3621; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3622; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3623; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3624; CHECK-NEXT:    ret i32 [[OR2]]
3625;
3626  %or1 = or i32 %b, %a
3627  %not1 = xor i32 %or1, -1
3628  %not2 = xor i32 %a, -1
3629  %and1 = and i32 %b, %c
3630  %and2 = and i32 %and1, %not2
3631  %or2 = or i32 %and2, %not1
3632  call void @use(i32 %not2)
3633  ret i32 %or2
3634}
3635
3636define i32 @not_and_and_or_no_or_use3(i32 %a, i32 %b, i32 %c) {
3637; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use3
3638; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3639; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3640; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3641; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3642; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3643; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3644; CHECK-NEXT:    ret i32 [[OR2]]
3645;
3646  %or1 = or i32 %b, %a
3647  %not1 = xor i32 %or1, -1
3648  %not2 = xor i32 %a, -1
3649  %and1 = and i32 %not2, %c
3650  %and2 = and i32 %and1, %b
3651  %or2 = or i32 %and2, %not1
3652  call void @use(i32 %not2)
3653  ret i32 %or2
3654}
3655
3656define i32 @not_and_and_or_no_or_use4(i32 %a, i32 %b, i32 %c) {
3657; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use4
3658; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3659; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3660; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3661; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3662; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3663; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3664; CHECK-NEXT:    ret i32 [[OR2]]
3665;
3666  %or1 = or i32 %b, %a
3667  %not1 = xor i32 %or1, -1
3668  %not2 = xor i32 %a, -1
3669  %and1 = and i32 %not2, %c
3670  %and2 = and i32 %and1, %b
3671  %or2 = or i32 %and2, %not1
3672  call void @use(i32 %not2)
3673  ret i32 %or2
3674}
3675
3676define i32 @not_and_and_or_no_or_use5(i32 %a, i32 %b, i32 %c) {
3677; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use5
3678; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3679; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3680; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
3681; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3682; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]
3683; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[TMP1]], [[B]]
3684; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3685; CHECK-NEXT:    call void @use(i32 [[OR1]])
3686; CHECK-NEXT:    ret i32 [[OR2]]
3687;
3688  %or1 = or i32 %b, %a
3689  %not1 = xor i32 %or1, -1
3690  %not2 = xor i32 %a, -1
3691  %and1 = and i32 %not2, %b
3692  %and2 = and i32 %and1, %c
3693  %or2 = or i32 %and2, %not1
3694  call void @use(i32 %or1)
3695  ret i32 %or2
3696}
3697
3698define i32 @not_and_and_or_no_or_use6(i32 %a, i32 %b, i32 %c) {
3699; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use6
3700; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3701; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3702; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
3703; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3704; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]
3705; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[TMP1]], [[B]]
3706; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3707; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3708; CHECK-NEXT:    ret i32 [[OR2]]
3709;
3710  %or1 = or i32 %b, %a
3711  %not1 = xor i32 %or1, -1
3712  %not2 = xor i32 %a, -1
3713  %and1 = and i32 %not2, %b
3714  %and2 = and i32 %and1, %c
3715  %or2 = or i32 %and2, %not1
3716  call void @use(i32 %not1)
3717  ret i32 %or2
3718}
3719
3720define i32 @not_and_and_or_no_or_use7(i32 %a, i32 %b, i32 %c) {
3721; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use7
3722; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3723; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3724; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3725; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3726; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3727; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3728; CHECK-NEXT:    call void @use(i32 [[AND1]])
3729; CHECK-NEXT:    ret i32 [[OR2]]
3730;
3731  %or1 = or i32 %b, %a
3732  %not1 = xor i32 %or1, -1
3733  %not2 = xor i32 %a, -1
3734  %and1 = and i32 %not2, %b
3735  %and2 = and i32 %and1, %c
3736  %or2 = or i32 %and2, %not1
3737  call void @use(i32 %and1)
3738  ret i32 %or2
3739}
3740
3741define i32 @not_and_and_or_no_or_use8(i32 %a, i32 %b, i32 %c) {
3742; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use8
3743; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3744; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3745; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
3746; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3747; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]
3748; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[TMP1]], [[B]]
3749; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3750; CHECK-NEXT:    call void @use(i32 [[AND2]])
3751; CHECK-NEXT:    ret i32 [[OR2]]
3752;
3753  %or1 = or i32 %b, %a
3754  %not1 = xor i32 %or1, -1
3755  %not2 = xor i32 %a, -1
3756  %and1 = and i32 %not2, %b
3757  %and2 = and i32 %and1, %c
3758  %or2 = or i32 %and2, %not1
3759  call void @use(i32 %and2)
3760  ret i32 %or2
3761}
3762
3763; (~a | b | c) & ~(a & b) -> (c & ~b) | ~a
3764
3765define i32 @not_or_or_and_no_and(i32 %a, i32 %b, i32 %c) {
3766; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and
3767; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3768; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3769; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3770; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3771; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3772; CHECK-NEXT:    ret i32 [[AND2]]
3773;
3774  %and1 = and i32 %b, %a
3775  %not1 = xor i32 %and1, -1
3776  %not2 = xor i32 %a, -1
3777  %or1 = or i32 %not2, %b
3778  %or2 = or i32 %or1, %c
3779  %and2 = and i32 %or2, %not1
3780  ret i32 %and2
3781}
3782
3783define i32 @not_or_or_and_no_and_commute1_or(i32 %a, i32 %b, i32 %c) {
3784; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1_or
3785; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3786; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3787; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3788; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3789; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3790; CHECK-NEXT:    ret i32 [[AND2]]
3791;
3792  %and1 = and i32 %b, %a
3793  %not1 = xor i32 %and1, -1
3794  %not2 = xor i32 %a, -1
3795  %or1 = or i32 %c, %b
3796  %or2 = or i32 %or1, %not2
3797  %and2 = and i32 %or2, %not1
3798  ret i32 %and2
3799}
3800
3801define i32 @not_or_or_and_no_and_commute2_or(i32 %a, i32 %b, i32 %c) {
3802; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2_or
3803; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3804; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3805; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3806; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3807; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3808; CHECK-NEXT:    ret i32 [[AND2]]
3809;
3810  %and1 = and i32 %b, %a
3811  %not1 = xor i32 %and1, -1
3812  %not2 = xor i32 %a, -1
3813  %or1 = or i32 %not2, %c
3814  %or2 = or i32 %or1, %b
3815  %and2 = and i32 %or2, %not1
3816  ret i32 %and2
3817}
3818
3819define i32 @not_or_or_and_no_and_commute1(i32 %a, i32 %b, i32 %c) {
3820; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1
3821; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3822; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3823; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3824; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3825; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3826; CHECK-NEXT:    ret i32 [[AND2]]
3827;
3828  %and1 = and i32 %a, %b
3829  %not1 = xor i32 %and1, -1
3830  %not2 = xor i32 %a, -1
3831  %or1 = or i32 %not2, %b
3832  %or2 = or i32 %or1, %c
3833  %and2 = and i32 %or2, %not1
3834  ret i32 %and2
3835}
3836
3837define i32 @not_or_or_and_no_and_commute2(i32 %a, i32 %b0, i32 %c) {
3838; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2
3839; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3840; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3841; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3842; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3843; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3844; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3845; CHECK-NEXT:    ret i32 [[AND2]]
3846;
3847  %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3848  %and1 = and i32 %b, %a
3849  %not1 = xor i32 %and1, -1
3850  %not2 = xor i32 %a, -1
3851  %or1 = or i32 %b, %not2
3852  %or2 = or i32 %or1, %c
3853  %and2 = and i32 %or2, %not1
3854  ret i32 %and2
3855}
3856
3857define i32 @not_or_or_and_no_and_commute3(i32 %a, i32 %b, i32 %c0) {
3858; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute3
3859; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3860; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3861; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3862; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3863; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3864; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3865; CHECK-NEXT:    ret i32 [[AND2]]
3866;
3867  %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3868  %and1 = and i32 %b, %a
3869  %not1 = xor i32 %and1, -1
3870  %not2 = xor i32 %a, -1
3871  %or1 = or i32 %not2, %b
3872  %or2 = or i32 %c, %or1
3873  %and2 = and i32 %or2, %not1
3874  ret i32 %and2
3875}
3876
3877define i32 @not_or_or_and_no_and_use1(i32 %a, i32 %b, i32 %c) {
3878; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use1
3879; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3880; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3881; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3882; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3883; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3884; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3885; CHECK-NEXT:    ret i32 [[AND2]]
3886;
3887  %and1 = and i32 %b, %a
3888  %not1 = xor i32 %and1, -1
3889  %not2 = xor i32 %a, -1
3890  %or1 = or i32 %not2, %b
3891  %or2 = or i32 %or1, %c
3892  %and2 = and i32 %or2, %not1
3893  call void @use(i32 %not2)
3894  ret i32 %and2
3895}
3896
3897define i32 @not_or_or_and_no_and_use2(i32 %a, i32 %b, i32 %c) {
3898; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use2
3899; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3900; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3901; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3902; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3903; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3904; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3905; CHECK-NEXT:    ret i32 [[AND2]]
3906;
3907  %and1 = and i32 %b, %a
3908  %not1 = xor i32 %and1, -1
3909  %not2 = xor i32 %a, -1
3910  %or1 = or i32 %b, %c
3911  %or2 = or i32 %or1, %not2
3912  %and2 = and i32 %or2, %not1
3913  call void @use(i32 %not2)
3914  ret i32 %and2
3915}
3916
3917define i32 @not_or_or_and_no_and_use3(i32 %a, i32 %b, i32 %c) {
3918; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use3
3919; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3920; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3921; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3922; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3923; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3924; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3925; CHECK-NEXT:    ret i32 [[AND2]]
3926;
3927  %and1 = and i32 %b, %a
3928  %not1 = xor i32 %and1, -1
3929  %not2 = xor i32 %a, -1
3930  %or1 = or i32 %not2, %c
3931  %or2 = or i32 %or1, %b
3932  %and2 = and i32 %or2, %not1
3933  call void @use(i32 %not2)
3934  ret i32 %and2
3935}
3936
3937define i32 @not_or_or_and_no_and_use4(i32 %a, i32 %b, i32 %c) {
3938; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use4
3939; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3940; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3941; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3942; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3943; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3944; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3945; CHECK-NEXT:    ret i32 [[AND2]]
3946;
3947  %and1 = and i32 %b, %a
3948  %not1 = xor i32 %and1, -1
3949  %not2 = xor i32 %a, -1
3950  %or1 = or i32 %not2, %c
3951  %or2 = or i32 %or1, %b
3952  %and2 = and i32 %or2, %not1
3953  call void @use(i32 %not2)
3954  ret i32 %and2
3955}
3956
3957define i32 @not_or_or_and_no_and_use5(i32 %a, i32 %b, i32 %c) {
3958; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use5
3959; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3960; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3961; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3962; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]
3963; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[TMP1]], [[B]]
3964; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]
3965; CHECK-NEXT:    call void @use(i32 [[AND1]])
3966; CHECK-NEXT:    ret i32 [[AND2]]
3967;
3968  %and1 = and i32 %b, %a
3969  %not1 = xor i32 %and1, -1
3970  %not2 = xor i32 %a, -1
3971  %or1 = or i32 %not2, %b
3972  %or2 = or i32 %or1, %c
3973  %and2 = and i32 %or2, %not1
3974  call void @use(i32 %and1)
3975  ret i32 %and2
3976}
3977
3978define i32 @not_or_or_and_no_and_use6(i32 %a, i32 %b, i32 %c) {
3979; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use6
3980; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3981; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3982; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
3983; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3984; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]
3985; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[TMP1]], [[B]]
3986; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]
3987; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3988; CHECK-NEXT:    ret i32 [[AND2]]
3989;
3990  %and1 = and i32 %b, %a
3991  %not1 = xor i32 %and1, -1
3992  %not2 = xor i32 %a, -1
3993  %or1 = or i32 %not2, %b
3994  %or2 = or i32 %or1, %c
3995  %and2 = and i32 %or2, %not1
3996  call void @use(i32 %not1)
3997  ret i32 %and2
3998}
3999
4000define i32 @not_or_or_and_no_and_use7(i32 %a, i32 %b, i32 %c) {
4001; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use7
4002; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
4003; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
4004; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
4005; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
4006; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
4007; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
4008; CHECK-NEXT:    call void @use(i32 [[OR1]])
4009; CHECK-NEXT:    ret i32 [[AND2]]
4010;
4011  %and1 = and i32 %b, %a
4012  %not1 = xor i32 %and1, -1
4013  %not2 = xor i32 %a, -1
4014  %or1 = or i32 %not2, %b
4015  %or2 = or i32 %or1, %c
4016  %and2 = and i32 %or2, %not1
4017  call void @use(i32 %or1)
4018  ret i32 %and2
4019}
4020
4021define i32 @not_or_or_and_no_and_use8(i32 %a, i32 %b, i32 %c) {
4022; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use8
4023; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
4024; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
4025; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
4026; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]
4027; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[TMP1]], [[B]]
4028; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]
4029; CHECK-NEXT:    call void @use(i32 [[OR2]])
4030; CHECK-NEXT:    ret i32 [[AND2]]
4031;
4032  %and1 = and i32 %b, %a
4033  %not1 = xor i32 %and1, -1
4034  %not2 = xor i32 %a, -1
4035  %or1 = or i32 %not2, %b
4036  %or2 = or i32 %or1, %c
4037  %and2 = and i32 %or2, %not1
4038  call void @use(i32 %or2)
4039  ret i32 %and2
4040}
4041
4042define i4 @and_orn_xor(i4 %a, i4 %b) {
4043; CHECK-LABEL: define {{[^@]+}}@and_orn_xor
4044; CHECK-SAME: (i4 [[A:%.*]], i4 [[B:%.*]]) {
4045; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[A]], -1
4046; CHECK-NEXT:    [[R:%.*]] = and i4 [[B]], [[TMP1]]
4047; CHECK-NEXT:    ret i4 [[R]]
4048;
4049  %xor = xor i4 %a, %b
4050  %nota = xor i4 %a, -1
4051  %or = or i4 %nota, %b
4052  %r = and i4 %or, %xor
4053  ret i4 %r
4054}
4055
4056define <2 x i4> @and_orn_xor_commute1(<2 x i4> %a, <2 x i4> %b) {
4057; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute1
4058; CHECK-SAME: (<2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {
4059; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[A]], splat (i4 -1)
4060; CHECK-NEXT:    [[R:%.*]] = and <2 x i4> [[B]], [[TMP1]]
4061; CHECK-NEXT:    ret <2 x i4> [[R]]
4062;
4063  %xor = xor <2 x i4> %a, %b
4064  %nota = xor <2 x i4> %a, <i4 -1, i4 poison>
4065  %or = or <2 x i4> %nota, %b
4066  %r = and <2 x i4> %xor, %or
4067  ret <2 x i4> %r
4068}
4069
4070define i32 @and_orn_xor_commute2(i32 %a, i32 %b) {
4071; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute2
4072; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
4073; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
4074; CHECK-NEXT:    call void @use(i32 [[XOR]])
4075; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4076; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4077; CHECK-NEXT:    ret i32 [[R]]
4078;
4079  %xor = xor i32 %b, %a
4080  call void @use(i32 %xor)
4081  %nota = xor i32 %a, -1
4082  %or = or i32 %nota, %b
4083  %r = and i32 %or, %xor
4084  ret i32 %r
4085}
4086
4087define i32 @and_orn_xor_commute3(i32 %a, i32 %b) {
4088; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute3
4089; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
4090; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4091; CHECK-NEXT:    call void @use(i32 [[NOTA]])
4092; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4093; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4094; CHECK-NEXT:    ret i32 [[R]]
4095;
4096  %xor = xor i32 %b, %a
4097  %nota = xor i32 %a, -1
4098  call void @use(i32 %nota)
4099  %or = or i32 %nota, %b
4100  %r = and i32 %xor, %or
4101  ret i32 %r
4102}
4103
4104define i32 @and_orn_xor_commute5(i32 %pa, i32 %pb) {
4105; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute5
4106; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4107; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4108; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4109; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4110; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOTA]]
4111; CHECK-NEXT:    call void @use(i32 [[OR]])
4112; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4113; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4114; CHECK-NEXT:    ret i32 [[R]]
4115;
4116  %a = mul i32 %pa, %pa
4117  %b = mul i32 %pb, %pb
4118  %xor = xor i32 %a, %b
4119  %nota = xor i32 %a, -1
4120  %or = or i32 %b, %nota
4121  call void @use(i32 %or)
4122  %r = and i32 %or, %xor
4123  ret i32 %r
4124}
4125
4126define i32 @and_orn_xor_commute6(i32 %pa, i32 %pb) {
4127; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute6
4128; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4129; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4130; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4131; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
4132; CHECK-NEXT:    call void @use(i32 [[XOR]])
4133; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4134; CHECK-NEXT:    call void @use(i32 [[NOTA]])
4135; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4136; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4137; CHECK-NEXT:    ret i32 [[R]]
4138;
4139  %a = mul i32 %pa, %pa
4140  %b = mul i32 %pb, %pb
4141  %xor = xor i32 %a, %b
4142  call void @use(i32 %xor)
4143  %nota = xor i32 %a, -1
4144  call void @use(i32 %nota)
4145  %or = or i32 %b, %nota
4146  %r = and i32 %xor, %or
4147  ret i32 %r
4148}
4149
4150define i32 @and_orn_xor_commute7(i32 %pa, i32 %pb) {
4151; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute7
4152; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4153; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4154; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4155; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
4156; CHECK-NEXT:    call void @use(i32 [[XOR]])
4157; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4158; CHECK-NEXT:    call void @use(i32 [[NOTA]])
4159; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOTA]]
4160; CHECK-NEXT:    call void @use(i32 [[OR]])
4161; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4162; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4163; CHECK-NEXT:    ret i32 [[R]]
4164;
4165  %a = mul i32 %pa, %pa
4166  %b = mul i32 %pb, %pb
4167  %xor = xor i32 %b, %a
4168  call void @use(i32 %xor)
4169  %nota = xor i32 %a, -1
4170  call void @use(i32 %nota)
4171  %or = or i32 %b, %nota
4172  call void @use(i32 %or)
4173  %r = and i32 %or, %xor
4174  ret i32 %r
4175}
4176
4177define i32 @and_orn_xor_commute8(i32 %pa, i32 %pb) {
4178; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute8
4179; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4180; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4181; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4182; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4183; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4184; CHECK-NEXT:    ret i32 [[R]]
4185;
4186  %a = mul i32 %pa, %pa
4187  %b = mul i32 %pb, %pb
4188  %xor = xor i32 %b, %a
4189  %nota = xor i32 %a, -1
4190  %or = or i32 %b, %nota
4191  %r = and i32 %xor, %or
4192  ret i32 %r
4193}
4194
4195define i32 @zext_zext_and_uses(i8 %x, i8 %y) {
4196; CHECK-LABEL: define {{[^@]+}}@zext_zext_and_uses
4197; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4198; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i32
4199; CHECK-NEXT:    call void @use(i32 [[ZX]])
4200; CHECK-NEXT:    [[ZY:%.*]] = zext i8 [[Y]] to i32
4201; CHECK-NEXT:    call void @use(i32 [[ZY]])
4202; CHECK-NEXT:    [[R:%.*]] = and i32 [[ZX]], [[ZY]]
4203; CHECK-NEXT:    ret i32 [[R]]
4204;
4205  %zx = zext i8 %x to i32
4206  call void @use(i32 %zx)
4207  %zy = zext i8 %y to i32
4208  call void @use(i32 %zy)
4209  %r = and i32 %zx, %zy
4210  ret i32 %r
4211}
4212
4213define i32 @sext_sext_or_uses(i8 %x, i8 %y) {
4214; CHECK-LABEL: define {{[^@]+}}@sext_sext_or_uses
4215; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4216; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i32
4217; CHECK-NEXT:    call void @use(i32 [[SX]])
4218; CHECK-NEXT:    [[SY:%.*]] = sext i8 [[Y]] to i32
4219; CHECK-NEXT:    call void @use(i32 [[SY]])
4220; CHECK-NEXT:    [[R:%.*]] = or i32 [[SX]], [[SY]]
4221; CHECK-NEXT:    ret i32 [[R]]
4222;
4223  %sx = sext i8 %x to i32
4224  call void @use(i32 %sx)
4225  %sy = sext i8 %y to i32
4226  call void @use(i32 %sy)
4227  %r = or i32 %sx, %sy
4228  ret i32 %r
4229}
4230
4231define i32 @trunc_trunc_xor_uses(i65 %x, i65 %y) {
4232; CHECK-LABEL: define {{[^@]+}}@trunc_trunc_xor_uses
4233; CHECK-SAME: (i65 [[X:%.*]], i65 [[Y:%.*]]) {
4234; CHECK-NEXT:    [[SX:%.*]] = trunc i65 [[X]] to i32
4235; CHECK-NEXT:    call void @use(i32 [[SX]])
4236; CHECK-NEXT:    [[SY:%.*]] = trunc i65 [[Y]] to i32
4237; CHECK-NEXT:    call void @use(i32 [[SY]])
4238; CHECK-NEXT:    [[R:%.*]] = xor i32 [[SX]], [[SY]]
4239; CHECK-NEXT:    ret i32 [[R]]
4240;
4241  %sx = trunc i65 %x to i32
4242  call void @use(i32 %sx)
4243  %sy = trunc i65 %y to i32
4244  call void @use(i32 %sy)
4245  %r = xor i32 %sx, %sy
4246  ret i32 %r
4247}
4248
4249define i16 @and_zext_zext(i8 %x, i4 %y) {
4250; CHECK-LABEL: define {{[^@]+}}@and_zext_zext
4251; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4252; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y]] to i8
4253; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X]], [[TMP1]]
4254; CHECK-NEXT:    [[R:%.*]] = zext nneg i8 [[TMP2]] to i16
4255; CHECK-NEXT:    ret i16 [[R]]
4256;
4257  %zx = zext i8 %x to i16
4258  %zy = zext i4 %y to i16
4259  %r = and i16 %zx, %zy
4260  ret i16 %r
4261}
4262
4263define i16 @or_zext_zext(i8 %x, i4 %y) {
4264; CHECK-LABEL: define {{[^@]+}}@or_zext_zext
4265; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4266; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y]] to i8
4267; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
4268; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
4269; CHECK-NEXT:    ret i16 [[R]]
4270;
4271  %zx = zext i8 %x to i16
4272  %zy = zext i4 %y to i16
4273  %r = or i16 %zy, %zx
4274  ret i16 %r
4275}
4276
4277define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) {
4278; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext
4279; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) {
4280; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i4> [[Y]] to <2 x i8>
4281; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i8> [[X]], [[TMP1]]
4282; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
4283; CHECK-NEXT:    ret <2 x i16> [[R]]
4284;
4285  %zx = zext <2 x i8> %x to <2 x i16>
4286  %zy = zext <2 x i4> %y to <2 x i16>
4287  %r = xor <2 x i16> %zx, %zy
4288  ret <2 x i16> %r
4289}
4290
4291define i16 @and_sext_sext(i8 %x, i4 %y) {
4292; CHECK-LABEL: define {{[^@]+}}@and_sext_sext
4293; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4294; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
4295; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X]], [[TMP1]]
4296; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
4297; CHECK-NEXT:    ret i16 [[R]]
4298;
4299  %sx = sext i8 %x to i16
4300  %sy = sext i4 %y to i16
4301  %r = and i16 %sy, %sx
4302  ret i16 %r
4303}
4304
4305define i16 @or_sext_sext(i8 %x, i4 %y) {
4306; CHECK-LABEL: define {{[^@]+}}@or_sext_sext
4307; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4308; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
4309; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
4310; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
4311; CHECK-NEXT:    ret i16 [[R]]
4312;
4313  %sx = sext i8 %x to i16
4314  %sy = sext i4 %y to i16
4315  %r = or i16 %sx, %sy
4316  ret i16 %r
4317}
4318
4319define i16 @xor_sext_sext(i8 %x, i4 %y) {
4320; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext
4321; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4322; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
4323; CHECK-NEXT:    [[TMP2:%.*]] = xor i8 [[X]], [[TMP1]]
4324; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
4325; CHECK-NEXT:    ret i16 [[R]]
4326;
4327  %sx = sext i8 %x to i16
4328  %sy = sext i4 %y to i16
4329  %r = xor i16 %sx, %sy
4330  ret i16 %r
4331}
4332
4333; negative test - mismatched casts
4334
4335define i16 @and_zext_sext(i8 %x, i4 %y) {
4336; CHECK-LABEL: define {{[^@]+}}@and_zext_sext
4337; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4338; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i16
4339; CHECK-NEXT:    [[SY:%.*]] = sext i4 [[Y]] to i16
4340; CHECK-NEXT:    [[R:%.*]] = and i16 [[ZX]], [[SY]]
4341; CHECK-NEXT:    ret i16 [[R]]
4342;
4343  %zx = zext i8 %x to i16
4344  %sy = sext i4 %y to i16
4345  %r = and i16 %zx, %sy
4346  ret i16 %r
4347}
4348
4349; negative test - don't create an extra instruction
4350
4351define i32 @and_zext_zext_use1(i8 %x, i4 %y) {
4352; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use1
4353; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4354; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i32
4355; CHECK-NEXT:    call void @use(i32 [[ZX]])
4356; CHECK-NEXT:    [[ZY:%.*]] = zext i4 [[Y]] to i32
4357; CHECK-NEXT:    [[R:%.*]] = and i32 [[ZX]], [[ZY]]
4358; CHECK-NEXT:    ret i32 [[R]]
4359;
4360  %zx = zext i8 %x to i32
4361  call void @use(i32 %zx)
4362  %zy = zext i4 %y to i32
4363  %r = and i32 %zx, %zy
4364  ret i32 %r
4365}
4366
4367; negative test - don't create an extra instruction
4368
4369define i32 @or_sext_sext_use1(i8 %x, i4 %y) {
4370; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use1
4371; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4372; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i32
4373; CHECK-NEXT:    [[SY:%.*]] = sext i4 [[Y]] to i32
4374; CHECK-NEXT:    call void @use(i32 [[SY]])
4375; CHECK-NEXT:    [[R:%.*]] = or i32 [[SX]], [[SY]]
4376; CHECK-NEXT:    ret i32 [[R]]
4377;
4378  %sx = sext i8 %x to i32
4379  %sy = sext i4 %y to i32
4380  call void @use(i32 %sy)
4381  %r = or i32 %sx, %sy
4382  ret i32 %r
4383}
4384
4385define i1 @PR56294(i8 %x) {
4386; CHECK-LABEL: define {{[^@]+}}@PR56294
4387; CHECK-SAME: (i8 [[X:%.*]]) {
4388; CHECK-NEXT:    ret i1 false
4389;
4390  %t2 = icmp eq i8 %x, 2
4391  %t3 = and i8 %x, 1
4392  %t4 = zext i1 %t2 to i32
4393  %t5 = zext i8 %t3 to i32
4394  %t6 = and i32 %t4, %t5
4395  %t7 = icmp ne i32 %t6, 0
4396  ret i1 %t7
4397}
4398
4399define i32 @canonicalize_logic_first_or0(i32 %x) {
4400; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0
4401; CHECK-SAME: (i32 [[X:%.*]]) {
4402; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X]], 15
4403; CHECK-NEXT:    [[R:%.*]] = add i32 [[TMP1]], 112
4404; CHECK-NEXT:    ret i32 [[R]]
4405;
4406  %a = add i32 %x, 112 ; 01110000
4407  %r = or i32 %a, 15   ; 00001111
4408  ret i32 %r
4409}
4410
4411define i32 @canonicalize_logic_first_or0_nsw(i32 %x) {
4412; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nsw
4413; CHECK-SAME: (i32 [[X:%.*]]) {
4414; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X]], 15
4415; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 112
4416; CHECK-NEXT:    ret i32 [[R]]
4417;
4418  %a = add nsw i32 %x, 112 ; 01110000
4419  %r = or i32 %a, 15   ; 00001111
4420  ret i32 %r
4421}
4422
4423define i32 @canonicalize_logic_first_or0_nswnuw(i32 %x) {
4424; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nswnuw
4425; CHECK-SAME: (i32 [[X:%.*]]) {
4426; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X]], 15
4427; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[TMP1]], 112
4428; CHECK-NEXT:    ret i32 [[R]]
4429;
4430  %a = add nsw nuw i32 %x, 112 ; 01110000
4431  %r = or i32 %a, 15   ; 00001111
4432  ret i32 %r
4433}
4434
4435define <2 x i32> @canonicalize_logic_first_or_vector0(<2 x i32> %x) {
4436; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0
4437; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4438; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)
4439; CHECK-NEXT:    [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 112)
4440; CHECK-NEXT:    ret <2 x i32> [[R]]
4441;
4442  %a = add <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>
4443  %r = or <2 x i32> <i32 15, i32 15>, %a    ; <0x0000000F, 0x0000000F>
4444  ret <2 x i32> %r
4445}
4446
4447define <2 x i32> @canonicalize_logic_first_or_vector0_nsw(<2 x i32> %x) {
4448; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nsw
4449; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4450; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)
4451; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 112)
4452; CHECK-NEXT:    ret <2 x i32> [[R]]
4453;
4454  %a = add nsw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>
4455  %r = or <2 x i32> <i32 15, i32 15>, %a    ; <0x0000000F, 0x0000000F>
4456  ret <2 x i32> %r
4457}
4458
4459define <2 x i32> @canonicalize_logic_first_or_vector0_nswnuw(<2 x i32> %x) {
4460; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nswnuw
4461; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4462; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)
4463; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 112)
4464; CHECK-NEXT:    ret <2 x i32> [[R]]
4465;
4466  %a = add nsw nuw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>
4467  %r = or <2 x i32> <i32 15, i32 15>, %a    ; <0x0000000F, 0x0000000F>
4468  ret <2 x i32> %r
4469}
4470
4471define <2 x i32> @canonicalize_logic_first_or_vector1(<2 x i32> %x) {
4472; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1
4473; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4474; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4475; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4476; CHECK-NEXT:    ret <2 x i32> [[R]]
4477;
4478  %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4479  %r = or <2 x i32> <i32 32783, i32 2063>, %a           ; <0x0000800F, 0x0000080F>
4480  ret <2 x i32> %r
4481}
4482
4483define <2 x i32> @canonicalize_logic_first_or_vector1_nsw(<2 x i32> %x) {
4484; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nsw
4485; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4486; CHECK-NEXT:    [[A:%.*]] = add nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4487; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4488; CHECK-NEXT:    ret <2 x i32> [[R]]
4489;
4490  %a = add nsw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4491  %r = or <2 x i32> <i32 32783, i32 2063>, %a           ; <0x0000800F, 0x0000080F>
4492  ret <2 x i32> %r
4493}
4494
4495define <2 x i32> @canonicalize_logic_first_or_vector1_nswnuw(<2 x i32> %x) {
4496; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nswnuw
4497; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4498; CHECK-NEXT:    [[A:%.*]] = add nuw nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4499; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4500; CHECK-NEXT:    ret <2 x i32> [[R]]
4501;
4502  %a = add nsw nuw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4503  %r = or <2 x i32> <i32 32783, i32 2063>, %a           ; <0x0000800F, 0x0000080F>
4504  ret <2 x i32> %r
4505}
4506
4507define <2 x i32> @canonicalize_logic_first_or_vector2(<2 x i32> %x) {
4508; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector2
4509; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4510; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640>
4511; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4512; CHECK-NEXT:    ret <2 x i32> [[R]]
4513;
4514  %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8>
4515  %r = or <2 x i32> <i32 32783, i32 2063>, %a             ; <0x0000800F, 0x0000080F>
4516  ret <2 x i32> %r
4517}
4518
4519define i32 @canonicalize_logic_first_or_mult_use1(i32 %x) {
4520; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_mult_use1
4521; CHECK-SAME: (i32 [[X:%.*]]) {
4522; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], 112
4523; CHECK-NEXT:    call void @use(i32 [[A]])
4524; CHECK-NEXT:    [[R:%.*]] = or i32 [[A]], 15
4525; CHECK-NEXT:    ret i32 [[R]]
4526;
4527  %a = add i32 %x, 112 ; 01110000
4528  call void @use(i32 %a)
4529  %r = or i32 %a, 15   ; 00001111
4530  ret i32 %r
4531}
4532
4533define i32 @canonicalize_logic_first_or_bad_constraints2(i32 %x) {
4534; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_bad_constraints2
4535; CHECK-SAME: (i32 [[X:%.*]]) {
4536; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], 112
4537; CHECK-NEXT:    [[R:%.*]] = or i32 [[A]], 16
4538; CHECK-NEXT:    ret i32 [[R]]
4539;
4540  %a = add i32 %x, 112 ; 01110000
4541  %r = or i32 %a, 16   ; 00010000
4542  ret i32 %r
4543}
4544
4545define i8 @canonicalize_logic_first_and0(i8 %x) {
4546; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0
4547; CHECK-SAME: (i8 [[X:%.*]]) {
4548; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -10
4549; CHECK-NEXT:    [[R:%.*]] = add i8 [[TMP1]], 48
4550; CHECK-NEXT:    ret i8 [[R]]
4551;
4552  %b = add i8 %x, 48    ;  00110000
4553  %r = and i8 %b, -10   ;  11110110
4554  ret i8 %r
4555}
4556
4557define i8 @canonicalize_logic_first_and0_nsw(i8 %x) {
4558; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nsw
4559; CHECK-SAME: (i8 [[X:%.*]]) {
4560; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -10
4561; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[TMP1]], 48
4562; CHECK-NEXT:    ret i8 [[R]]
4563;
4564  %b = add nsw i8 %x, 48    ;  00110000
4565  %r = and i8 %b, -10   ;  11110110
4566  ret i8 %r
4567}
4568
4569define i8 @canonicalize_logic_first_and0_nswnuw(i8 %x) {
4570; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nswnuw
4571; CHECK-SAME: (i8 [[X:%.*]]) {
4572; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -10
4573; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i8 [[TMP1]], 48
4574; CHECK-NEXT:    ret i8 [[R]]
4575;
4576  %b = add nsw nuw i8 %x, 48    ;  00110000
4577  %r = and i8 %b, -10   ;  11110110
4578  ret i8 %r
4579}
4580
4581define <2 x i8> @canonicalize_logic_first_and_vector0(<2 x i8> %x) {
4582; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0
4583; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4584; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)
4585; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[TMP1]], splat (i8 48)
4586; CHECK-NEXT:    ret <2 x i8> [[R]]
4587;
4588  %a = add <2 x i8> <i8 48, i8 48>, %x
4589  %r = and <2 x i8> <i8 -10, i8 -10>, %a
4590  ret <2 x i8> %r
4591}
4592
4593define <2 x i8> @canonicalize_logic_first_and_vector0_nsw(<2 x i8> %x) {
4594; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nsw
4595; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4596; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)
4597; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[TMP1]], splat (i8 48)
4598; CHECK-NEXT:    ret <2 x i8> [[R]]
4599;
4600  %a = add nsw <2 x i8> <i8 48, i8 48>, %x
4601  %r = and <2 x i8> <i8 -10, i8 -10>, %a
4602  ret <2 x i8> %r
4603}
4604
4605define <2 x i8> @canonicalize_logic_first_and_vector0_nswnuw(<2 x i8> %x) {
4606; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nswnuw
4607; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4608; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)
4609; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i8> [[TMP1]], splat (i8 48)
4610; CHECK-NEXT:    ret <2 x i8> [[R]]
4611;
4612  %a = add nsw nuw <2 x i8> <i8 48, i8 48>, %x
4613  %r = and <2 x i8> <i8 -10, i8 -10>, %a
4614  ret <2 x i8> %r
4615}
4616
4617; element-wise the constants match constraints
4618define <2 x i8> @canonicalize_logic_first_and_vector1(<2 x i8> %x) {
4619; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector1
4620; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4621; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X]], <i8 48, i8 32>
4622; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 -10, i8 -4>
4623; CHECK-NEXT:    ret <2 x i8> [[R]]
4624;
4625  %a = add <2 x i8> <i8 48, i8 32>, %x
4626  %r = and <2 x i8> <i8 -10, i8 -4>, %a
4627  ret <2 x i8> %r
4628}
4629
4630; elementwise these constants do match constraints needed to canonicalize
4631; logic op first then math op
4632define <2 x i32> @canonicalize_logic_first_and_vector2(<2 x i32> %x) {
4633; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector2
4634; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4635; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], splat (i32 612368384)
4636; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768>
4637; CHECK-NEXT:    ret <2 x i32> [[R]]
4638;
4639  %a = add <2 x i32> <i32 612368384, i32 612368384>, %x ; <0x24800000, 0x24800000>
4640  %r = and <2 x i32> <i32 -65536, i32 -32768>, %a       ; <0xFFFF0000, 0xFFFF8000>
4641  ret <2 x i32> %r
4642}
4643
4644define <2 x i32> @canonicalize_logic_first_and_vector3(<2 x i32> %x) {
4645; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector3
4646; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4647; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 32768, i32 16384>
4648; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768>
4649; CHECK-NEXT:    ret <2 x i32> [[R]]
4650;
4651  %a = add <2 x i32> <i32 32768, i32 16384>, %x   ; <0x00008000, 0x00004000>
4652  %r = and <2 x i32> <i32 -65536, i32 -32768>, %a ; <0xFFFF0000, 0xFFFF8000>
4653  ret <2 x i32> %r
4654}
4655
4656define i8 @canonicalize_logic_first_and_mult_use1(i8 %x) {
4657; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_mult_use1
4658; CHECK-SAME: (i8 [[X:%.*]]) {
4659; CHECK-NEXT:    [[B:%.*]] = add i8 [[X]], 48
4660; CHECK-NEXT:    call void @use_i8(i8 [[B]])
4661; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], -10
4662; CHECK-NEXT:    ret i8 [[R]]
4663;
4664  %b = add i8 %x, 48    ;  00110000
4665  call void @use_i8(i8 %b)
4666  %r = and i8 %b, -10   ;  11110110
4667  ret i8 %r
4668}
4669
4670define i8 @canonicalize_logic_first_and_bad_constraints2(i8 %x) {
4671; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_bad_constraints2
4672; CHECK-SAME: (i8 [[X:%.*]]) {
4673; CHECK-NEXT:    [[B:%.*]] = add i8 [[X]], 48
4674; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], -26
4675; CHECK-NEXT:    ret i8 [[R]]
4676;
4677  %b = add i8 %x, 48    ;  00110000
4678  %r = and i8 %b, -26   ;  11100110
4679  ret i8 %r
4680}
4681
4682define i8 @canonicalize_logic_first_xor_0(i8 %x) {
4683; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0
4684; CHECK-SAME: (i8 [[X:%.*]]) {
4685; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], 31
4686; CHECK-NEXT:    [[R:%.*]] = add i8 [[TMP1]], 96
4687; CHECK-NEXT:    ret i8 [[R]]
4688;
4689  %a = add i8 %x, 96  ; 01100000
4690  %r = xor i8 %a, 31  ; 00011111
4691  ret i8 %r
4692}
4693
4694define i8 @canonicalize_logic_first_xor_0_nsw(i8 %x) {
4695; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nsw
4696; CHECK-SAME: (i8 [[X:%.*]]) {
4697; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], 31
4698; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[TMP1]], 96
4699; CHECK-NEXT:    ret i8 [[R]]
4700;
4701  %a = add nsw i8 %x, 96  ; 01100000
4702  %r = xor i8 %a, 31  ; 00011111
4703  ret i8 %r
4704}
4705
4706define i8 @canonicalize_logic_first_xor_0_nswnuw(i8 %x) {
4707; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nswnuw
4708; CHECK-SAME: (i8 [[X:%.*]]) {
4709; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], 31
4710; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i8 [[TMP1]], 96
4711; CHECK-NEXT:    ret i8 [[R]]
4712;
4713  %a = add nsw nuw i8 %x, 96  ; 01100000
4714  %r = xor i8 %a, 31  ; 00011111
4715  ret i8 %r
4716}
4717
4718define <2 x i32> @canonicalize_logic_first_xor_vector0(<2 x i32> %x) {
4719; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0
4720; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4721; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)
4722; CHECK-NEXT:    [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 -8388608)
4723; CHECK-NEXT:    ret <2 x i32> [[R]]
4724;
4725  %a = add <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>
4726  %r = xor <2 x i32> <i32 32783, i32 32783>, %a       ; <0x0000800F, 0x0000800F>
4727  ret <2 x i32> %r
4728}
4729
4730define <2 x i32> @canonicalize_logic_first_xor_vector0_nsw(<2 x i32> %x) {
4731; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nsw
4732; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4733; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)
4734; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 -8388608)
4735; CHECK-NEXT:    ret <2 x i32> [[R]]
4736;
4737  %a = add nsw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>
4738  %r = xor <2 x i32> <i32 32783, i32 32783>, %a       ; <0x0000800F, 0x0000800F>
4739  ret <2 x i32> %r
4740}
4741
4742define <2 x i32> @canonicalize_logic_first_xor_vector0_nswnuw(<2 x i32> %x) {
4743; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nswnuw
4744; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4745; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)
4746; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 -8388608)
4747; CHECK-NEXT:    ret <2 x i32> [[R]]
4748;
4749  %a = add nsw nuw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>
4750  %r = xor <2 x i32> <i32 32783, i32 32783>, %a       ; <0x0000800F, 0x0000800F>
4751  ret <2 x i32> %r
4752}
4753
4754define <2 x i32> @canonicalize_logic_first_xor_vector1(<2 x i32> %x) {
4755; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector1
4756; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4757; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4758; CHECK-NEXT:    [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063>
4759; CHECK-NEXT:    ret <2 x i32> [[R]]
4760;
4761  %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4762  %r = xor <2 x i32> <i32 32783, i32 2063>, %a          ; <0x0000800F, 0x0000080F>
4763  ret <2 x i32> %r
4764}
4765
4766define <2 x i32> @canonicalize_logic_first_xor_vector2(<2 x i32> %x) {
4767; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector2
4768; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4769; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640>
4770; CHECK-NEXT:    [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063>
4771; CHECK-NEXT:    ret <2 x i32> [[R]]
4772;
4773  %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8>
4774  %r = xor <2 x i32> <i32 32783, i32 2063>, %a            ; <0x0000800F, 0x0000080F>
4775  ret <2 x i32> %r
4776}
4777
4778define i8 @canonicalize_logic_first_xor_mult_use1(i8 %x) {
4779; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_mult_use1
4780; CHECK-SAME: (i8 [[X:%.*]]) {
4781; CHECK-NEXT:    [[A:%.*]] = add i8 [[X]], 96
4782; CHECK-NEXT:    call void @use_i8(i8 [[A]])
4783; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], 31
4784; CHECK-NEXT:    ret i8 [[R]]
4785;
4786  %a = add i8 %x, 96  ; 01100000
4787  call void @use_i8(i8 %a)
4788  %r = xor i8 %a, 31  ; 00011111
4789  ret i8 %r
4790}
4791
4792define i8 @canonicalize_logic_first_xor_bad_constants2(i8 %x) {
4793; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_bad_constants2
4794; CHECK-SAME: (i8 [[X:%.*]]) {
4795; CHECK-NEXT:    [[A:%.*]] = add i8 [[X]], 96
4796; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], 32
4797; CHECK-NEXT:    ret i8 [[R]]
4798;
4799  %a = add i8 %x, 96  ; 01100000
4800  %r = xor i8 %a, 32  ; 00100000
4801  ret i8 %r
4802}
4803
4804@g = external global i8
4805
4806define i32 @canonicalize_logic_first_constexpr(i32 %x) {
4807; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr
4808; CHECK-SAME: (i32 [[X:%.*]]) {
4809; CHECK-NEXT:    [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -10
4810; CHECK-NEXT:    ret i32 [[R]]
4811;
4812  %a = add i32 ptrtoint (ptr @g to i32), 48
4813  %r = and i32 %a, -10
4814  ret i32 %r
4815}
4816
4817define i32 @canonicalize_logic_first_constexpr_nuw(i32 %x) {
4818; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr_nuw
4819; CHECK-SAME: (i32 [[X:%.*]]) {
4820; CHECK-NEXT:    [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -10
4821; CHECK-NEXT:    ret i32 [[R]]
4822;
4823  %a = add nuw i32 ptrtoint (ptr @g to i32), 48
4824  %r = and i32 %a, -10
4825  ret i32 %r
4826}
4827
4828define i1 @test_and_xor_freely_invertable(i32 %x, i32 %y, i1 %z) {
4829; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable
4830; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) {
4831; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X]], [[Y]]
4832; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[Z]]
4833; CHECK-NEXT:    ret i1 [[AND]]
4834;
4835  %cmp = icmp sgt i32 %x, %y
4836  %xor = xor i1 %cmp, %z
4837  %and = and i1 %xor, %z
4838  ret i1 %and
4839}
4840
4841define i1 @test_and_xor_freely_invertable_multiuse(i32 %x, i32 %y, i1 %z) {
4842; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable_multiuse
4843; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) {
4844; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]
4845; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
4846; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[CMP]], true
4847; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Z]], [[TMP1]]
4848; CHECK-NEXT:    ret i1 [[AND]]
4849;
4850  %cmp = icmp sgt i32 %x, %y
4851  call void @use_i1(i1 %cmp)
4852  %xor = xor i1 %cmp, %z
4853  %and = and i1 %xor, %z
4854  ret i1 %and
4855}
4856