[AArch64][NFC] NFC for const vector as Instruction operand (#116790)
[llvm-project.git] / llvm / test / Transforms / InstCombine / and-xor-or.ll
blob5a0890e918ef0f0ee49a96e584c80778ee5d0df5
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
4 declare void @use(i32)
5 declare void @use_i8(i8)
6 declare void @use_i1(i1)
8 ; a & (a ^ b) --> a & ~b
10 define 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]]
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
26 ; a & (b ^ a) --> a & ~b
28 define 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]]
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
44 ; (b ^ a) & a --> a & ~b
46 define 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]]
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
62 ; (a ^ b) & a --> a & ~b
64 define <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]]
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
80 ; It's ok to match a common constant.
81 ; The xor should be a 'not' op (-1 constant).
83 define <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]]
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
95 ; a & (a ^ ~b) --> a & b
97 define 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]]
103   %b2 = xor i32 %b, -1
104   %t2 = xor i32 %a, %b2
105   %t4 = and i32 %t2, %a
106   ret i32 %t4
109 ; a & (a ^ ~b) --> a & b
111 define 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]]
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
126 ; a & ~(a ^ b) --> a & b
128 define 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]]
134   %b2 = xor i32 %b, %a
135   %t2 = xor i32 %b2, -1
136   %t4 = and i32 %t2, %a
137   ret i32 %t4
140 declare i32 @gen32()
141 define 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]]
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
155 ; rdar://10770603
156 ; (x & y) | (x ^ y) -> x | y
158 define 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]]
164   %1 = and i64 %y, %x
165   %2 = xor i64 %y, %x
166   %3 = add i64 %1, %2
167   ret i64 %3
170 ; (x & y) + (x ^ y) -> x | y
172 define 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]]
178   %1 = and i64 %y, %x
179   %2 = xor i64 %y, %x
180   %3 = or i64 %1, %2
181   ret i64 %3
184 ; ((x & y) ^ z) | y -> (z | y)
186 define 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]]
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
203 ; ((y & x) ^ z) | y -> (z | y)
205 define 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]]
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
222 ; (z ^ (x & y)) | y -> (z | y)
224 define 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]]
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
241 ; (z ^ (y & x)) | y -> (z | y)
243 define 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]]
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
260 ; y | ((x & y) ^ z) -> (y | z)
262 define 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]]
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
279 ; y | ((y & x) ^ z) -> (y | z)
281 define 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]]
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
298 ; y | (z ^ (x & y)) -> (y | z)
300 define 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]]
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
317 ; y | (z ^ (y & x)) -> (y | z)
319 define 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]]
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
336 ; w | (z ^ (y & x))
338 define 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]]
346   %1 = and i64 %y, %x
347   %2 = xor i64 %z, %1
348   %3 = or i64 %w, %2
349   ret i64 %3
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.
357 define 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]]
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
372 define 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]]
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
387 define 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:    [[SX:%.*]] = shl i8 [[X]], [[SHAMT]]
392 ; CHECK-NEXT:    [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]
393 ; CHECK-NEXT:    [[A:%.*]] = xor i8 [[Z]], [[SX]]
394 ; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], [[SY]]
395 ; CHECK-NEXT:    ret i8 [[R]]
397   %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
398   %sx = shl i8 %x, %shamt
399   %sy = shl i8 %y, %shamt
400   %a = xor i8 %z, %sx
401   %r = xor i8 %a, %sy
402   ret i8 %r
405 define i8 @and_lshr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
406 ; CHECK-LABEL: define {{[^@]+}}@and_lshr
407 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
408 ; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
409 ; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]
410 ; CHECK-NEXT:    [[SY:%.*]] = lshr i8 [[Y]], [[SHAMT]]
411 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[Z]], [[SX]]
412 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[SY]], [[A]]
413 ; CHECK-NEXT:    ret i8 [[R]]
415   %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
416   %sx = lshr i8 %x, %shamt
417   %sy = lshr i8 %y, %shamt
418   %a = and i8 %z, %sx
419   %r = and i8 %sy, %a
420   ret i8 %r
423 define i8 @or_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {
424 ; CHECK-LABEL: define {{[^@]+}}@or_lshr
425 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
426 ; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X]], [[Y]]
427 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
428 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[TMP2]], [[Z]]
429 ; CHECK-NEXT:    ret i8 [[R]]
431   %sx = lshr i8 %x, %shamt
432   %sy = lshr i8 %y, %shamt
433   %a = or i8 %sx, %z
434   %r = or i8 %sy, %a
435   ret i8 %r
438 define i8 @xor_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {
439 ; CHECK-LABEL: define {{[^@]+}}@xor_lshr
440 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
441 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], [[Y]]
442 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
443 ; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP2]], [[Z]]
444 ; CHECK-NEXT:    ret i8 [[R]]
446   %sx = lshr i8 %x, %shamt
447   %sy = lshr i8 %y, %shamt
448   %a = xor i8 %sx, %z
449   %r = xor i8 %a, %sy
450   ret i8 %r
453 define i8 @and_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
454 ; CHECK-LABEL: define {{[^@]+}}@and_ashr
455 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
456 ; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
457 ; CHECK-NEXT:    [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]]
458 ; CHECK-NEXT:    [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]]
459 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[Z]], [[SX]]
460 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[A]], [[SY]]
461 ; CHECK-NEXT:    ret i8 [[R]]
463   %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
464   %sx = ashr i8 %x, %shamt
465   %sy = ashr i8 %y, %shamt
466   %a = and i8 %z, %sx
467   %r = and i8 %a, %sy
468   ret i8 %r
471 define i8 @or_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
472 ; CHECK-LABEL: define {{[^@]+}}@or_ashr
473 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {
474 ; CHECK-NEXT:    [[Z:%.*]] = sdiv i8 42, [[ZARG]]
475 ; CHECK-NEXT:    [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]]
476 ; CHECK-NEXT:    [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]]
477 ; CHECK-NEXT:    [[A:%.*]] = or i8 [[Z]], [[SX]]
478 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SY]], [[A]]
479 ; CHECK-NEXT:    ret i8 [[R]]
481   %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
482   %sx = ashr i8 %x, %shamt
483   %sy = ashr i8 %y, %shamt
484   %a = or i8 %z, %sx
485   %r = or i8 %sy, %a
486   ret i8 %r
489 define <2 x i8> @xor_ashr(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z, <2 x i8> %shamt) {
490 ; CHECK-LABEL: define {{[^@]+}}@xor_ashr
491 ; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]], <2 x i8> [[SHAMT:%.*]]) {
492 ; CHECK-NEXT:    [[SX:%.*]] = ashr <2 x i8> [[X]], [[SHAMT]]
493 ; CHECK-NEXT:    [[SY:%.*]] = ashr <2 x i8> [[Y]], [[SHAMT]]
494 ; CHECK-NEXT:    [[A:%.*]] = xor <2 x i8> [[SX]], [[Z]]
495 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i8> [[A]], [[SY]]
496 ; CHECK-NEXT:    ret <2 x i8> [[R]]
498   %sx = ashr <2 x i8> %x, %shamt
499   %sy = ashr <2 x i8> %y, %shamt
500   %a = xor <2 x i8> %sx, %z
501   %r = xor <2 x i8> %a, %sy
502   ret <2 x i8> %r
505 ; Negative test - different logic ops
507 define i8 @or_and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
508 ; CHECK-LABEL: define {{[^@]+}}@or_and_shl
509 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
510 ; CHECK-NEXT:    [[SX:%.*]] = shl i8 [[X]], [[SHAMT]]
511 ; CHECK-NEXT:    [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]
512 ; CHECK-NEXT:    [[A:%.*]] = or i8 [[SX]], [[Z]]
513 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[SY]], [[A]]
514 ; CHECK-NEXT:    ret i8 [[R]]
516   %sx = shl i8 %x, %shamt
517   %sy = shl i8 %y, %shamt
518   %a = or i8 %sx, %z
519   %r = and i8 %sy, %a
520   ret i8 %r
523 ; Negative test - different shift ops
525 define i8 @or_lshr_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
526 ; CHECK-LABEL: define {{[^@]+}}@or_lshr_shl
527 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
528 ; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]
529 ; CHECK-NEXT:    [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]
530 ; CHECK-NEXT:    [[A:%.*]] = or i8 [[SX]], [[Z]]
531 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[A]], [[SY]]
532 ; CHECK-NEXT:    ret i8 [[R]]
534   %sx = lshr i8 %x, %shamt
535   %sy = shl i8 %y, %shamt
536   %a = or i8 %sx, %z
537   %r = or i8 %a, %sy
538   ret i8 %r
541 ; Negative test - different shift amounts
543 define i8 @or_lshr_shamt2(i8 %x, i8 %y, i8 %z, i8 %shamt) {
544 ; CHECK-LABEL: define {{[^@]+}}@or_lshr_shamt2
545 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
546 ; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], 5
547 ; CHECK-NEXT:    [[SY:%.*]] = lshr i8 [[Y]], [[SHAMT]]
548 ; CHECK-NEXT:    [[A:%.*]] = or i8 [[SX]], [[Z]]
549 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SY]], [[A]]
550 ; CHECK-NEXT:    ret i8 [[R]]
552   %sx = lshr i8 %x, 5
553   %sy = lshr i8 %y, %shamt
554   %a = or i8 %sx, %z
555   %r = or i8 %sy, %a
556   ret i8 %r
559 ; Negative test - multi-use
561 define i8 @xor_lshr_multiuse(i8 %x, i8 %y, i8 %z, i8 %shamt) {
562 ; CHECK-LABEL: define {{[^@]+}}@xor_lshr_multiuse
563 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {
564 ; CHECK-NEXT:    [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]
565 ; CHECK-NEXT:    [[A:%.*]] = xor i8 [[SX]], [[Z]]
566 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], [[Y]]
567 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]
568 ; CHECK-NEXT:    [[R:%.*]] = xor i8 [[TMP2]], [[Z]]
569 ; CHECK-NEXT:    [[R2:%.*]] = sdiv i8 [[A]], [[R]]
570 ; CHECK-NEXT:    ret i8 [[R2]]
572   %sx = lshr i8 %x, %shamt
573   %sy = lshr i8 %y, %shamt
574   %a = xor i8 %sx, %z
575   %r = xor i8 %a, %sy
576   %r2 = sdiv i8 %a, %r
577   ret i8 %r2
580 ; Reassociate chains of extend(X) | (extend(Y) | Z).
581 ; Check that logical op is performed on a smaller type and then extended.
583 define i64 @sext_or_chain(i64 %a, i16 %b, i16 %c) {
584 ; CHECK-LABEL: define {{[^@]+}}@sext_or_chain
585 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
586 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
587 ; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
588 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
589 ; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
590 ; CHECK-NEXT:    ret i64 [[OR2]]
592   %conv = sext i16 %b to i64
593   %conv2 = sext i16 %c to i64
594   %or = or i64 %a, %conv
595   %or2 = or i64 %or, %conv2
596   ret i64 %or2
599 define i64 @zext_or_chain(i64 %a, i16 %b, i16 %c) {
600 ; CHECK-LABEL: define {{[^@]+}}@zext_or_chain
601 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
602 ; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[B]] to i64
603 ; CHECK-NEXT:    [[CONV2:%.*]] = zext i16 [[C]] to i64
604 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
605 ; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
606 ; CHECK-NEXT:    ret i64 [[OR2]]
608   %conv = zext i16 %b to i64
609   %conv2 = zext i16 %c to i64
610   %or = or i64 %a, %conv
611   %or2 = or i64 %or, %conv2
612   ret i64 %or2
615 define i64 @sext_and_chain(i64 %a, i16 %b, i16 %c) {
616 ; CHECK-LABEL: define {{[^@]+}}@sext_and_chain
617 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
618 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
619 ; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
620 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A]], [[CONV]]
621 ; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]
622 ; CHECK-NEXT:    ret i64 [[AND2]]
624   %conv = sext i16 %b to i64
625   %conv2 = sext i16 %c to i64
626   %and = and i64 %a, %conv
627   %and2 = and i64 %and, %conv2
628   ret i64 %and2
631 define i64 @zext_and_chain(i64 %a, i16 %b, i16 %c) {
632 ; CHECK-LABEL: define {{[^@]+}}@zext_and_chain
633 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
634 ; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[B]] to i64
635 ; CHECK-NEXT:    [[CONV2:%.*]] = zext i16 [[C]] to i64
636 ; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A]], [[CONV]]
637 ; CHECK-NEXT:    [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]
638 ; CHECK-NEXT:    ret i64 [[AND2]]
640   %conv = zext i16 %b to i64
641   %conv2 = zext i16 %c to i64
642   %and = and i64 %a, %conv
643   %and2 = and i64 %and, %conv2
644   ret i64 %and2
647 define i64 @sext_xor_chain(i64 %a, i16 %b, i16 %c) {
648 ; CHECK-LABEL: define {{[^@]+}}@sext_xor_chain
649 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
650 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
651 ; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
652 ; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[A]], [[CONV]]
653 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]
654 ; CHECK-NEXT:    ret i64 [[XOR2]]
656   %conv = sext i16 %b to i64
657   %conv2 = sext i16 %c to i64
658   %xor = xor i64 %a, %conv
659   %xor2 = xor i64 %xor, %conv2
660   ret i64 %xor2
663 define i64 @zext_xor_chain(i64 %a, i16 %b, i16 %c) {
664 ; CHECK-LABEL: define {{[^@]+}}@zext_xor_chain
665 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {
666 ; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[B]] to i64
667 ; CHECK-NEXT:    [[CONV2:%.*]] = zext i16 [[C]] to i64
668 ; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[A]], [[CONV]]
669 ; CHECK-NEXT:    [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]
670 ; CHECK-NEXT:    ret i64 [[XOR2]]
672   %conv = zext i16 %b to i64
673   %conv2 = zext i16 %c to i64
674   %xor = xor i64 %a, %conv
675   %xor2 = xor i64 %xor, %conv2
676   ret i64 %xor2
679 ; Negative test with more uses.
680 define i64 @sext_or_chain_two_uses1(i64 %a, i16 %b, i16 %c, i64 %d) {
681 ; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses1
682 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) {
683 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
684 ; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
685 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
686 ; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
687 ; CHECK-NEXT:    [[USE:%.*]] = udiv i64 [[OR]], [[D]]
688 ; CHECK-NEXT:    [[RETVAL:%.*]] = udiv i64 [[OR2]], [[USE]]
689 ; CHECK-NEXT:    ret i64 [[RETVAL]]
691   %conv = sext i16 %b to i64
692   %conv2 = sext i16 %c to i64
693   ; %or has two uses
694   %or = or i64 %a, %conv
695   %or2 = or i64 %or, %conv2
696   %use = udiv i64 %or, %d
697   %retval = udiv i64 %or2, %use
698   ret i64 %retval
700 define i64 @sext_or_chain_two_uses2(i64 %a, i16 %b, i16 %c, i64 %d) {
701 ; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses2
702 ; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) {
703 ; CHECK-NEXT:    [[CONV:%.*]] = sext i16 [[B]] to i64
704 ; CHECK-NEXT:    [[CONV2:%.*]] = sext i16 [[C]] to i64
705 ; CHECK-NEXT:    [[OR:%.*]] = or i64 [[A]], [[CONV]]
706 ; CHECK-NEXT:    [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
707 ; CHECK-NEXT:    [[USE1:%.*]] = udiv i64 [[OR2]], [[D]]
708 ; CHECK-NEXT:    [[USE2:%.*]] = udiv i64 [[OR2]], [[USE1]]
709 ; CHECK-NEXT:    ret i64 [[USE2]]
711   %conv = sext i16 %b to i64
712   %conv2 = sext i16 %c to i64
713   %or = or i64 %a, %conv
714   ; %or2 has two uses
715   %or2 = or i64 %or, %conv2
716   %use1 = udiv i64 %or2, %d
717   %use2 = udiv i64 %or2, %use1
718   ret i64 %use2
721 ; (a & ~b) & ~c --> a & ~(b | c)
723 define i32 @not_and_and_not(i32 %a0, i32 %b, i32 %c) {
724 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_not
725 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
726 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
727 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B]], [[C]]
728 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
729 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
730 ; CHECK-NEXT:    ret i32 [[AND2]]
732   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
733   %not1 = xor i32 %b, -1
734   %not2 = xor i32 %c, -1
735   %and1 = and i32 %a, %not1
736   %and2 = and i32 %and1, %not2
737   ret i32 %and2
740 define <4 x i64> @not_and_and_not_4i64(<4 x i64> %a0, <4 x i64> %b, <4 x i64> %c) {
741 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_4i64
742 ; CHECK-SAME: (<4 x i64> [[A0:%.*]], <4 x i64> [[B:%.*]], <4 x i64> [[C:%.*]]) {
743 ; CHECK-NEXT:    [[A:%.*]] = sdiv <4 x i64> splat (i64 42), [[A0]]
744 ; CHECK-NEXT:    [[TMP1:%.*]] = or <4 x i64> [[B]], [[C]]
745 ; CHECK-NEXT:    [[TMP2:%.*]] = xor <4 x i64> [[TMP1]], splat (i64 -1)
746 ; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i64> [[A]], [[TMP2]]
747 ; CHECK-NEXT:    ret <4 x i64> [[AND2]]
749   %a = sdiv <4 x i64> <i64 42, i64 42, i64 42, i64 42>, %a0 ; thwart complexity-based canonicalization
750   %not1 = xor <4 x i64> %b, <i64 -1, i64 -1, i64 -1, i64 -1>
751   %not2 = xor <4 x i64> %c, <i64 -1, i64 -1, i64 -1, i64 -1>
752   %and1 = and <4 x i64> %a, %not1
753   %and2 = and <4 x i64> %and1, %not2
754   ret <4 x i64> %and2
757 ; (~b & a) & ~c --> a & ~(b | c)
759 define i32 @not_and_and_not_commute1(i32 %a, i32 %b, i32 %c) {
760 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute1
761 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
762 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B]], [[C]]
763 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
764 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
765 ; CHECK-NEXT:    ret i32 [[AND2]]
767   %not1 = xor i32 %b, -1
768   %not2 = xor i32 %c, -1
769   %and1 = and i32 %not1, %a
770   %and2 = and i32 %and1, %not2
771   ret i32 %and2
774 ; ~c & (a & ~b) --> a & ~(b | c)
776 define i32 @not_and_and_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {
777 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute2_extra_not_use
778 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
779 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
780 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
781 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B]], [[C]]
782 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
783 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
784 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
785 ; CHECK-NEXT:    ret i32 [[AND2]]
787   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
788   %not1 = xor i32 %b, -1
789   %not2 = xor i32 %c, -1
790   %and1 = and i32 %a, %not1
791   %and2 = and i32 %not2, %and1
792   call void @use(i32 %not2)
793   ret i32 %and2
796 define i32 @not_and_and_not_extra_and1_use(i32 %a0, i32 %b, i32 %c) {
797 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_extra_and1_use
798 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
799 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
800 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[B]], -1
801 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
802 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
803 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[NOT2]]
804 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
805 ; CHECK-NEXT:    ret i32 [[AND2]]
807   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
808   %not1 = xor i32 %b, -1
809   %not2 = xor i32 %c, -1
810   %and1 = and i32 %a, %not1
811   %and2 = and i32 %and1, %not2
812   call void @use(i32 %and1)
813   ret i32 %and2
816 ; (a | ~b) | ~c --> a | ~(b & c)
818 define i32 @not_or_or_not(i32 %a0, i32 %b, i32 %c) {
819 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_not
820 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
821 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
822 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C]]
823 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
824 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
825 ; CHECK-NEXT:    ret i32 [[OR2]]
827   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
828   %not1 = xor i32 %b, -1
829   %not2 = xor i32 %c, -1
830   %or1 = or i32 %a, %not1
831   %or2 = or i32 %or1, %not2
832   ret i32 %or2
835 define <2 x i6> @not_or_or_not_2i6(<2 x i6> %a0, <2 x i6> %b, <2 x i6> %c) {
836 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_2i6
837 ; CHECK-SAME: (<2 x i6> [[A0:%.*]], <2 x i6> [[B:%.*]], <2 x i6> [[C:%.*]]) {
838 ; CHECK-NEXT:    [[A:%.*]] = sdiv <2 x i6> splat (i6 3), [[A0]]
839 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i6> [[B]], [[C]]
840 ; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i6> [[TMP1]], splat (i6 -1)
841 ; CHECK-NEXT:    [[OR2:%.*]] = or <2 x i6> [[A]], [[TMP2]]
842 ; CHECK-NEXT:    ret <2 x i6> [[OR2]]
844   %a = sdiv <2 x i6> <i6 3, i6 3>, %a0 ; thwart complexity-based canonicalization
845   %not1 = xor <2 x i6> %b, <i6 -1, i6 -1>
846   %not2 = xor <2 x i6> %c, <i6 -1, i6 poison>
847   %or1 = or <2 x i6> %a, %not1
848   %or2 = or <2 x i6> %or1, %not2
849   ret <2 x i6> %or2
852 ; (~b | a) | ~c --> a | ~(b & c)
854 define i32 @not_or_or_not_commute1(i32 %a, i32 %b, i32 %c) {
855 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute1
856 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
857 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C]]
858 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
859 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
860 ; CHECK-NEXT:    ret i32 [[OR2]]
862   %not1 = xor i32 %b, -1
863   %not2 = xor i32 %c, -1
864   %or1 = or i32 %not1, %a
865   %or2 = or i32 %or1, %not2
866   ret i32 %or2
869 ; ~c | (a | ~b) --> a | ~(b & c)
871 define i32 @not_or_or_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {
872 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute2_extra_not_use
873 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
874 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
875 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
876 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C]]
877 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], -1
878 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
879 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
880 ; CHECK-NEXT:    ret i32 [[OR2]]
882   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
883   %not1 = xor i32 %b, -1
884   %not2 = xor i32 %c, -1
885   %or1 = or i32 %a, %not1
886   %or2 = or i32 %not2, %or1
887   call void @use(i32 %not2)
888   ret i32 %or2
891 define i32 @not_or_or_not_extra_or1_use(i32 %a0, i32 %b, i32 %c) {
892 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_extra_or1_use
893 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
894 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
895 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[B]], -1
896 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[C]], -1
897 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
898 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[NOT2]]
899 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
900 ; CHECK-NEXT:    ret i32 [[OR2]]
902   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
903   %not1 = xor i32 %b, -1
904   %not2 = xor i32 %c, -1
905   %or1 = or i32 %a, %not1
906   %or2 = or i32 %or1, %not2
907   call void @use(i32 %or1)
908   ret i32 %or2
911 ; (c & ~(a | b)) | (b & ~(a | c)) --> ~a & (b ^ c)
913 define i32 @or_not_and(i32 %a, i32 %b, i32 %c) {
914 ; CHECK-LABEL: define {{[^@]+}}@or_not_and
915 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
916 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
917 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
918 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
919 ; CHECK-NEXT:    ret i32 [[OR3]]
921   %or1 = or i32 %a, %b
922   %not1 = xor i32 %or1, -1
923   %and1 = and i32 %not1, %c
924   %or2 = or i32 %a, %c
925   %not2 = xor i32 %or2, -1
926   %and2 = and i32 %not2, %b
927   %or3 = or i32 %and1, %and2
928   ret i32 %or3
931 define i32 @or_not_and_commute1(i32 %a, i32 %b0, i32 %c) {
932 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute1
933 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
934 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
935 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
936 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
937 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
938 ; CHECK-NEXT:    ret i32 [[OR3]]
940   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
941   %or1 = or i32 %a, %b
942   %not1 = xor i32 %or1, -1
943   %and1 = and i32 %not1, %c
944   %or2 = or i32 %a, %c
945   %not2 = xor i32 %or2, -1
946   %and2 = and i32 %b, %not2
947   %or3 = or i32 %and1, %and2
948   ret i32 %or3
951 define i32 @or_not_and_commute2(i32 %a, i32 %b0, i32 %c) {
952 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute2
953 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
954 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
955 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
956 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
957 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
958 ; CHECK-NEXT:    ret i32 [[OR3]]
960   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
961   %or1 = or i32 %a, %b
962   %not1 = xor i32 %or1, -1
963   %and1 = and i32 %not1, %c
964   %or2 = or i32 %a, %c
965   %not2 = xor i32 %or2, -1
966   %and2 = and i32 %b, %not2
967   %or3 = or i32 %and2, %and1
968   ret i32 %or3
971 define i32 @or_not_and_commute3(i32 %a, i32 %b, i32 %c) {
972 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute3
973 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
974 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
975 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
976 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
977 ; CHECK-NEXT:    ret i32 [[OR3]]
979   %or1 = or i32 %b, %a
980   %not1 = xor i32 %or1, -1
981   %and1 = and i32 %not1, %c
982   %or2 = or i32 %c, %a
983   %not2 = xor i32 %or2, -1
984   %and2 = and i32 %not2, %b
985   %or3 = or i32 %and1, %and2
986   ret i32 %or3
989 define i32 @or_not_and_commute4(i32 %a, i32 %b, i32 %c0) {
990 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute4
991 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
992 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
993 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
994 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
995 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
996 ; CHECK-NEXT:    ret i32 [[OR3]]
998   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
999   %or1 = or i32 %a, %b
1000   %not1 = xor i32 %or1, -1
1001   %and1 = and i32 %c, %not1
1002   %or2 = or i32 %a, %c
1003   %not2 = xor i32 %or2, -1
1004   %and2 = and i32 %not2, %b
1005   %or3 = or i32 %and1, %and2
1006   ret i32 %or3
1009 define i32 @or_not_and_commute5(i32 %a0, i32 %b, i32 %c0) {
1010 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute5
1011 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1012 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1013 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1014 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1015 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1016 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1017 ; CHECK-NEXT:    ret i32 [[OR3]]
1019   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1020   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1021   %or1 = or i32 %a, %b
1022   %not1 = xor i32 %or1, -1
1023   %and1 = and i32 %c, %not1
1024   %or2 = or i32 %a, %c
1025   %not2 = xor i32 %or2, -1
1026   %and2 = and i32 %not2, %b
1027   %or3 = or i32 %and1, %and2
1028   ret i32 %or3
1031 define i32 @or_not_and_commute6(i32 %a, i32 %b, i32 %c) {
1032 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute6
1033 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1034 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1035 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1036 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1037 ; CHECK-NEXT:    ret i32 [[OR3]]
1039   %or1 = or i32 %a, %b
1040   %not1 = xor i32 %or1, -1
1041   %and1 = and i32 %not1, %c
1042   %or2 = or i32 %c, %a
1043   %not2 = xor i32 %or2, -1
1044   %and2 = and i32 %not2, %b
1045   %or3 = or i32 %and1, %and2
1046   ret i32 %or3
1049 define i32 @or_not_and_commute7(i32 %a, i32 %b, i32 %c) {
1050 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute7
1051 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1052 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1053 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1054 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1055 ; CHECK-NEXT:    ret i32 [[OR3]]
1057   %or1 = or i32 %b, %a
1058   %not1 = xor i32 %or1, -1
1059   %and1 = and i32 %not1, %c
1060   %or2 = or i32 %a, %c
1061   %not2 = xor i32 %or2, -1
1062   %and2 = and i32 %not2, %b
1063   %or3 = or i32 %and1, %and2
1064   ret i32 %or3
1067 define i32 @or_not_and_commute8(i32 %a0, i32 %b0, i32 %c) {
1068 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute8
1069 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1070 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1071 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1072 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1073 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1074 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1075 ; CHECK-NEXT:    ret i32 [[OR3]]
1077   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1078   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1079   %or1 = or i32 %a, %b
1080   %not1 = xor i32 %or1, -1
1081   %and1 = and i32 %not1, %c
1082   %or2 = or i32 %c, %a
1083   %not2 = xor i32 %or2, -1
1084   %and2 = and i32 %b, %not2
1085   %or3 = or i32 %and1, %and2
1086   ret i32 %or3
1089 define i32 @or_not_and_commute9(i32 %a0, i32 %b0, i32 %c0) {
1090 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute9
1091 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) {
1092 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1093 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1094 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
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]]
1100   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1101   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1102   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1103   %or1 = or i32 %a, %b
1104   %not1 = xor i32 %or1, -1
1105   %and1 = and i32 %not1, %c
1106   %or2 = or i32 %a, %c
1107   %not2 = xor i32 %or2, -1
1108   %and2 = and i32 %b, %not2
1109   %or3 = or i32 %and1, %and2
1110   ret i32 %or3
1113 define i32 @or_not_and_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1114 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use1
1115 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1116 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1117 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1118 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1119 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1120 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1121 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
1122 ; CHECK-NEXT:    ret i32 [[OR3]]
1124   %or1 = or i32 %a, %b
1125   %not1 = xor i32 %or1, -1
1126   %and1 = and i32 %not1, %c
1127   %or2 = or i32 %a, %c
1128   %not2 = xor i32 %or2, -1
1129   %and2 = and i32 %not2, %b
1130   %or3 = or i32 %and1, %and2
1131   call void @use(i32 %not1)
1132   ret i32 %or3
1135 define i32 @or_not_and_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1136 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use2
1137 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1138 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1139 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1140 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1141 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1142 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1143 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[B]], [[NOT2]]
1144 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1145 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
1146 ; CHECK-NEXT:    ret i32 [[OR3]]
1148   %or1 = or i32 %a, %b
1149   %not1 = xor i32 %or1, -1
1150   %and1 = and i32 %not1, %c
1151   %or2 = or i32 %a, %c
1152   %not2 = xor i32 %or2, -1
1153   %and2 = and i32 %not2, %b
1154   %or3 = or i32 %and1, %and2
1155   call void @use(i32 %not2)
1156   ret i32 %or3
1159 define i32 @or_not_and_extra_and_use1(i32 %a, i32 %b, i32 %c) {
1160 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use1
1161 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1162 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1163 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1164 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1165 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1166 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1167 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1168 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
1169 ; CHECK-NEXT:    ret i32 [[OR3]]
1171   %or1 = or i32 %a, %b
1172   %not1 = xor i32 %or1, -1
1173   %and1 = and i32 %not1, %c
1174   %or2 = or i32 %a, %c
1175   %not2 = xor i32 %or2, -1
1176   %and2 = and i32 %not2, %b
1177   %or3 = or i32 %and1, %and2
1178   call void @use(i32 %and1)
1179   ret i32 %or3
1182 define i32 @or_not_and_extra_and_use2(i32 %a, i32 %b, i32 %c) {
1183 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use2
1184 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1185 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1186 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1187 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1188 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1189 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1190 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[B]], [[NOT2]]
1191 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1192 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
1193 ; CHECK-NEXT:    ret i32 [[OR3]]
1195   %or1 = or i32 %a, %b
1196   %not1 = xor i32 %or1, -1
1197   %and1 = and i32 %not1, %c
1198   %or2 = or i32 %a, %c
1199   %not2 = xor i32 %or2, -1
1200   %and2 = and i32 %not2, %b
1201   %or3 = or i32 %and1, %and2
1202   call void @use(i32 %and2)
1203   ret i32 %or3
1206 define i32 @or_not_and_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1207 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use1
1208 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1209 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1210 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1211 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1212 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1213 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
1214 ; CHECK-NEXT:    ret i32 [[OR3]]
1216   %or1 = or i32 %a, %b
1217   %not1 = xor i32 %or1, -1
1218   %and1 = and i32 %not1, %c
1219   %or2 = or i32 %a, %c
1220   %not2 = xor i32 %or2, -1
1221   %and2 = and i32 %not2, %b
1222   %or3 = or i32 %and1, %and2
1223   call void @use(i32 %or1)
1224   ret i32 %or3
1227 define i32 @or_not_and_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1228 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use2
1229 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1230 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1231 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1232 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[A]], -1
1233 ; CHECK-NEXT:    [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1234 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
1235 ; CHECK-NEXT:    ret i32 [[OR3]]
1237   %or1 = or i32 %a, %b
1238   %not1 = xor i32 %or1, -1
1239   %and1 = and i32 %not1, %c
1240   %or2 = or i32 %a, %c
1241   %not2 = xor i32 %or2, -1
1242   %and2 = and i32 %not2, %b
1243   %or3 = or i32 %and1, %and2
1244   call void @use(i32 %or2)
1245   ret i32 %or3
1248 define i32 @or_not_and_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {
1249 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_c
1250 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1251 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1252 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1253 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1254 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[D]]
1255 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1256 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[B]], [[NOT2]]
1257 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1258 ; CHECK-NEXT:    ret i32 [[OR3]]
1260   %or1 = or i32 %a, %b
1261   %not1 = xor i32 %or1, -1
1262   %and1 = and i32 %not1, %c
1263   %or2 = or i32 %a, %d
1264   %not2 = xor i32 %or2, -1
1265   %and2 = and i32 %not2, %b
1266   %or3 = or i32 %and1, %and2
1267   ret i32 %or3
1270 define i32 @or_not_and_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1271 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_b
1272 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1273 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[B]]
1274 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1275 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[NOT1]]
1276 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1277 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1278 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[D]], [[NOT2]]
1279 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1280 ; CHECK-NEXT:    ret i32 [[OR3]]
1282   %or1 = or i32 %a, %b
1283   %not1 = xor i32 %or1, -1
1284   %and1 = and i32 %not1, %c
1285   %or2 = or i32 %a, %c
1286   %not2 = xor i32 %or2, -1
1287   %and2 = and i32 %not2, %d
1288   %or3 = or i32 %and1, %and2
1289   ret i32 %or3
1292 ; (c | ~(a & b)) & (b | ~(a & c)) --> ~(a & (b ^ c))
1294 define i32 @and_not_or(i32 %a, i32 %b, i32 %c) {
1295 ; CHECK-LABEL: define {{[^@]+}}@and_not_or
1296 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1297 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1298 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1299 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1300 ; CHECK-NEXT:    ret i32 [[AND3]]
1302   %and1 = and i32 %a, %b
1303   %not1 = xor i32 %and1, -1
1304   %or1 = or i32 %not1, %c
1305   %and2 = and i32 %a, %c
1306   %not2 = xor i32 %and2, -1
1307   %or2 = or i32 %not2, %b
1308   %and3 = and i32 %or1, %or2
1309   ret i32 %and3
1312 define i32 @and_not_or_commute1(i32 %a, i32 %b0, i32 %c) {
1313 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute1
1314 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1315 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1316 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1317 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1318 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1319 ; CHECK-NEXT:    ret i32 [[AND3]]
1321   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1322   %and1 = and i32 %a, %b
1323   %not1 = xor i32 %and1, -1
1324   %or1 = or i32 %not1, %c
1325   %and2 = and i32 %a, %c
1326   %not2 = xor i32 %and2, -1
1327   %or2 = or i32 %b, %not2
1328   %and3 = and i32 %or1, %or2
1329   ret i32 %and3
1332 define i32 @and_not_or_commute2(i32 %a, i32 %b0, i32 %c) {
1333 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute2
1334 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1335 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1336 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
1337 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1338 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1339 ; CHECK-NEXT:    ret i32 [[AND3]]
1341   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1342   %and1 = and i32 %a, %b
1343   %not1 = xor i32 %and1, -1
1344   %or1 = or i32 %not1, %c
1345   %and2 = and i32 %a, %c
1346   %not2 = xor i32 %and2, -1
1347   %or2 = or i32 %b, %not2
1348   %and3 = and i32 %or2, %or1
1349   ret i32 %and3
1352 define i32 @and_not_or_commute3(i32 %a, i32 %b, i32 %c) {
1353 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute3
1354 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1355 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1356 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1357 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1358 ; CHECK-NEXT:    ret i32 [[AND3]]
1360   %and1 = and i32 %b, %a
1361   %not1 = xor i32 %and1, -1
1362   %or1 = or i32 %not1, %c
1363   %and2 = and i32 %c, %a
1364   %not2 = xor i32 %and2, -1
1365   %or2 = or i32 %not2, %b
1366   %and3 = and i32 %or1, %or2
1367   ret i32 %and3
1370 define i32 @and_not_or_commute4(i32 %a, i32 %b, i32 %c0) {
1371 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute4
1372 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1373 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1374 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1375 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1376 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1377 ; CHECK-NEXT:    ret i32 [[AND3]]
1379   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1380   %and1 = and i32 %a, %b
1381   %not1 = xor i32 %and1, -1
1382   %or1 = or i32 %c, %not1
1383   %and2 = and i32 %a, %c
1384   %not2 = xor i32 %and2, -1
1385   %or2 = or i32 %not2, %b
1386   %and3 = and i32 %or1, %or2
1387   ret i32 %and3
1390 define i32 @and_not_or_commute5(i32 %a0, i32 %b, i32 %c0) {
1391 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute5
1392 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
1393 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1394 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
1395 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1396 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1397 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1398 ; CHECK-NEXT:    ret i32 [[AND3]]
1400   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1401   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1402   %and1 = and i32 %a, %b
1403   %not1 = xor i32 %and1, -1
1404   %or1 = or i32 %c, %not1
1405   %and2 = and i32 %a, %c
1406   %not2 = xor i32 %and2, -1
1407   %or2 = or i32 %not2, %b
1408   %and3 = and i32 %or1, %or2
1409   ret i32 %and3
1412 define i32 @and_not_or_commute6(i32 %a, i32 %b, i32 %c) {
1413 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute6
1414 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1415 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1416 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1417 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1418 ; CHECK-NEXT:    ret i32 [[AND3]]
1420   %and1 = and i32 %a, %b
1421   %not1 = xor i32 %and1, -1
1422   %or1 = or i32 %not1, %c
1423   %and2 = and i32 %c, %a
1424   %not2 = xor i32 %and2, -1
1425   %or2 = or i32 %not2, %b
1426   %and3 = and i32 %or1, %or2
1427   ret i32 %and3
1430 define i32 @and_not_or_commute7(i32 %a, i32 %b, i32 %c) {
1431 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute7
1432 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1433 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1434 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1435 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1436 ; CHECK-NEXT:    ret i32 [[AND3]]
1438   %and1 = and i32 %b, %a
1439   %not1 = xor i32 %and1, -1
1440   %or1 = or i32 %not1, %c
1441   %and2 = and i32 %a, %c
1442   %not2 = xor i32 %and2, -1
1443   %or2 = or i32 %not2, %b
1444   %and3 = and i32 %or1, %or2
1445   ret i32 %and3
1448 define i32 @and_not_or_commute8(i32 %a0, i32 %b0, i32 %c) {
1449 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute8
1450 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1451 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1452 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1453 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1454 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1455 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1456 ; CHECK-NEXT:    ret i32 [[AND3]]
1458   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1459   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1460   %and1 = and i32 %a, %b
1461   %not1 = xor i32 %and1, -1
1462   %or1 = or i32 %not1, %c
1463   %and2 = and i32 %c, %a
1464   %not2 = xor i32 %and2, -1
1465   %or2 = or i32 %b, %not2
1466   %and3 = and i32 %or1, %or2
1467   ret i32 %and3
1470 define i32 @and_not_or_commute9(i32 %a0, i32 %b0, i32 %c0) {
1471 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute9
1472 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) {
1473 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
1474 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1475 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
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]]
1481   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1482   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1483   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1484   %and1 = and i32 %a, %b
1485   %not1 = xor i32 %and1, -1
1486   %or1 = or i32 %not1, %c
1487   %and2 = and i32 %a, %c
1488   %not2 = xor i32 %and2, -1
1489   %or2 = or i32 %b, %not2
1490   %and3 = and i32 %or1, %or2
1491   ret i32 %and3
1494 define i32 @and_not_or_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1495 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use1
1496 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1497 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1498 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1499 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1500 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1501 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1502 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
1503 ; CHECK-NEXT:    ret i32 [[AND3]]
1505   %and1 = and i32 %a, %b
1506   %not1 = xor i32 %and1, -1
1507   %or1 = or i32 %not1, %c
1508   %and2 = and i32 %a, %c
1509   %not2 = xor i32 %and2, -1
1510   %or2 = or i32 %not2, %b
1511   %and3 = and i32 %or1, %or2
1512   call void @use(i32 %not1)
1513   ret i32 %and3
1516 define i32 @and_not_or_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1517 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use2
1518 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1519 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1520 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1521 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1522 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1523 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1524 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[B]], [[NOT2]]
1525 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1526 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
1527 ; CHECK-NEXT:    ret i32 [[AND3]]
1529   %and1 = and i32 %a, %b
1530   %not1 = xor i32 %and1, -1
1531   %or1 = or i32 %not1, %c
1532   %and2 = and i32 %a, %c
1533   %not2 = xor i32 %and2, -1
1534   %or2 = or i32 %not2, %b
1535   %and3 = and i32 %or1, %or2
1536   call void @use(i32 %not2)
1537   ret i32 %and3
1540 define i32 @and_not_or_extra_and_use1(i32 %a, i32 %b, i32 %c) {
1541 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use1
1542 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1543 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1544 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1545 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1546 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1547 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1548 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1549 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
1550 ; CHECK-NEXT:    ret i32 [[AND3]]
1552   %and1 = and i32 %a, %b
1553   %not1 = xor i32 %and1, -1
1554   %or1 = or i32 %not1, %c
1555   %and2 = and i32 %a, %c
1556   %not2 = xor i32 %and2, -1
1557   %or2 = or i32 %not2, %b
1558   %and3 = and i32 %or1, %or2
1559   call void @use(i32 %or1)
1560   ret i32 %and3
1563 define i32 @and_not_or_extra_and_use2(i32 %a, i32 %b, i32 %c) {
1564 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use2
1565 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1566 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1567 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1568 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1569 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1570 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1571 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[B]], [[NOT2]]
1572 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1573 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
1574 ; CHECK-NEXT:    ret i32 [[AND3]]
1576   %and1 = and i32 %a, %b
1577   %not1 = xor i32 %and1, -1
1578   %or1 = or i32 %not1, %c
1579   %and2 = and i32 %a, %c
1580   %not2 = xor i32 %and2, -1
1581   %or2 = or i32 %not2, %b
1582   %and3 = and i32 %or1, %or2
1583   call void @use(i32 %or2)
1584   ret i32 %and3
1587 define i32 @and_not_or_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1588 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use1
1589 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1590 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1591 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1592 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1593 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1594 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
1595 ; CHECK-NEXT:    ret i32 [[AND3]]
1597   %and1 = and i32 %a, %b
1598   %not1 = xor i32 %and1, -1
1599   %or1 = or i32 %not1, %c
1600   %and2 = and i32 %a, %c
1601   %not2 = xor i32 %and2, -1
1602   %or2 = or i32 %not2, %b
1603   %and3 = and i32 %or1, %or2
1604   call void @use(i32 %and1)
1605   ret i32 %and3
1608 define i32 @and_not_or_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1609 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use2
1610 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1611 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1612 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1613 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1614 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1615 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
1616 ; CHECK-NEXT:    ret i32 [[AND3]]
1618   %and1 = and i32 %a, %b
1619   %not1 = xor i32 %and1, -1
1620   %or1 = or i32 %not1, %c
1621   %and2 = and i32 %a, %c
1622   %not2 = xor i32 %and2, -1
1623   %or2 = or i32 %not2, %b
1624   %and3 = and i32 %or1, %or2
1625   call void @use(i32 %and2)
1626   ret i32 %and3
1629 define i32 @and_not_or_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {
1630 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_c
1631 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1632 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1633 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1634 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1635 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[D]]
1636 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1637 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[B]], [[NOT2]]
1638 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1639 ; CHECK-NEXT:    ret i32 [[AND3]]
1641   %and1 = and i32 %a, %b
1642   %not1 = xor i32 %and1, -1
1643   %or1 = or i32 %not1, %c
1644   %and2 = and i32 %a, %d
1645   %not2 = xor i32 %and2, -1
1646   %or2 = or i32 %not2, %b
1647   %and3 = and i32 %or1, %or2
1648   ret i32 %and3
1651 define i32 @and_not_or_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1652 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_b
1653 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1654 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[B]]
1655 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
1656 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[NOT1]]
1657 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
1658 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
1659 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[D]], [[NOT2]]
1660 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1661 ; CHECK-NEXT:    ret i32 [[AND3]]
1663   %and1 = and i32 %a, %b
1664   %not1 = xor i32 %and1, -1
1665   %or1 = or i32 %not1, %c
1666   %and2 = and i32 %a, %c
1667   %not2 = xor i32 %and2, -1
1668   %or2 = or i32 %not2, %d
1669   %and3 = and i32 %or1, %or2
1670   ret i32 %and3
1673 ; (b & ~(a | c)) | ~(a | b) --> ~((b & c) | a)
1675 define i32 @or_and_not_not(i32 %a, i32 %b, i32 %c) {
1676 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not
1677 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1678 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1679 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1680 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1681 ; CHECK-NEXT:    ret i32 [[OR3]]
1683   %or1 = or i32 %b, %a
1684   %not1 = xor i32 %or1, -1
1685   %or2 = or i32 %a, %c
1686   %not2 = xor i32 %or2, -1
1687   %and = and i32 %not2, %b
1688   %or3 = or i32 %and, %not1
1689   ret i32 %or3
1692 define i32 @or_and_not_not_commute1(i32 %a, i32 %b0, i32 %c) {
1693 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute1
1694 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1695 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1696 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1697 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1698 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1699 ; CHECK-NEXT:    ret i32 [[OR3]]
1701   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1702   %or1 = or i32 %b, %a
1703   %not1 = xor i32 %or1, -1
1704   %or2 = or i32 %a, %c
1705   %not2 = xor i32 %or2, -1
1706   %and = and i32 %b, %not2
1707   %or3 = or i32 %and, %not1
1708   ret i32 %or3
1711 define i32 @or_and_not_not_commute2(i32 %a, i32 %b, i32 %c) {
1712 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute2
1713 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1714 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1715 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1716 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1717 ; CHECK-NEXT:    ret i32 [[OR3]]
1719   %or1 = or i32 %b, %a
1720   %not1 = xor i32 %or1, -1
1721   %or2 = or i32 %a, %c
1722   %not2 = xor i32 %or2, -1
1723   %and = and i32 %not2, %b
1724   %or3 = or i32 %and, %not1
1725   ret i32 %or3
1728 define i32 @or_and_not_not_commute3(i32 %a, i32 %b, i32 %c) {
1729 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute3
1730 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1731 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1732 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1733 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1734 ; CHECK-NEXT:    ret i32 [[OR3]]
1736   %or1 = or i32 %b, %a
1737   %not1 = xor i32 %or1, -1
1738   %or2 = or i32 %c, %a
1739   %not2 = xor i32 %or2, -1
1740   %and = and i32 %not2, %b
1741   %or3 = or i32 %and, %not1
1742   ret i32 %or3
1745 define i32 @or_and_not_not_commute4(i32 %a, i32 %b, i32 %c) {
1746 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute4
1747 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1748 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1749 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1750 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1751 ; CHECK-NEXT:    ret i32 [[OR3]]
1753   %or1 = or i32 %a, %b
1754   %not1 = xor i32 %or1, -1
1755   %or2 = or i32 %a, %c
1756   %not2 = xor i32 %or2, -1
1757   %and = and i32 %not2, %b
1758   %or3 = or i32 %and, %not1
1759   ret i32 %or3
1762 define i32 @or_and_not_not_commute5(i32 %a, i32 %b, i32 %c) {
1763 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute5
1764 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1765 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1766 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1767 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1768 ; CHECK-NEXT:    ret i32 [[OR3]]
1770   %or1 = or i32 %b, %a
1771   %not1 = xor i32 %or1, -1
1772   %or2 = or i32 %a, %c
1773   %not2 = xor i32 %or2, -1
1774   %and = and i32 %not2, %b
1775   %or3 = or i32 %not1, %and
1776   ret i32 %or3
1779 define i32 @or_and_not_not_commute6(i32 %a, i32 %b0, i32 %c) {
1780 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute6
1781 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
1782 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
1783 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1784 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1785 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1786 ; CHECK-NEXT:    ret i32 [[OR3]]
1788   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1789   %or1 = or i32 %b, %a
1790   %not1 = xor i32 %or1, -1
1791   %or2 = or i32 %c, %a
1792   %not2 = xor i32 %or2, -1
1793   %and = and i32 %b, %not2
1794   %or3 = or i32 %and, %not1
1795   ret i32 %or3
1798 define i32 @or_and_not_not_commute7(i32 %a, i32 %b, i32 %c) {
1799 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute7
1800 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1801 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1802 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1803 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1804 ; CHECK-NEXT:    ret i32 [[OR3]]
1806   %or1 = or i32 %a, %b
1807   %not1 = xor i32 %or1, -1
1808   %or2 = or i32 %c, %a
1809   %not2 = xor i32 %or2, -1
1810   %and = and i32 %not2, %b
1811   %or3 = or i32 %and, %not1
1812   ret i32 %or3
1815 define i32 @or_and_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1816 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use1
1817 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1818 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
1819 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1820 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1821 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1822 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1823 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1824 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
1825 ; CHECK-NEXT:    ret i32 [[OR3]]
1827   %or1 = or i32 %b, %a
1828   %not1 = xor i32 %or1, -1
1829   %or2 = or i32 %a, %c
1830   %not2 = xor i32 %or2, -1
1831   %and = and i32 %not2, %b
1832   %or3 = or i32 %and, %not1
1833   call void @use(i32 %not1)
1834   ret i32 %or3
1837 define i32 @or_and_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1838 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use2
1839 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1840 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1841 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1842 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1843 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1844 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1845 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
1846 ; CHECK-NEXT:    ret i32 [[OR3]]
1848   %or1 = or i32 %b, %a
1849   %not1 = xor i32 %or1, -1
1850   %or2 = or i32 %a, %c
1851   %not2 = xor i32 %or2, -1
1852   %and = and i32 %not2, %b
1853   %or3 = or i32 %and, %not1
1854   call void @use(i32 %not2)
1855   ret i32 %or3
1858 define i32 @or_and_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {
1859 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_and_use
1860 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1861 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1862 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1863 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1864 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1865 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1866 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1867 ; CHECK-NEXT:    call void @use(i32 [[AND]])
1868 ; CHECK-NEXT:    ret i32 [[OR3]]
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 %and)
1877   ret i32 %or3
1880 define i32 @or_and_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1881 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use1
1882 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1883 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
1884 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1885 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1886 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1887 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1888 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1889 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
1890 ; CHECK-NEXT:    ret i32 [[OR3]]
1892   %or1 = or i32 %b, %a
1893   %not1 = xor i32 %or1, -1
1894   %or2 = or i32 %a, %c
1895   %not2 = xor i32 %or2, -1
1896   %and = and i32 %not2, %b
1897   %or3 = or i32 %and, %not1
1898   call void @use(i32 %or1)
1899   ret i32 %or3
1902 define i32 @or_and_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1903 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use2
1904 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1905 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1906 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[B]]
1907 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1908 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
1909 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
1910 ; CHECK-NEXT:    ret i32 [[OR3]]
1912   %or1 = or i32 %b, %a
1913   %not1 = xor i32 %or1, -1
1914   %or2 = or i32 %a, %c
1915   %not2 = xor i32 %or2, -1
1916   %and = and i32 %not2, %b
1917   %or3 = or i32 %and, %not1
1918   call void @use(i32 %or2)
1919   ret i32 %or3
1922 ; Check the use limit. It can be adjusted in the future in terms of
1923 ; LHS and RHS uses distribution to be more flexible.
1924 define i32 @or_and_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {
1925 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_2_extra_uses
1926 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1927 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
1928 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
1929 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1930 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1931 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1932 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1933 ; CHECK-NEXT:    call void @use(i32 [[AND]])
1934 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1935 ; CHECK-NEXT:    ret i32 [[OR3]]
1937   %or1 = or i32 %b, %a
1938   call void @use(i32 %or1)
1939   %not1 = xor i32 %or1, -1
1940   %or2 = or i32 %a, %c
1941   %not2 = xor i32 %or2, -1
1942   %and = and i32 %not2, %b
1943   call void @use(i32 %and)
1944   %or3 = or i32 %not1, %and
1945   ret i32 %or3
1948 define i32 @or_and_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {
1949 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_a
1950 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1951 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[D]]
1952 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
1953 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[C]]
1954 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
1955 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[B]], [[NOT2]]
1956 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1957 ; CHECK-NEXT:    ret i32 [[OR3]]
1959   %or1 = or i32 %b, %d
1960   %not1 = xor i32 %or1, -1
1961   %or2 = or i32 %a, %c
1962   %not2 = xor i32 %or2, -1
1963   %and = and i32 %not2, %b
1964   %or3 = or i32 %and, %not1
1965   ret i32 %or3
1968 define i32 @or_and_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1969 ; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_b
1970 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
1971 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[D]], [[A]]
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:    [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1977 ; CHECK-NEXT:    ret i32 [[OR3]]
1979   %or1 = or i32 %d, %a
1980   %not1 = xor i32 %or1, -1
1981   %or2 = or i32 %a, %c
1982   %not2 = xor i32 %or2, -1
1983   %and = and i32 %not2, %b
1984   %or3 = or i32 %and, %not1
1985   ret i32 %or3
1988 ; (b | ~(a & c)) & ~(a & b) --> ~((b | c) & a)
1990 define i32 @and_or_not_not(i32 %a, i32 %b, i32 %c) {
1991 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not
1992 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
1993 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
1994 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1995 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
1996 ; CHECK-NEXT:    ret i32 [[AND3]]
1998   %and1 = and i32 %b, %a
1999   %not1 = xor i32 %and1, -1
2000   %and2 = and i32 %a, %c
2001   %not2 = xor i32 %and2, -1
2002   %or = or i32 %not2, %b
2003   %and3 = and i32 %or, %not1
2004   ret i32 %and3
2007 define i32 @and_or_not_not_commute1(i32 %a, i32 %b0, i32 %c) {
2008 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute1
2009 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
2010 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
2011 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2012 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2013 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2014 ; CHECK-NEXT:    ret i32 [[AND3]]
2016   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2017   %and1 = and i32 %b, %a
2018   %not1 = xor i32 %and1, -1
2019   %and2 = and i32 %a, %c
2020   %not2 = xor i32 %and2, -1
2021   %or = or i32 %b, %not2
2022   %and3 = and i32 %or, %not1
2023   ret i32 %and3
2026 define i32 @and_or_not_not_commute2(i32 %a, i32 %b, i32 %c) {
2027 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute2
2028 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2029 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2030 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2031 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2032 ; CHECK-NEXT:    ret i32 [[AND3]]
2034   %and1 = and i32 %b, %a
2035   %not1 = xor i32 %and1, -1
2036   %and2 = and i32 %a, %c
2037   %not2 = xor i32 %and2, -1
2038   %or = or i32 %not2, %b
2039   %and3 = and i32 %or, %not1
2040   ret i32 %and3
2043 define i32 @and_or_not_not_commute3(i32 %a, i32 %b, i32 %c) {
2044 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute3
2045 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2046 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2047 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2048 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2049 ; CHECK-NEXT:    ret i32 [[AND3]]
2051   %and1 = and i32 %b, %a
2052   %not1 = xor i32 %and1, -1
2053   %and2 = and i32 %c, %a
2054   %not2 = xor i32 %and2, -1
2055   %or = or i32 %not2, %b
2056   %and3 = and i32 %or, %not1
2057   ret i32 %and3
2060 define i32 @and_or_not_not_commute4(i32 %a, i32 %b, i32 %c) {
2061 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute4
2062 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2063 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2064 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2065 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2066 ; CHECK-NEXT:    ret i32 [[AND3]]
2068   %and1 = and i32 %a, %b
2069   %not1 = xor i32 %and1, -1
2070   %and2 = and i32 %a, %c
2071   %not2 = xor i32 %and2, -1
2072   %or = or i32 %not2, %b
2073   %and3 = and i32 %or, %not1
2074   ret i32 %and3
2077 define i32 @and_or_not_not_commute5(i32 %a, i32 %b, i32 %c) {
2078 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute5
2079 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2080 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2081 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2082 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2083 ; CHECK-NEXT:    ret i32 [[AND3]]
2085   %and1 = and i32 %b, %a
2086   %not1 = xor i32 %and1, -1
2087   %and2 = and i32 %a, %c
2088   %not2 = xor i32 %and2, -1
2089   %or = or i32 %not2, %b
2090   %and3 = and i32 %not1, %or
2091   ret i32 %and3
2094 define i32 @and_or_not_not_commute6(i32 %a, i32 %b0, i32 %c) {
2095 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute6
2096 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
2097 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
2098 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2099 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2100 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2101 ; CHECK-NEXT:    ret i32 [[AND3]]
2103   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2104   %and1 = and i32 %b, %a
2105   %not1 = xor i32 %and1, -1
2106   %and2 = and i32 %c, %a
2107   %not2 = xor i32 %and2, -1
2108   %or = or i32 %b, %not2
2109   %and3 = and i32 %or, %not1
2110   ret i32 %and3
2113 define i32 @and_or_not_not_commute7(i32 %a, i32 %b, i32 %c) {
2114 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute7
2115 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2116 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2117 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2118 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2119 ; CHECK-NEXT:    ret i32 [[AND3]]
2121   %and1 = and i32 %a, %b
2122   %not1 = xor i32 %and1, -1
2123   %and2 = and i32 %c, %a
2124   %not2 = xor i32 %and2, -1
2125   %or = or i32 %not2, %b
2126   %and3 = and i32 %or, %not1
2127   ret i32 %and3
2130 define i32 @and_or_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {
2131 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use1
2132 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2133 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
2134 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2135 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2136 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2137 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2138 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2139 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
2140 ; CHECK-NEXT:    ret i32 [[AND3]]
2142   %and1 = and i32 %b, %a
2143   %not1 = xor i32 %and1, -1
2144   %and2 = and i32 %a, %c
2145   %not2 = xor i32 %and2, -1
2146   %or = or i32 %not2, %b
2147   %and3 = and i32 %or, %not1
2148   call void @use(i32 %not1)
2149   ret i32 %and3
2152 define i32 @and_or_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {
2153 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use2
2154 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2155 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2156 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2157 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2158 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2159 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2160 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
2161 ; CHECK-NEXT:    ret i32 [[AND3]]
2163   %and1 = and i32 %b, %a
2164   %not1 = xor i32 %and1, -1
2165   %and2 = and i32 %a, %c
2166   %not2 = xor i32 %and2, -1
2167   %or = or i32 %not2, %b
2168   %and3 = and i32 %or, %not1
2169   call void @use(i32 %not2)
2170   ret i32 %and3
2173 define i32 @and_or_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {
2174 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_and_use
2175 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2176 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2177 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2178 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2179 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2180 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2181 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2182 ; CHECK-NEXT:    call void @use(i32 [[OR]])
2183 ; CHECK-NEXT:    ret i32 [[AND3]]
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 %or)
2192   ret i32 %and3
2195 define i32 @and_or_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {
2196 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use1
2197 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2198 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
2199 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2200 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2201 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2202 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2203 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
2204 ; CHECK-NEXT:    ret i32 [[AND3]]
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 %and1)
2213   ret i32 %and3
2216 define i32 @and_or_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {
2217 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use2
2218 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2219 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2220 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[B]]
2221 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
2222 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[TMP2]], -1
2223 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
2224 ; CHECK-NEXT:    ret i32 [[AND3]]
2226   %and1 = and i32 %b, %a
2227   %not1 = xor i32 %and1, -1
2228   %and2 = and i32 %a, %c
2229   %not2 = xor i32 %and2, -1
2230   %or = or i32 %not2, %b
2231   %and3 = and i32 %or, %not1
2232   call void @use(i32 %and2)
2233   ret i32 %and3
2236 define i32 @and_or_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {
2237 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_2_extra_uses
2238 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2239 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
2240 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
2241 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2242 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2243 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2244 ; CHECK-NEXT:    call void @use(i32 [[OR]])
2245 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2246 ; CHECK-NEXT:    ret i32 [[AND3]]
2248   %and1 = and i32 %b, %a
2249   call void @use(i32 %and1)
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   call void @use(i32 %or)
2255   %and3 = and i32 %not1, %or
2256   ret i32 %and3
2259 define i32 @and_or_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {
2260 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_a
2261 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
2262 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[D]]
2263 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2264 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2265 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2266 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
2267 ; CHECK-NEXT:    ret i32 [[AND3]]
2269   %and1 = and i32 %b, %d
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   ret i32 %and3
2278 define i32 @and_or_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
2279 ; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_b
2280 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
2281 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[D]], [[A]]
2282 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2283 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[C]]
2284 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2285 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOT2]]
2286 ; CHECK-NEXT:    [[AND3:%.*]] = and i32 [[OR]], [[NOT1]]
2287 ; CHECK-NEXT:    ret i32 [[AND3]]
2289   %and1 = and i32 %d, %a
2290   %not1 = xor i32 %and1, -1
2291   %and2 = and i32 %a, %c
2292   %not2 = xor i32 %and2, -1
2293   %or = or i32 %not2, %b
2294   %and3 = and i32 %or, %not1
2295   ret i32 %and3
2298 ; (a & ~(b | c)) | ~(a | (b ^ c)) --> (~a & b & c) | ~(b | c)
2300 define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) {
2301 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor
2302 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2303 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2304 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2305 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2306 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2307 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2308 ; CHECK-NEXT:    ret i32 [[OR3]]
2310   %or1 = or i32 %b, %c
2311   %not1 = xor i32 %or1, -1
2312   %and1 = and i32 %not1, %a
2313   %xor1 = xor i32 %b, %c
2314   %or2 = or i32 %xor1, %a
2315   %not2 = xor i32 %or2, -1
2316   %or3 = or i32 %and1, %not2
2317   ret i32 %or3
2320 define i32 @and_not_or_or_not_or_xor_commute1(i32 %a, i32 %b, i32 %c) {
2321 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute1
2322 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2323 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[C]], [[B]]
2324 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2325 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2326 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2327 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2328 ; CHECK-NEXT:    ret i32 [[OR3]]
2330   %or1 = or i32 %c, %b
2331   %not1 = xor i32 %or1, -1
2332   %and1 = and i32 %not1, %a
2333   %xor1 = xor i32 %b, %c
2334   %or2 = or i32 %xor1, %a
2335   %not2 = xor i32 %or2, -1
2336   %or3 = or i32 %and1, %not2
2337   ret i32 %or3
2340 define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) {
2341 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute2
2342 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2343 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2344 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2345 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2346 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2347 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2348 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2349 ; CHECK-NEXT:    ret i32 [[OR3]]
2351   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2352   %or1 = or i32 %b, %c
2353   %not1 = xor i32 %or1, -1
2354   %and1 = and i32 %a, %not1
2355   %xor1 = xor i32 %b, %c
2356   %or2 = or i32 %xor1, %a
2357   %not2 = xor i32 %or2, -1
2358   %or3 = or i32 %and1, %not2
2359   ret i32 %or3
2362 define i32 @and_not_or_or_not_or_xor_commute3(i32 %a, i32 %b, i32 %c) {
2363 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute3
2364 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2365 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2366 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C]], [[B]]
2367 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2368 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2369 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2370 ; CHECK-NEXT:    ret i32 [[OR3]]
2372   %or1 = or i32 %b, %c
2373   %not1 = xor i32 %or1, -1
2374   %and1 = and i32 %not1, %a
2375   %xor1 = xor i32 %c, %b
2376   %or2 = or i32 %xor1, %a
2377   %not2 = xor i32 %or2, -1
2378   %or3 = or i32 %and1, %not2
2379   ret i32 %or3
2382 define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) {
2383 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute4
2384 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2385 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2386 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2387 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2388 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[A]], [[XOR1]]
2389 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2390 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2391 ; CHECK-NEXT:    ret i32 [[OR3]]
2393   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2394   %or1 = or i32 %b, %c
2395   %not1 = xor i32 %or1, -1
2396   %and1 = and i32 %a, %not1
2397   %xor1 = xor i32 %b, %c
2398   %or2 = or i32 %a, %xor1
2399   %not2 = xor i32 %or2, -1
2400   %or3 = or i32 %and1, %not2
2401   ret i32 %or3
2404 define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) {
2405 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute5
2406 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2407 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2408 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2409 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2410 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2411 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2412 ; CHECK-NEXT:    ret i32 [[OR3]]
2414   %or1 = or i32 %b, %c
2415   %not1 = xor i32 %or1, -1
2416   %and1 = and i32 %not1, %a
2417   %xor1 = xor i32 %b, %c
2418   %or2 = or i32 %xor1, %a
2419   %not2 = xor i32 %or2, -1
2420   %or3 = or i32 %not2, %and1
2421   ret i32 %or3
2424 define i32 @and_not_or_or_not_or_xor_use1(i32 %a, i32 %b, i32 %c) {
2425 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use1
2426 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2427 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2428 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2429 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2430 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2431 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2432 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
2433 ; CHECK-NEXT:    ret i32 [[OR3]]
2435   %or1 = or i32 %b, %c
2436   %not1 = xor i32 %or1, -1
2437   %and1 = and i32 %not1, %a
2438   %xor1 = xor i32 %b, %c
2439   %or2 = or i32 %xor1, %a
2440   %not2 = xor i32 %or2, -1
2441   %or3 = or i32 %and1, %not2
2442   call void @use(i32 %or1)
2443   ret i32 %or3
2446 define i32 @and_not_or_or_not_or_xor_use2(i32 %a, i32 %b, i32 %c) {
2447 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use2
2448 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2449 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2450 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
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:    call void @use(i32 [[NOT1]])
2456 ; CHECK-NEXT:    ret i32 [[OR3]]
2458   %or1 = or i32 %b, %c
2459   %not1 = xor i32 %or1, -1
2460   %and1 = and i32 %not1, %a
2461   %xor1 = xor i32 %b, %c
2462   %or2 = or i32 %xor1, %a
2463   %not2 = xor i32 %or2, -1
2464   %or3 = or i32 %and1, %not2
2465   call void @use(i32 %not1)
2466   ret i32 %or3
2469 define i32 @and_not_or_or_not_or_xor_use3(i32 %a, i32 %b, i32 %c) {
2470 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use3
2471 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2472 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2473 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
2474 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
2475 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2476 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2477 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
2478 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
2479 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
2480 ; CHECK-NEXT:    ret i32 [[OR3]]
2482   %or1 = or i32 %b, %c
2483   %not1 = xor i32 %or1, -1
2484   %and1 = and i32 %not1, %a
2485   %xor1 = xor i32 %b, %c
2486   %or2 = or i32 %xor1, %a
2487   %not2 = xor i32 %or2, -1
2488   %or3 = or i32 %and1, %not2
2489   call void @use(i32 %and1)
2490   ret i32 %or3
2493 define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) {
2494 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use4
2495 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2496 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2497 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2498 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2499 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2500 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2501 ; CHECK-NEXT:    call void @use(i32 [[XOR1]])
2502 ; CHECK-NEXT:    ret i32 [[OR3]]
2504   %or1 = or i32 %b, %c
2505   %not1 = xor i32 %or1, -1
2506   %and1 = and i32 %not1, %a
2507   %xor1 = xor i32 %b, %c
2508   %or2 = or i32 %xor1, %a
2509   %not2 = xor i32 %or2, -1
2510   %or3 = or i32 %and1, %not2
2511   call void @use(i32 %xor1)
2512   ret i32 %or3
2515 define i32 @and_not_or_or_not_or_xor_use5(i32 %a, i32 %b, i32 %c) {
2516 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use5
2517 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2518 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2519 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2520 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2521 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2522 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP1]], -1
2523 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
2524 ; CHECK-NEXT:    ret i32 [[OR3]]
2526   %or1 = or i32 %b, %c
2527   %not1 = xor i32 %or1, -1
2528   %and1 = and i32 %not1, %a
2529   %xor1 = xor i32 %b, %c
2530   %or2 = or i32 %xor1, %a
2531   %not2 = xor i32 %or2, -1
2532   %or3 = or i32 %and1, %not2
2533   call void @use(i32 %or2)
2534   ret i32 %or3
2537 define i32 @and_not_or_or_not_or_xor_use6(i32 %a, i32 %b, i32 %c) {
2538 ; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use6
2539 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2540 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[C]]
2541 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
2542 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
2543 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2544 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2545 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[OR2]], -1
2546 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
2547 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
2548 ; CHECK-NEXT:    ret i32 [[OR3]]
2550   %or1 = or i32 %b, %c
2551   %not1 = xor i32 %or1, -1
2552   %and1 = and i32 %not1, %a
2553   %xor1 = xor i32 %b, %c
2554   %or2 = or i32 %xor1, %a
2555   %not2 = xor i32 %or2, -1
2556   %or3 = or i32 %and1, %not2
2557   call void @use(i32 %not2)
2558   ret i32 %or3
2561 ; (a | ~(b & c)) & ~(a & (b ^ c)) --> ~(a | b) | (a ^ b ^ c)
2562 ; This pattern is not handled because the result is more undefined than a source.
2563 ; It is invalid as is, but feezing %a and %b will make it valid.
2565 define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) {
2566 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor
2567 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2568 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2569 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2570 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2571 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2572 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2573 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2574 ; CHECK-NEXT:    ret i32 [[AND3]]
2576   %and1 = and i32 %b, %c
2577   %not1 = xor i32 %and1, -1
2578   %or1 = or i32 %not1, %a
2579   %xor1 = xor i32 %b, %c
2580   %and2 = and i32 %xor1, %a
2581   %not2 = xor i32 %and2, -1
2582   %and3 = and i32 %or1, %not2
2583   ret i32 %and3
2586 define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) {
2587 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute1
2588 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2589 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[C]], [[B]]
2590 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2591 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2592 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2593 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2594 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2595 ; CHECK-NEXT:    ret i32 [[AND3]]
2597   %and1 = and i32 %c, %b
2598   %not1 = xor i32 %and1, -1
2599   %or1 = or i32 %not1, %a
2600   %xor1 = xor i32 %b, %c
2601   %and2 = and i32 %xor1, %a
2602   %not2 = xor i32 %and2, -1
2603   %and3 = and i32 %or1, %not2
2604   ret i32 %and3
2607 define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) {
2608 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute2
2609 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2610 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
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]]
2619   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2620   %and1 = and i32 %b, %c
2621   %not1 = xor i32 %and1, -1
2622   %or1 = or i32 %a, %not1
2623   %xor1 = xor i32 %b, %c
2624   %and2 = and i32 %xor1, %a
2625   %not2 = xor i32 %and2, -1
2626   %and3 = and i32 %or1, %not2
2627   ret i32 %and3
2630 define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) {
2631 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute3
2632 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2633 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2634 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2635 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2636 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[C]], [[B]]
2637 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2638 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2639 ; CHECK-NEXT:    ret i32 [[AND3]]
2641   %and1 = and i32 %b, %c
2642   %not1 = xor i32 %and1, -1
2643   %or1 = or i32 %not1, %a
2644   %xor1 = xor i32 %c, %b
2645   %and2 = and i32 %xor1, %a
2646   %not2 = xor i32 %and2, -1
2647   %and3 = and i32 %or1, %not2
2648   ret i32 %and3
2651 define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) {
2652 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute4
2653 ; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2654 ; CHECK-NEXT:    [[A:%.*]] = sdiv i32 42, [[A0]]
2655 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2656 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2657 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2658 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2659 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[A]], [[XOR1]]
2660 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2661 ; CHECK-NEXT:    ret i32 [[AND3]]
2663   %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2664   %and1 = and i32 %b, %c
2665   %not1 = xor i32 %and1, -1
2666   %or1 = or i32 %a, %not1
2667   %xor1 = xor i32 %b, %c
2668   %and2 = and i32 %a, %xor1
2669   %not2 = xor i32 %and2, -1
2670   %and3 = and i32 %or1, %not2
2671   ret i32 %and3
2674 define i32 @or_not_and_and_not_and_xor_commute5(i32 %a, i32 %b, i32 %c) {
2675 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute5
2676 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2677 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2678 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2679 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2680 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2681 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2682 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2683 ; CHECK-NEXT:    ret i32 [[AND3]]
2685   %and1 = and i32 %b, %c
2686   %not1 = xor i32 %and1, -1
2687   %or1 = or i32 %not1, %a
2688   %xor1 = xor i32 %b, %c
2689   %and2 = and i32 %xor1, %a
2690   %not2 = xor i32 %and2, -1
2691   %and3 = and i32 %not2, %or1
2692   ret i32 %and3
2695 define i32 @or_not_and_and_not_and_xor_use1(i32 %a, i32 %b, i32 %c) {
2696 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use1
2697 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
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 [[XOR1]], [[A]]
2703 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2704 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
2705 ; CHECK-NEXT:    ret i32 [[AND3]]
2707   %and1 = and i32 %b, %c
2708   %not1 = xor i32 %and1, -1
2709   %or1 = or i32 %not1, %a
2710   %xor1 = xor i32 %b, %c
2711   %and2 = and i32 %xor1, %a
2712   %not2 = xor i32 %and2, -1
2713   %and3 = and i32 %or1, %not2
2714   call void @use(i32 %and1)
2715   ret i32 %and3
2718 define i32 @or_not_and_and_not_and_xor_use2(i32 %a, i32 %b, i32 %c) {
2719 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use2
2720 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2721 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2722 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2723 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2724 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2725 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2726 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2727 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
2728 ; CHECK-NEXT:    ret i32 [[AND3]]
2730   %and1 = and i32 %b, %c
2731   %not1 = xor i32 %and1, -1
2732   %or1 = or i32 %not1, %a
2733   %xor1 = xor i32 %b, %c
2734   %and2 = and i32 %xor1, %a
2735   %not2 = xor i32 %and2, -1
2736   %and3 = and i32 %or1, %not2
2737   call void @use(i32 %not1)
2738   ret i32 %and3
2741 define i32 @or_not_and_and_not_and_xor_use3(i32 %a, i32 %b, i32 %c) {
2742 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use3
2743 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2744 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2745 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2746 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2747 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2748 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2749 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2750 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
2751 ; CHECK-NEXT:    ret i32 [[AND3]]
2753   %and1 = and i32 %b, %c
2754   %not1 = xor i32 %and1, -1
2755   %or1 = or i32 %not1, %a
2756   %xor1 = xor i32 %b, %c
2757   %and2 = and i32 %xor1, %a
2758   %not2 = xor i32 %and2, -1
2759   %and3 = and i32 %or1, %not2
2760   call void @use(i32 %or1)
2761   ret i32 %and3
2764 define i32 @or_not_and_and_not_and_xor_use4(i32 %a, i32 %b, i32 %c) {
2765 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use4
2766 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2767 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2768 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2769 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2770 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2771 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2772 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2773 ; CHECK-NEXT:    call void @use(i32 [[XOR1]])
2774 ; CHECK-NEXT:    ret i32 [[AND3]]
2776   %and1 = and i32 %b, %c
2777   %not1 = xor i32 %and1, -1
2778   %or1 = or i32 %not1, %a
2779   %xor1 = xor i32 %b, %c
2780   %and2 = and i32 %xor1, %a
2781   %not2 = xor i32 %and2, -1
2782   %and3 = and i32 %or1, %not2
2783   call void @use(i32 %xor1)
2784   ret i32 %and3
2787 define i32 @or_not_and_and_not_and_xor_use5(i32 %a, i32 %b, i32 %c) {
2788 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use5
2789 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2790 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2791 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2792 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2793 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2794 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2795 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2796 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
2797 ; CHECK-NEXT:    ret i32 [[AND3]]
2799   %and1 = and i32 %b, %c
2800   %not1 = xor i32 %and1, -1
2801   %or1 = or i32 %not1, %a
2802   %xor1 = xor i32 %b, %c
2803   %and2 = and i32 %xor1, %a
2804   %not2 = xor i32 %and2, -1
2805   %and3 = and i32 %or1, %not2
2806   call void @use(i32 %and2)
2807   ret i32 %and3
2810 define i32 @or_not_and_and_not_and_xor_use6(i32 %a, i32 %b, i32 %c) {
2811 ; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use6
2812 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2813 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[C]]
2814 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
2815 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2816 ; CHECK-NEXT:    [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2817 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2818 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[AND2]], -1
2819 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2820 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
2821 ; CHECK-NEXT:    ret i32 [[AND3]]
2823   %and1 = and i32 %b, %c
2824   %not1 = xor i32 %and1, -1
2825   %or1 = or i32 %not1, %a
2826   %xor1 = xor i32 %b, %c
2827   %and2 = and i32 %xor1, %a
2828   %not2 = xor i32 %and2, -1
2829   %and3 = and i32 %or1, %not2
2830   call void @use(i32 %not2)
2831   ret i32 %and3
2834 ; (~a & b & c) | ~(a | b | c) -> ~(a | (b ^ c))
2836 define i32 @not_and_and_or_not_or_or(i32 %a, i32 %b, i32 %c) {
2837 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or
2838 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2839 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2840 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2841 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2842 ; CHECK-NEXT:    ret i32 [[OR3]]
2844   %or1 = or i32 %b, %a
2845   %or2 = or i32 %or1, %c
2846   %not1 = xor i32 %or2, -1
2847   %not2 = xor i32 %a, -1
2848   %and1 = and i32 %not2, %b
2849   %and2 = and i32 %and1, %c
2850   %or3 = or i32 %and2, %not1
2851   ret i32 %or3
2854 define i32 @not_and_and_or_not_or_or_commute1_or(i32 %a, i32 %b, i32 %c) {
2855 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_or
2856 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2857 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2858 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2859 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2860 ; CHECK-NEXT:    ret i32 [[OR3]]
2862   %or1 = or i32 %c, %a
2863   %or2 = or i32 %or1, %b
2864   %not1 = xor i32 %or2, -1
2865   %not2 = xor i32 %a, -1
2866   %and1 = and i32 %not2, %b
2867   %and2 = and i32 %and1, %c
2868   %or3 = or i32 %and2, %not1
2869   ret i32 %or3
2872 define i32 @not_and_and_or_not_or_or_commute2_or(i32 %a, i32 %b, i32 %c) {
2873 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_or
2874 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2875 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2876 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2877 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2878 ; CHECK-NEXT:    ret i32 [[OR3]]
2880   %or1 = or i32 %b, %c
2881   %or2 = or i32 %or1, %a
2882   %not1 = xor i32 %or2, -1
2883   %not2 = xor i32 %a, -1
2884   %and1 = and i32 %not2, %b
2885   %and2 = and i32 %and1, %c
2886   %or3 = or i32 %and2, %not1
2887   ret i32 %or3
2890 define i32 @not_and_and_or_not_or_or_commute1_and(i32 %a, i32 %b, i32 %c) {
2891 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_and
2892 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2893 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
2894 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2895 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2896 ; CHECK-NEXT:    ret i32 [[OR3]]
2898   %or1 = or i32 %b, %a
2899   %or2 = or i32 %or1, %c
2900   %not1 = xor i32 %or2, -1
2901   %not2 = xor i32 %a, -1
2902   %and1 = and i32 %not2, %c
2903   %and2 = and i32 %and1, %b
2904   %or3 = or i32 %and2, %not1
2905   ret i32 %or3
2908 define i32 @not_and_and_or_not_or_or_commute2_and(i32 %a, i32 %b, i32 %c) {
2909 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_and
2910 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2911 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
2912 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2913 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2914 ; CHECK-NEXT:    ret i32 [[OR3]]
2916   %or1 = or i32 %b, %a
2917   %or2 = or i32 %or1, %c
2918   %not1 = xor i32 %or2, -1
2919   %not2 = xor i32 %a, -1
2920   %and1 = and i32 %b, %c
2921   %and2 = and i32 %and1, %not2
2922   %or3 = or i32 %and2, %not1
2923   ret i32 %or3
2926 define i32 @not_and_and_or_not_or_or_commute1(i32 %a, i32 %b, i32 %c) {
2927 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1
2928 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
2929 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2930 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2931 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2932 ; CHECK-NEXT:    ret i32 [[OR3]]
2934   %or1 = or i32 %a, %b
2935   %or2 = or i32 %or1, %c
2936   %not1 = xor i32 %or2, -1
2937   %not2 = xor i32 %a, -1
2938   %and1 = and i32 %not2, %b
2939   %and2 = and i32 %and1, %c
2940   %or3 = or i32 %and2, %not1
2941   ret i32 %or3
2944 define i32 @not_and_and_or_not_or_or_commute2(i32 %a, i32 %b, i32 %c0) {
2945 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2
2946 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
2947 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
2948 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2949 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2950 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2951 ; CHECK-NEXT:    ret i32 [[OR3]]
2953   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2954   %or1 = or i32 %b, %a
2955   %or2 = or i32 %c, %or1
2956   %not1 = xor i32 %or2, -1
2957   %not2 = xor i32 %a, -1
2958   %and1 = and i32 %not2, %b
2959   %and2 = and i32 %and1, %c
2960   %or3 = or i32 %and2, %not1
2961   ret i32 %or3
2964 define i32 @not_and_and_or_not_or_or_commute3(i32 %a, i32 %b0, i32 %c) {
2965 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute3
2966 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
2967 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
2968 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2969 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2970 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2971 ; CHECK-NEXT:    ret i32 [[OR3]]
2973   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2974   %or1 = or i32 %b, %a
2975   %or2 = or i32 %or1, %c
2976   %not1 = xor i32 %or2, -1
2977   %not2 = xor i32 %a, -1
2978   %and1 = and i32 %b, %not2
2979   %and2 = and i32 %and1, %c
2980   %or3 = or i32 %and2, %not1
2981   ret i32 %or3
2984 define i32 @not_and_and_or_not_or_or_commute4(i32 %a, i32 %b, i32 %c0) {
2985 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute4
2986 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
2987 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
2988 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2989 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2990 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
2991 ; CHECK-NEXT:    ret i32 [[OR3]]
2993   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2994   %or1 = or i32 %b, %a
2995   %or2 = or i32 %or1, %c
2996   %not1 = xor i32 %or2, -1
2997   %not2 = xor i32 %a, -1
2998   %and1 = and i32 %not2, %b
2999   %and2 = and i32 %c, %and1
3000   %or3 = or i32 %and2, %not1
3001   ret i32 %or3
3004 define i32 @not_and_and_or_not_or_or_use1(i32 %a, i32 %b, i32 %c) {
3005 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use1
3006 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3007 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3008 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3009 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3010 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3011 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
3012 ; CHECK-NEXT:    ret i32 [[OR3]]
3014   %or1 = or i32 %b, %a
3015   %or2 = or i32 %or1, %c
3016   %not1 = xor i32 %or2, -1
3017   %not2 = xor i32 %a, -1
3018   %and1 = and i32 %not2, %b
3019   %and2 = and i32 %and1, %c
3020   %or3 = or i32 %and2, %not1
3021   call void @use(i32 %or1)
3022   ret i32 %or3
3025 define i32 @not_and_and_or_not_or_or_use2(i32 %a, i32 %b, i32 %c) {
3026 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use2
3027 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3028 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3029 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3030 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3031 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3032 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3033 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
3034 ; CHECK-NEXT:    ret i32 [[OR3]]
3036   %or1 = or i32 %b, %a
3037   %or2 = or i32 %or1, %c
3038   %not1 = xor i32 %or2, -1
3039   %not2 = xor i32 %a, -1
3040   %and1 = and i32 %not2, %b
3041   %and2 = and i32 %and1, %c
3042   %or3 = or i32 %and2, %not1
3043   call void @use(i32 %or2)
3044   ret i32 %or3
3047 define i32 @not_and_and_or_not_or_or_use3(i32 %a, i32 %b, i32 %c) {
3048 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use3
3049 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3050 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3051 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3052 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR2]], -1
3053 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3054 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3055 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3056 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]
3057 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3058 ; CHECK-NEXT:    ret i32 [[OR3]]
3060   %or1 = or i32 %b, %a
3061   %or2 = or i32 %or1, %c
3062   %not1 = xor i32 %or2, -1
3063   %not2 = xor i32 %a, -1
3064   %and1 = and i32 %not2, %b
3065   %and2 = and i32 %and1, %c
3066   %or3 = or i32 %and2, %not1
3067   call void @use(i32 %not1)
3068   ret i32 %or3
3071 define i32 @not_and_and_or_not_or_or_use4(i32 %a, i32 %b, i32 %c) {
3072 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use4
3073 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3074 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3075 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3076 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3077 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3078 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3079 ; CHECK-NEXT:    ret i32 [[OR3]]
3081   %or1 = or i32 %b, %a
3082   %or2 = or i32 %or1, %c
3083   %not1 = xor i32 %or2, -1
3084   %not2 = xor i32 %a, -1
3085   %and1 = and i32 %not2, %b
3086   %and2 = and i32 %and1, %c
3087   %or3 = or i32 %and2, %not1
3088   call void @use(i32 %not2)
3089   ret i32 %or3
3092 define i32 @not_and_and_or_not_or_or_use5(i32 %a, i32 %b, i32 %c) {
3093 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use5
3094 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3095 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3096 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3097 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3098 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
3099 ; CHECK-NEXT:    [[OR3:%.*]] = xor i32 [[TMP2]], -1
3100 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
3101 ; CHECK-NEXT:    ret i32 [[OR3]]
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 %and1)
3111   ret i32 %or3
3114 define i32 @not_and_and_or_not_or_or_use6(i32 %a, i32 %b, i32 %c) {
3115 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use6
3116 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3117 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3118 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3119 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR2]], -1
3120 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3121 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3122 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3123 ; CHECK-NEXT:    [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]
3124 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
3125 ; CHECK-NEXT:    ret i32 [[OR3]]
3127   %or1 = or i32 %b, %a
3128   %or2 = or i32 %or1, %c
3129   %not1 = xor i32 %or2, -1
3130   %not2 = xor i32 %a, -1
3131   %and1 = and i32 %not2, %b
3132   %and2 = and i32 %and1, %c
3133   %or3 = or i32 %and2, %not1
3134   call void @use(i32 %and2)
3135   ret i32 %or3
3138 ; (~a | b | c) & ~(a & b & c) -> ~a | (b ^ c)
3140 define i32 @not_or_or_and_not_and_and(i32 %a, i32 %b, i32 %c) {
3141 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and
3142 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3143 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3144 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3145 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3146 ; CHECK-NEXT:    ret i32 [[AND3]]
3148   %and1 = and i32 %b, %a
3149   %and2 = and i32 %and1, %c
3150   %not1 = xor i32 %and2, -1
3151   %not2 = xor i32 %a, -1
3152   %or1 = or i32 %not2, %b
3153   %or2 = or i32 %or1, %c
3154   %and3 = and i32 %or2, %not1
3155   ret i32 %and3
3158 define i32 @not_or_or_and_not_and_and_commute1_and(i32 %a, i32 %b, i32 %c) {
3159 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_and
3160 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3161 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3162 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3163 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3164 ; CHECK-NEXT:    ret i32 [[AND3]]
3166   %and1 = and i32 %c, %a
3167   %and2 = and i32 %and1, %b
3168   %not1 = xor i32 %and2, -1
3169   %not2 = xor i32 %a, -1
3170   %or1 = or i32 %not2, %b
3171   %or2 = or i32 %or1, %c
3172   %and3 = and i32 %or2, %not1
3173   ret i32 %and3
3176 define i32 @not_or_or_and_not_and_and_commute2_and(i32 %a, i32 %b, i32 %c) {
3177 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_and
3178 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3179 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3180 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3181 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3182 ; CHECK-NEXT:    ret i32 [[AND3]]
3184   %and1 = and i32 %b, %c
3185   %and2 = and i32 %and1, %a
3186   %not1 = xor i32 %and2, -1
3187   %not2 = xor i32 %a, -1
3188   %or1 = or i32 %not2, %b
3189   %or2 = or i32 %or1, %c
3190   %and3 = and i32 %or2, %not1
3191   ret i32 %and3
3194 define i32 @not_or_or_and_not_and_and_commute1_or(i32 %a, i32 %b, i32 %c) {
3195 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_or
3196 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3197 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3198 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
3199 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3200 ; CHECK-NEXT:    ret i32 [[AND3]]
3202   %and1 = and i32 %b, %a
3203   %and2 = and i32 %and1, %c
3204   %not1 = xor i32 %and2, -1
3205   %not2 = xor i32 %a, -1
3206   %or1 = or i32 %not2, %c
3207   %or2 = or i32 %or1, %b
3208   %and3 = and i32 %or2, %not1
3209   ret i32 %and3
3212 define i32 @not_or_or_and_not_and_and_commute2_or(i32 %a, i32 %b, i32 %c) {
3213 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_or
3214 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3215 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3216 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], [[C]]
3217 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3218 ; CHECK-NEXT:    ret i32 [[AND3]]
3220   %and1 = and i32 %b, %a
3221   %and2 = and i32 %and1, %c
3222   %not1 = xor i32 %and2, -1
3223   %not2 = xor i32 %a, -1
3224   %or1 = or i32 %b, %c
3225   %or2 = or i32 %or1, %not2
3226   %and3 = and i32 %or2, %not1
3227   ret i32 %and3
3230 define i32 @not_or_or_and_not_and_and_commute1(i32 %a, i32 %b, i32 %c) {
3231 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1
3232 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3233 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3234 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3235 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3236 ; CHECK-NEXT:    ret i32 [[AND3]]
3238   %and1 = and i32 %a, %b
3239   %and2 = and i32 %and1, %c
3240   %not1 = xor i32 %and2, -1
3241   %not2 = xor i32 %a, -1
3242   %or1 = or i32 %not2, %b
3243   %or2 = or i32 %or1, %c
3244   %and3 = and i32 %or2, %not1
3245   ret i32 %and3
3248 define i32 @not_or_or_and_not_and_and_commute2(i32 %a, i32 %b, i32 %c0) {
3249 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2
3250 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3251 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3252 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3253 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3254 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3255 ; CHECK-NEXT:    ret i32 [[AND3]]
3257   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3258   %and1 = and i32 %b, %a
3259   %and2 = and i32 %c, %and1
3260   %not1 = xor i32 %and2, -1
3261   %not2 = xor i32 %a, -1
3262   %or1 = or i32 %not2, %b
3263   %or2 = or i32 %or1, %c
3264   %and3 = and i32 %or2, %not1
3265   ret i32 %and3
3268 define i32 @not_or_or_and_not_and_and_commute3(i32 %a, i32 %b0, i32 %c) {
3269 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute3
3270 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3271 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3272 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3273 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3274 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3275 ; CHECK-NEXT:    ret i32 [[AND3]]
3277   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3278   %and1 = and i32 %b, %a
3279   %and2 = and i32 %and1, %c
3280   %not1 = xor i32 %and2, -1
3281   %not2 = xor i32 %a, -1
3282   %or1 = or i32 %b, %not2
3283   %or2 = or i32 %or1, %c
3284   %and3 = and i32 %or2, %not1
3285   ret i32 %and3
3288 define i32 @not_or_or_and_not_and_and_commute4(i32 %a, i32 %b, i32 %c0) {
3289 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute4
3290 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3291 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3292 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3293 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3294 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3295 ; CHECK-NEXT:    ret i32 [[AND3]]
3297   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3298   %and1 = and i32 %b, %a
3299   %and2 = and i32 %and1, %c
3300   %not1 = xor i32 %and2, -1
3301   %not2 = xor i32 %a, -1
3302   %or1 = or i32 %not2, %b
3303   %or2 = or i32 %c, %or1
3304   %and3 = and i32 %or2, %not1
3305   ret i32 %and3
3308 define i32 @not_or_or_and_not_and_and_use1(i32 %a, i32 %b, i32 %c) {
3309 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use1
3310 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3311 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3312 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3313 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3314 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3315 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
3316 ; CHECK-NEXT:    ret i32 [[AND3]]
3318   %and1 = and i32 %b, %a
3319   %and2 = and i32 %and1, %c
3320   %not1 = xor i32 %and2, -1
3321   %not2 = xor i32 %a, -1
3322   %or1 = or i32 %not2, %b
3323   %or2 = or i32 %or1, %c
3324   %and3 = and i32 %or2, %not1
3325   call void @use(i32 %and1)
3326   ret i32 %and3
3329 define i32 @not_or_or_and_not_and_and_use2(i32 %a, i32 %b, i32 %c) {
3330 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use2
3331 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3332 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3333 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3334 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3335 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3336 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3337 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
3338 ; CHECK-NEXT:    ret i32 [[AND3]]
3340   %and1 = and i32 %b, %a
3341   %and2 = and i32 %and1, %c
3342   %not1 = xor i32 %and2, -1
3343   %not2 = xor i32 %a, -1
3344   %or1 = or i32 %not2, %b
3345   %or2 = or i32 %or1, %c
3346   %and3 = and i32 %or2, %not1
3347   call void @use(i32 %and2)
3348   ret i32 %and3
3351 define i32 @not_or_or_and_not_and_and_use3(i32 %a, i32 %b, i32 %c) {
3352 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use3
3353 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3354 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3355 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3356 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND2]], -1
3357 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3358 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3359 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3360 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]
3361 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3362 ; CHECK-NEXT:    ret i32 [[AND3]]
3364   %and1 = and i32 %b, %a
3365   %and2 = and i32 %and1, %c
3366   %not1 = xor i32 %and2, -1
3367   %not2 = xor i32 %a, -1
3368   %or1 = or i32 %not2, %b
3369   %or2 = or i32 %or1, %c
3370   %and3 = and i32 %or2, %not1
3371   call void @use(i32 %not1)
3372   ret i32 %and3
3375 define i32 @not_or_or_and_not_and_and_use4(i32 %a, i32 %b, i32 %c) {
3376 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use4
3377 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3378 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3379 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3380 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3381 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3382 ; CHECK-NEXT:    ret i32 [[AND3]]
3384   %and1 = and i32 %b, %a
3385   %and2 = and i32 %and1, %c
3386   %not1 = xor i32 %and2, -1
3387   %not2 = xor i32 %a, -1
3388   %or1 = or i32 %not2, %b
3389   %or2 = or i32 %or1, %c
3390   %and3 = and i32 %or2, %not1
3391   call void @use(i32 %not2)
3392   ret i32 %and3
3395 define i32 @not_or_or_and_not_and_and_use5(i32 %a, i32 %b, i32 %c) {
3396 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use5
3397 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3398 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3399 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3400 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3401 ; CHECK-NEXT:    [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3402 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
3403 ; CHECK-NEXT:    ret i32 [[AND3]]
3405   %and1 = and i32 %b, %a
3406   %and2 = and i32 %and1, %c
3407   %not1 = xor i32 %and2, -1
3408   %not2 = xor i32 %a, -1
3409   %or1 = or i32 %not2, %b
3410   %or2 = or i32 %or1, %c
3411   %and3 = and i32 %or2, %not1
3412   call void @use(i32 %or1)
3413   ret i32 %and3
3416 define i32 @not_or_or_and_not_and_and_use6(i32 %a, i32 %b, i32 %c) {
3417 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use6
3418 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3419 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3420 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C]]
3421 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3422 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3423 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3424 ; CHECK-NEXT:    [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]
3425 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
3426 ; CHECK-NEXT:    ret i32 [[AND3]]
3428   %and1 = and i32 %b, %a
3429   %and2 = and i32 %and1, %c
3430   %not1 = xor i32 %and2, -1
3431   %not2 = xor i32 %a, -1
3432   %or1 = or i32 %not2, %b
3433   %or2 = or i32 %or1, %c
3434   %and3 = and i32 %or2, %not1
3435   call void @use(i32 %or2)
3436   ret i32 %and3
3439 ; (~a & b & c) | ~(a | b) -> (c | ~b) & ~a
3441 define i32 @not_and_and_or_no_or(i32 %a, i32 %b, i32 %c) {
3442 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or
3443 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3444 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3445 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3446 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3447 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3448 ; CHECK-NEXT:    ret i32 [[OR2]]
3450   %or1 = or i32 %b, %a
3451   %not1 = xor i32 %or1, -1
3452   %not2 = xor i32 %a, -1
3453   %and1 = and i32 %not2, %b
3454   %and2 = and i32 %and1, %c
3455   %or2 = or i32 %and2, %not1
3456   ret i32 %or2
3459 define i32 @not_and_and_or_no_or_commute1_and(i32 %a, i32 %b, i32 %c) {
3460 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1_and
3461 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3462 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3463 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3464 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3465 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3466 ; CHECK-NEXT:    ret i32 [[OR2]]
3468   %or1 = or i32 %b, %a
3469   %not1 = xor i32 %or1, -1
3470   %not2 = xor i32 %a, -1
3471   %and1 = and i32 %c, %b
3472   %and2 = and i32 %and1, %not2
3473   %or2 = or i32 %and2, %not1
3474   ret i32 %or2
3477 define i32 @not_and_and_or_no_or_commute2_and(i32 %a, i32 %b, i32 %c) {
3478 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2_and
3479 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3480 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3481 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3482 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3483 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3484 ; CHECK-NEXT:    ret i32 [[OR2]]
3486   %or1 = or i32 %b, %a
3487   %not1 = xor i32 %or1, -1
3488   %not2 = xor i32 %a, -1
3489   %and1 = and i32 %not2, %c
3490   %and2 = and i32 %and1, %b
3491   %or2 = or i32 %and2, %not1
3492   ret i32 %or2
3495 define i32 @not_and_and_or_no_or_commute1(i32 %a, i32 %b, i32 %c) {
3496 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1
3497 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3498 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3499 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3500 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3501 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3502 ; CHECK-NEXT:    ret i32 [[OR2]]
3504   %or1 = or i32 %a, %b
3505   %not1 = xor i32 %or1, -1
3506   %not2 = xor i32 %a, -1
3507   %and1 = and i32 %not2, %b
3508   %and2 = and i32 %and1, %c
3509   %or2 = or i32 %and2, %not1
3510   ret i32 %or2
3513 define i32 @not_and_and_or_no_or_commute2(i32 %a, i32 %b0, i32 %c) {
3514 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2
3515 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3516 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3517 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3518 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3519 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3520 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3521 ; CHECK-NEXT:    ret i32 [[OR2]]
3523   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3524   %or1 = or i32 %b, %a
3525   %not1 = xor i32 %or1, -1
3526   %not2 = xor i32 %a, -1
3527   %and1 = and i32 %b, %not2
3528   %and2 = and i32 %and1, %c
3529   %or2 = or i32 %and2, %not1
3530   ret i32 %or2
3533 define i32 @not_and_and_or_no_or_commute3(i32 %a, i32 %b, i32 %c0) {
3534 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute3
3535 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3536 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3537 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3538 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3539 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3540 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3541 ; CHECK-NEXT:    ret i32 [[OR2]]
3543   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3544   %or1 = or i32 %b, %a
3545   %not1 = xor i32 %or1, -1
3546   %not2 = xor i32 %a, -1
3547   %and1 = and i32 %not2, %b
3548   %and2 = and i32 %c, %and1
3549   %or2 = or i32 %and2, %not1
3550   ret i32 %or2
3553 define i32 @not_and_and_or_no_or_use1(i32 %a, i32 %b, i32 %c) {
3554 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use1
3555 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3556 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3557 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3558 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3559 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3560 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3561 ; CHECK-NEXT:    ret i32 [[OR2]]
3563   %or1 = or i32 %b, %a
3564   %not1 = xor i32 %or1, -1
3565   %not2 = xor i32 %a, -1
3566   %and1 = and i32 %not2, %b
3567   %and2 = and i32 %and1, %c
3568   %or2 = or i32 %and2, %not1
3569   call void @use(i32 %not2)
3570   ret i32 %or2
3573 define i32 @not_and_and_or_no_or_use2(i32 %a, i32 %b, i32 %c) {
3574 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use2
3575 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3576 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3577 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3578 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3579 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3580 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3581 ; CHECK-NEXT:    ret i32 [[OR2]]
3583   %or1 = or i32 %b, %a
3584   %not1 = xor i32 %or1, -1
3585   %not2 = xor i32 %a, -1
3586   %and1 = and i32 %b, %c
3587   %and2 = and i32 %and1, %not2
3588   %or2 = or i32 %and2, %not1
3589   call void @use(i32 %not2)
3590   ret i32 %or2
3593 define i32 @not_and_and_or_no_or_use3(i32 %a, i32 %b, i32 %c) {
3594 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use3
3595 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3596 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3597 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3598 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3599 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3600 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3601 ; CHECK-NEXT:    ret i32 [[OR2]]
3603   %or1 = or i32 %b, %a
3604   %not1 = xor i32 %or1, -1
3605   %not2 = xor i32 %a, -1
3606   %and1 = and i32 %not2, %c
3607   %and2 = and i32 %and1, %b
3608   %or2 = or i32 %and2, %not1
3609   call void @use(i32 %not2)
3610   ret i32 %or2
3613 define i32 @not_and_and_or_no_or_use4(i32 %a, i32 %b, i32 %c) {
3614 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use4
3615 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3616 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3617 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3618 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3619 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3620 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3621 ; CHECK-NEXT:    ret i32 [[OR2]]
3623   %or1 = or i32 %b, %a
3624   %not1 = xor i32 %or1, -1
3625   %not2 = xor i32 %a, -1
3626   %and1 = and i32 %not2, %c
3627   %and2 = and i32 %and1, %b
3628   %or2 = or i32 %and2, %not1
3629   call void @use(i32 %not2)
3630   ret i32 %or2
3633 define i32 @not_and_and_or_no_or_use5(i32 %a, i32 %b, i32 %c) {
3634 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use5
3635 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3636 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3637 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
3638 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3639 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]
3640 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[TMP1]], [[B]]
3641 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3642 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
3643 ; CHECK-NEXT:    ret i32 [[OR2]]
3645   %or1 = or i32 %b, %a
3646   %not1 = xor i32 %or1, -1
3647   %not2 = xor i32 %a, -1
3648   %and1 = and i32 %not2, %b
3649   %and2 = and i32 %and1, %c
3650   %or2 = or i32 %and2, %not1
3651   call void @use(i32 %or1)
3652   ret i32 %or2
3655 define i32 @not_and_and_or_no_or_use6(i32 %a, i32 %b, i32 %c) {
3656 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use6
3657 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3658 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[A]]
3659 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[OR1]], -1
3660 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3661 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]
3662 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[TMP1]], [[B]]
3663 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3664 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3665 ; CHECK-NEXT:    ret i32 [[OR2]]
3667   %or1 = or i32 %b, %a
3668   %not1 = xor i32 %or1, -1
3669   %not2 = xor i32 %a, -1
3670   %and1 = and i32 %not2, %b
3671   %and2 = and i32 %and1, %c
3672   %or2 = or i32 %and2, %not1
3673   call void @use(i32 %not1)
3674   ret i32 %or2
3677 define i32 @not_and_and_or_no_or_use7(i32 %a, i32 %b, i32 %c) {
3678 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use7
3679 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3680 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3681 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[NOT2]]
3682 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3683 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3684 ; CHECK-NEXT:    [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3685 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
3686 ; CHECK-NEXT:    ret i32 [[OR2]]
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 %and1)
3695   ret i32 %or2
3698 define i32 @not_and_and_or_no_or_use8(i32 %a, i32 %b, i32 %c) {
3699 ; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use8
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 [[AND2]])
3708 ; CHECK-NEXT:    ret i32 [[OR2]]
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 %and2)
3717   ret i32 %or2
3720 ; (~a | b | c) & ~(a & b) -> (c & ~b) | ~a
3722 define i32 @not_or_or_and_no_and(i32 %a, i32 %b, i32 %c) {
3723 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and
3724 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3725 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3726 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3727 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3728 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3729 ; CHECK-NEXT:    ret i32 [[AND2]]
3731   %and1 = and i32 %b, %a
3732   %not1 = xor i32 %and1, -1
3733   %not2 = xor i32 %a, -1
3734   %or1 = or i32 %not2, %b
3735   %or2 = or i32 %or1, %c
3736   %and2 = and i32 %or2, %not1
3737   ret i32 %and2
3740 define i32 @not_or_or_and_no_and_commute1_or(i32 %a, i32 %b, i32 %c) {
3741 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1_or
3742 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3743 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3744 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3745 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3746 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3747 ; CHECK-NEXT:    ret i32 [[AND2]]
3749   %and1 = and i32 %b, %a
3750   %not1 = xor i32 %and1, -1
3751   %not2 = xor i32 %a, -1
3752   %or1 = or i32 %c, %b
3753   %or2 = or i32 %or1, %not2
3754   %and2 = and i32 %or2, %not1
3755   ret i32 %and2
3758 define i32 @not_or_or_and_no_and_commute2_or(i32 %a, i32 %b, i32 %c) {
3759 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2_or
3760 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3761 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3762 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3763 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3764 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3765 ; CHECK-NEXT:    ret i32 [[AND2]]
3767   %and1 = and i32 %b, %a
3768   %not1 = xor i32 %and1, -1
3769   %not2 = xor i32 %a, -1
3770   %or1 = or i32 %not2, %c
3771   %or2 = or i32 %or1, %b
3772   %and2 = and i32 %or2, %not1
3773   ret i32 %and2
3776 define i32 @not_or_or_and_no_and_commute1(i32 %a, i32 %b, i32 %c) {
3777 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1
3778 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3779 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3780 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3781 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3782 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3783 ; CHECK-NEXT:    ret i32 [[AND2]]
3785   %and1 = and i32 %a, %b
3786   %not1 = xor i32 %and1, -1
3787   %not2 = xor i32 %a, -1
3788   %or1 = or i32 %not2, %b
3789   %or2 = or i32 %or1, %c
3790   %and2 = and i32 %or2, %not1
3791   ret i32 %and2
3794 define i32 @not_or_or_and_no_and_commute2(i32 %a, i32 %b0, i32 %c) {
3795 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2
3796 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {
3797 ; CHECK-NEXT:    [[B:%.*]] = sdiv i32 42, [[B0]]
3798 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3799 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3800 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3801 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3802 ; CHECK-NEXT:    ret i32 [[AND2]]
3804   %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3805   %and1 = and i32 %b, %a
3806   %not1 = xor i32 %and1, -1
3807   %not2 = xor i32 %a, -1
3808   %or1 = or i32 %b, %not2
3809   %or2 = or i32 %or1, %c
3810   %and2 = and i32 %or2, %not1
3811   ret i32 %and2
3814 define i32 @not_or_or_and_no_and_commute3(i32 %a, i32 %b, i32 %c0) {
3815 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute3
3816 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {
3817 ; CHECK-NEXT:    [[C:%.*]] = sdiv i32 42, [[C0]]
3818 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3819 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3820 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3821 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3822 ; CHECK-NEXT:    ret i32 [[AND2]]
3824   %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3825   %and1 = and i32 %b, %a
3826   %not1 = xor i32 %and1, -1
3827   %not2 = xor i32 %a, -1
3828   %or1 = or i32 %not2, %b
3829   %or2 = or i32 %c, %or1
3830   %and2 = and i32 %or2, %not1
3831   ret i32 %and2
3834 define i32 @not_or_or_and_no_and_use1(i32 %a, i32 %b, i32 %c) {
3835 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use1
3836 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3837 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3838 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3839 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3840 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3841 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3842 ; CHECK-NEXT:    ret i32 [[AND2]]
3844   %and1 = and i32 %b, %a
3845   %not1 = xor i32 %and1, -1
3846   %not2 = xor i32 %a, -1
3847   %or1 = or i32 %not2, %b
3848   %or2 = or i32 %or1, %c
3849   %and2 = and i32 %or2, %not1
3850   call void @use(i32 %not2)
3851   ret i32 %and2
3854 define i32 @not_or_or_and_no_and_use2(i32 %a, i32 %b, i32 %c) {
3855 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use2
3856 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3857 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3858 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3859 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3860 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3861 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3862 ; CHECK-NEXT:    ret i32 [[AND2]]
3864   %and1 = and i32 %b, %a
3865   %not1 = xor i32 %and1, -1
3866   %not2 = xor i32 %a, -1
3867   %or1 = or i32 %b, %c
3868   %or2 = or i32 %or1, %not2
3869   %and2 = and i32 %or2, %not1
3870   call void @use(i32 %not2)
3871   ret i32 %and2
3874 define i32 @not_or_or_and_no_and_use3(i32 %a, i32 %b, i32 %c) {
3875 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use3
3876 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3877 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3878 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3879 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3880 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3881 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3882 ; CHECK-NEXT:    ret i32 [[AND2]]
3884   %and1 = and i32 %b, %a
3885   %not1 = xor i32 %and1, -1
3886   %not2 = xor i32 %a, -1
3887   %or1 = or i32 %not2, %c
3888   %or2 = or i32 %or1, %b
3889   %and2 = and i32 %or2, %not1
3890   call void @use(i32 %not2)
3891   ret i32 %and2
3894 define i32 @not_or_or_and_no_and_use4(i32 %a, i32 %b, i32 %c) {
3895 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use4
3896 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3897 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3898 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3899 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3900 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3901 ; CHECK-NEXT:    call void @use(i32 [[NOT2]])
3902 ; CHECK-NEXT:    ret i32 [[AND2]]
3904   %and1 = and i32 %b, %a
3905   %not1 = xor i32 %and1, -1
3906   %not2 = xor i32 %a, -1
3907   %or1 = or i32 %not2, %c
3908   %or2 = or i32 %or1, %b
3909   %and2 = and i32 %or2, %not1
3910   call void @use(i32 %not2)
3911   ret i32 %and2
3914 define i32 @not_or_or_and_no_and_use5(i32 %a, i32 %b, i32 %c) {
3915 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use5
3916 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3917 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3918 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3919 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]
3920 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[TMP1]], [[B]]
3921 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]
3922 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
3923 ; CHECK-NEXT:    ret i32 [[AND2]]
3925   %and1 = and i32 %b, %a
3926   %not1 = xor i32 %and1, -1
3927   %not2 = xor i32 %a, -1
3928   %or1 = or i32 %not2, %b
3929   %or2 = or i32 %or1, %c
3930   %and2 = and i32 %or2, %not1
3931   call void @use(i32 %and1)
3932   ret i32 %and2
3935 define i32 @not_or_or_and_no_and_use6(i32 %a, i32 %b, i32 %c) {
3936 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use6
3937 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3938 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3939 ; CHECK-NEXT:    [[NOT1:%.*]] = xor i32 [[AND1]], -1
3940 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3941 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]
3942 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[TMP1]], [[B]]
3943 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]
3944 ; CHECK-NEXT:    call void @use(i32 [[NOT1]])
3945 ; CHECK-NEXT:    ret i32 [[AND2]]
3947   %and1 = and i32 %b, %a
3948   %not1 = xor i32 %and1, -1
3949   %not2 = xor i32 %a, -1
3950   %or1 = or i32 %not2, %b
3951   %or2 = or i32 %or1, %c
3952   %and2 = and i32 %or2, %not1
3953   call void @use(i32 %not1)
3954   ret i32 %and2
3957 define i32 @not_or_or_and_no_and_use7(i32 %a, i32 %b, i32 %c) {
3958 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use7
3959 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3960 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3961 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[B]], [[NOT2]]
3962 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[B]], -1
3963 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3964 ; CHECK-NEXT:    [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3965 ; CHECK-NEXT:    call void @use(i32 [[OR1]])
3966 ; CHECK-NEXT:    ret i32 [[AND2]]
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 %or1)
3975   ret i32 %and2
3978 define i32 @not_or_or_and_no_and_use8(i32 %a, i32 %b, i32 %c) {
3979 ; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use8
3980 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
3981 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[B]], [[A]]
3982 ; CHECK-NEXT:    [[NOT2:%.*]] = xor i32 [[A]], -1
3983 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]
3984 ; CHECK-NEXT:    [[OR2:%.*]] = or i32 [[TMP1]], [[B]]
3985 ; CHECK-NEXT:    [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]
3986 ; CHECK-NEXT:    call void @use(i32 [[OR2]])
3987 ; CHECK-NEXT:    ret i32 [[AND2]]
3989   %and1 = and i32 %b, %a
3990   %not1 = xor i32 %and1, -1
3991   %not2 = xor i32 %a, -1
3992   %or1 = or i32 %not2, %b
3993   %or2 = or i32 %or1, %c
3994   %and2 = and i32 %or2, %not1
3995   call void @use(i32 %or2)
3996   ret i32 %and2
3999 define i4 @and_orn_xor(i4 %a, i4 %b) {
4000 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor
4001 ; CHECK-SAME: (i4 [[A:%.*]], i4 [[B:%.*]]) {
4002 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[A]], -1
4003 ; CHECK-NEXT:    [[R:%.*]] = and i4 [[B]], [[TMP1]]
4004 ; CHECK-NEXT:    ret i4 [[R]]
4006   %xor = xor i4 %a, %b
4007   %nota = xor i4 %a, -1
4008   %or = or i4 %nota, %b
4009   %r = and i4 %or, %xor
4010   ret i4 %r
4013 define <2 x i4> @and_orn_xor_commute1(<2 x i4> %a, <2 x i4> %b) {
4014 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute1
4015 ; CHECK-SAME: (<2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {
4016 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[A]], splat (i4 -1)
4017 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i4> [[B]], [[TMP1]]
4018 ; CHECK-NEXT:    ret <2 x i4> [[R]]
4020   %xor = xor <2 x i4> %a, %b
4021   %nota = xor <2 x i4> %a, <i4 -1, i4 poison>
4022   %or = or <2 x i4> %nota, %b
4023   %r = and <2 x i4> %xor, %or
4024   ret <2 x i4> %r
4027 define i32 @and_orn_xor_commute2(i32 %a, i32 %b) {
4028 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute2
4029 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
4030 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
4031 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
4032 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4033 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4034 ; CHECK-NEXT:    ret i32 [[R]]
4036   %xor = xor i32 %b, %a
4037   call void @use(i32 %xor)
4038   %nota = xor i32 %a, -1
4039   %or = or i32 %nota, %b
4040   %r = and i32 %or, %xor
4041   ret i32 %r
4044 define i32 @and_orn_xor_commute3(i32 %a, i32 %b) {
4045 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute3
4046 ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {
4047 ; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4048 ; CHECK-NEXT:    call void @use(i32 [[NOTA]])
4049 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4050 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4051 ; CHECK-NEXT:    ret i32 [[R]]
4053   %xor = xor i32 %b, %a
4054   %nota = xor i32 %a, -1
4055   call void @use(i32 %nota)
4056   %or = or i32 %nota, %b
4057   %r = and i32 %xor, %or
4058   ret i32 %r
4061 define i32 @and_orn_xor_commute5(i32 %pa, i32 %pb) {
4062 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute5
4063 ; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4064 ; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4065 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4066 ; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4067 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOTA]]
4068 ; CHECK-NEXT:    call void @use(i32 [[OR]])
4069 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4070 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4071 ; CHECK-NEXT:    ret i32 [[R]]
4073   %a = mul i32 %pa, %pa
4074   %b = mul i32 %pb, %pb
4075   %xor = xor i32 %a, %b
4076   %nota = xor i32 %a, -1
4077   %or = or i32 %b, %nota
4078   call void @use(i32 %or)
4079   %r = and i32 %or, %xor
4080   ret i32 %r
4083 define i32 @and_orn_xor_commute6(i32 %pa, i32 %pb) {
4084 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute6
4085 ; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4086 ; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4087 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4088 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A]], [[B]]
4089 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
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]]
4096   %a = mul i32 %pa, %pa
4097   %b = mul i32 %pb, %pb
4098   %xor = xor i32 %a, %b
4099   call void @use(i32 %xor)
4100   %nota = xor i32 %a, -1
4101   call void @use(i32 %nota)
4102   %or = or i32 %b, %nota
4103   %r = and i32 %xor, %or
4104   ret i32 %r
4107 define i32 @and_orn_xor_commute7(i32 %pa, i32 %pb) {
4108 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute7
4109 ; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4110 ; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4111 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4112 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[B]], [[A]]
4113 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
4114 ; CHECK-NEXT:    [[NOTA:%.*]] = xor i32 [[A]], -1
4115 ; CHECK-NEXT:    call void @use(i32 [[NOTA]])
4116 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B]], [[NOTA]]
4117 ; CHECK-NEXT:    call void @use(i32 [[OR]])
4118 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4119 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4120 ; CHECK-NEXT:    ret i32 [[R]]
4122   %a = mul i32 %pa, %pa
4123   %b = mul i32 %pb, %pb
4124   %xor = xor i32 %b, %a
4125   call void @use(i32 %xor)
4126   %nota = xor i32 %a, -1
4127   call void @use(i32 %nota)
4128   %or = or i32 %b, %nota
4129   call void @use(i32 %or)
4130   %r = and i32 %or, %xor
4131   ret i32 %r
4134 define i32 @and_orn_xor_commute8(i32 %pa, i32 %pb) {
4135 ; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute8
4136 ; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {
4137 ; CHECK-NEXT:    [[A:%.*]] = mul i32 [[PA]], [[PA]]
4138 ; CHECK-NEXT:    [[B:%.*]] = mul i32 [[PB]], [[PB]]
4139 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], -1
4140 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[B]], [[TMP1]]
4141 ; CHECK-NEXT:    ret i32 [[R]]
4143   %a = mul i32 %pa, %pa
4144   %b = mul i32 %pb, %pb
4145   %xor = xor i32 %b, %a
4146   %nota = xor i32 %a, -1
4147   %or = or i32 %b, %nota
4148   %r = and i32 %xor, %or
4149   ret i32 %r
4152 define i32 @zext_zext_and_uses(i8 %x, i8 %y) {
4153 ; CHECK-LABEL: define {{[^@]+}}@zext_zext_and_uses
4154 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4155 ; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i32
4156 ; CHECK-NEXT:    call void @use(i32 [[ZX]])
4157 ; CHECK-NEXT:    [[ZY:%.*]] = zext i8 [[Y]] to i32
4158 ; CHECK-NEXT:    call void @use(i32 [[ZY]])
4159 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[ZX]], [[ZY]]
4160 ; CHECK-NEXT:    ret i32 [[R]]
4162   %zx = zext i8 %x to i32
4163   call void @use(i32 %zx)
4164   %zy = zext i8 %y to i32
4165   call void @use(i32 %zy)
4166   %r = and i32 %zx, %zy
4167   ret i32 %r
4170 define i32 @sext_sext_or_uses(i8 %x, i8 %y) {
4171 ; CHECK-LABEL: define {{[^@]+}}@sext_sext_or_uses
4172 ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4173 ; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i32
4174 ; CHECK-NEXT:    call void @use(i32 [[SX]])
4175 ; CHECK-NEXT:    [[SY:%.*]] = sext i8 [[Y]] to i32
4176 ; CHECK-NEXT:    call void @use(i32 [[SY]])
4177 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[SX]], [[SY]]
4178 ; CHECK-NEXT:    ret i32 [[R]]
4180   %sx = sext i8 %x to i32
4181   call void @use(i32 %sx)
4182   %sy = sext i8 %y to i32
4183   call void @use(i32 %sy)
4184   %r = or i32 %sx, %sy
4185   ret i32 %r
4188 define i32 @trunc_trunc_xor_uses(i65 %x, i65 %y) {
4189 ; CHECK-LABEL: define {{[^@]+}}@trunc_trunc_xor_uses
4190 ; CHECK-SAME: (i65 [[X:%.*]], i65 [[Y:%.*]]) {
4191 ; CHECK-NEXT:    [[SX:%.*]] = trunc i65 [[X]] to i32
4192 ; CHECK-NEXT:    call void @use(i32 [[SX]])
4193 ; CHECK-NEXT:    [[SY:%.*]] = trunc i65 [[Y]] to i32
4194 ; CHECK-NEXT:    call void @use(i32 [[SY]])
4195 ; CHECK-NEXT:    [[R:%.*]] = xor i32 [[SX]], [[SY]]
4196 ; CHECK-NEXT:    ret i32 [[R]]
4198   %sx = trunc i65 %x to i32
4199   call void @use(i32 %sx)
4200   %sy = trunc i65 %y to i32
4201   call void @use(i32 %sy)
4202   %r = xor i32 %sx, %sy
4203   ret i32 %r
4206 define i16 @and_zext_zext(i8 %x, i4 %y) {
4207 ; CHECK-LABEL: define {{[^@]+}}@and_zext_zext
4208 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4209 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y]] to i8
4210 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X]], [[TMP1]]
4211 ; CHECK-NEXT:    [[R:%.*]] = zext nneg i8 [[TMP2]] to i16
4212 ; CHECK-NEXT:    ret i16 [[R]]
4214   %zx = zext i8 %x to i16
4215   %zy = zext i4 %y to i16
4216   %r = and i16 %zx, %zy
4217   ret i16 %r
4220 define i16 @or_zext_zext(i8 %x, i4 %y) {
4221 ; CHECK-LABEL: define {{[^@]+}}@or_zext_zext
4222 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4223 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i4 [[Y]] to i8
4224 ; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
4225 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP2]] to i16
4226 ; CHECK-NEXT:    ret i16 [[R]]
4228   %zx = zext i8 %x to i16
4229   %zy = zext i4 %y to i16
4230   %r = or i16 %zy, %zx
4231   ret i16 %r
4234 define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) {
4235 ; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext
4236 ; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) {
4237 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i4> [[Y]] to <2 x i8>
4238 ; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i8> [[X]], [[TMP1]]
4239 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i8> [[TMP2]] to <2 x i16>
4240 ; CHECK-NEXT:    ret <2 x i16> [[R]]
4242   %zx = zext <2 x i8> %x to <2 x i16>
4243   %zy = zext <2 x i4> %y to <2 x i16>
4244   %r = xor <2 x i16> %zx, %zy
4245   ret <2 x i16> %r
4248 define i16 @and_sext_sext(i8 %x, i4 %y) {
4249 ; CHECK-LABEL: define {{[^@]+}}@and_sext_sext
4250 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4251 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
4252 ; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X]], [[TMP1]]
4253 ; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
4254 ; CHECK-NEXT:    ret i16 [[R]]
4256   %sx = sext i8 %x to i16
4257   %sy = sext i4 %y to i16
4258   %r = and i16 %sy, %sx
4259   ret i16 %r
4262 define i16 @or_sext_sext(i8 %x, i4 %y) {
4263 ; CHECK-LABEL: define {{[^@]+}}@or_sext_sext
4264 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4265 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
4266 ; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X]], [[TMP1]]
4267 ; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
4268 ; CHECK-NEXT:    ret i16 [[R]]
4270   %sx = sext i8 %x to i16
4271   %sy = sext i4 %y to i16
4272   %r = or i16 %sx, %sy
4273   ret i16 %r
4276 define i16 @xor_sext_sext(i8 %x, i4 %y) {
4277 ; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext
4278 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4279 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i4 [[Y]] to i8
4280 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i8 [[X]], [[TMP1]]
4281 ; CHECK-NEXT:    [[R:%.*]] = sext i8 [[TMP2]] to i16
4282 ; CHECK-NEXT:    ret i16 [[R]]
4284   %sx = sext i8 %x to i16
4285   %sy = sext i4 %y to i16
4286   %r = xor i16 %sx, %sy
4287   ret i16 %r
4290 ; negative test - mismatched casts
4292 define i16 @and_zext_sext(i8 %x, i4 %y) {
4293 ; CHECK-LABEL: define {{[^@]+}}@and_zext_sext
4294 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4295 ; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i16
4296 ; CHECK-NEXT:    [[SY:%.*]] = sext i4 [[Y]] to i16
4297 ; CHECK-NEXT:    [[R:%.*]] = and i16 [[ZX]], [[SY]]
4298 ; CHECK-NEXT:    ret i16 [[R]]
4300   %zx = zext i8 %x to i16
4301   %sy = sext i4 %y to i16
4302   %r = and i16 %zx, %sy
4303   ret i16 %r
4306 ; negative test - don't create an extra instruction
4308 define i32 @and_zext_zext_use1(i8 %x, i4 %y) {
4309 ; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use1
4310 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4311 ; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X]] to i32
4312 ; CHECK-NEXT:    call void @use(i32 [[ZX]])
4313 ; CHECK-NEXT:    [[ZY:%.*]] = zext i4 [[Y]] to i32
4314 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[ZX]], [[ZY]]
4315 ; CHECK-NEXT:    ret i32 [[R]]
4317   %zx = zext i8 %x to i32
4318   call void @use(i32 %zx)
4319   %zy = zext i4 %y to i32
4320   %r = and i32 %zx, %zy
4321   ret i32 %r
4324 ; negative test - don't create an extra instruction
4326 define i32 @or_sext_sext_use1(i8 %x, i4 %y) {
4327 ; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use1
4328 ; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4329 ; CHECK-NEXT:    [[SX:%.*]] = sext i8 [[X]] to i32
4330 ; CHECK-NEXT:    [[SY:%.*]] = sext i4 [[Y]] to i32
4331 ; CHECK-NEXT:    call void @use(i32 [[SY]])
4332 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[SX]], [[SY]]
4333 ; CHECK-NEXT:    ret i32 [[R]]
4335   %sx = sext i8 %x to i32
4336   %sy = sext i4 %y to i32
4337   call void @use(i32 %sy)
4338   %r = or i32 %sx, %sy
4339   ret i32 %r
4342 define i1 @PR56294(i8 %x) {
4343 ; CHECK-LABEL: define {{[^@]+}}@PR56294
4344 ; CHECK-SAME: (i8 [[X:%.*]]) {
4345 ; CHECK-NEXT:    ret i1 false
4347   %t2 = icmp eq i8 %x, 2
4348   %t3 = and i8 %x, 1
4349   %t4 = zext i1 %t2 to i32
4350   %t5 = zext i8 %t3 to i32
4351   %t6 = and i32 %t4, %t5
4352   %t7 = icmp ne i32 %t6, 0
4353   ret i1 %t7
4356 define i32 @canonicalize_logic_first_or0(i32 %x) {
4357 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0
4358 ; CHECK-SAME: (i32 [[X:%.*]]) {
4359 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X]], 15
4360 ; CHECK-NEXT:    [[R:%.*]] = add i32 [[TMP1]], 112
4361 ; CHECK-NEXT:    ret i32 [[R]]
4363   %a = add i32 %x, 112 ; 01110000
4364   %r = or i32 %a, 15   ; 00001111
4365   ret i32 %r
4368 define i32 @canonicalize_logic_first_or0_nsw(i32 %x) {
4369 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nsw
4370 ; CHECK-SAME: (i32 [[X:%.*]]) {
4371 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X]], 15
4372 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 112
4373 ; CHECK-NEXT:    ret i32 [[R]]
4375   %a = add nsw i32 %x, 112 ; 01110000
4376   %r = or i32 %a, 15   ; 00001111
4377   ret i32 %r
4380 define i32 @canonicalize_logic_first_or0_nswnuw(i32 %x) {
4381 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nswnuw
4382 ; CHECK-SAME: (i32 [[X:%.*]]) {
4383 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[X]], 15
4384 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[TMP1]], 112
4385 ; CHECK-NEXT:    ret i32 [[R]]
4387   %a = add nsw nuw i32 %x, 112 ; 01110000
4388   %r = or i32 %a, 15   ; 00001111
4389   ret i32 %r
4392 define <2 x i32> @canonicalize_logic_first_or_vector0(<2 x i32> %x) {
4393 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0
4394 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4395 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)
4396 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 112)
4397 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4399   %a = add <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>
4400   %r = or <2 x i32> <i32 15, i32 15>, %a    ; <0x0000000F, 0x0000000F>
4401   ret <2 x i32> %r
4404 define <2 x i32> @canonicalize_logic_first_or_vector0_nsw(<2 x i32> %x) {
4405 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nsw
4406 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4407 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)
4408 ; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 112)
4409 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4411   %a = add nsw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>
4412   %r = or <2 x i32> <i32 15, i32 15>, %a    ; <0x0000000F, 0x0000000F>
4413   ret <2 x i32> %r
4416 define <2 x i32> @canonicalize_logic_first_or_vector0_nswnuw(<2 x i32> %x) {
4417 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nswnuw
4418 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4419 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)
4420 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 112)
4421 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4423   %a = add nsw nuw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>
4424   %r = or <2 x i32> <i32 15, i32 15>, %a    ; <0x0000000F, 0x0000000F>
4425   ret <2 x i32> %r
4428 define <2 x i32> @canonicalize_logic_first_or_vector1(<2 x i32> %x) {
4429 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1
4430 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4431 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4432 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4433 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4435   %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4436   %r = or <2 x i32> <i32 32783, i32 2063>, %a           ; <0x0000800F, 0x0000080F>
4437   ret <2 x i32> %r
4440 define <2 x i32> @canonicalize_logic_first_or_vector1_nsw(<2 x i32> %x) {
4441 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nsw
4442 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4443 ; CHECK-NEXT:    [[A:%.*]] = add nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4444 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4445 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4447   %a = add nsw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4448   %r = or <2 x i32> <i32 32783, i32 2063>, %a           ; <0x0000800F, 0x0000080F>
4449   ret <2 x i32> %r
4452 define <2 x i32> @canonicalize_logic_first_or_vector1_nswnuw(<2 x i32> %x) {
4453 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nswnuw
4454 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4455 ; CHECK-NEXT:    [[A:%.*]] = add nuw nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4456 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4457 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4459   %a = add nsw nuw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4460   %r = or <2 x i32> <i32 32783, i32 2063>, %a           ; <0x0000800F, 0x0000080F>
4461   ret <2 x i32> %r
4464 define <2 x i32> @canonicalize_logic_first_or_vector2(<2 x i32> %x) {
4465 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector2
4466 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4467 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640>
4468 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>
4469 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4471   %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8>
4472   %r = or <2 x i32> <i32 32783, i32 2063>, %a             ; <0x0000800F, 0x0000080F>
4473   ret <2 x i32> %r
4476 define i32 @canonicalize_logic_first_or_mult_use1(i32 %x) {
4477 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_mult_use1
4478 ; CHECK-SAME: (i32 [[X:%.*]]) {
4479 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], 112
4480 ; CHECK-NEXT:    call void @use(i32 [[A]])
4481 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[A]], 15
4482 ; CHECK-NEXT:    ret i32 [[R]]
4484   %a = add i32 %x, 112 ; 01110000
4485   call void @use(i32 %a)
4486   %r = or i32 %a, 15   ; 00001111
4487   ret i32 %r
4490 define i32 @canonicalize_logic_first_or_bad_constraints2(i32 %x) {
4491 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_bad_constraints2
4492 ; CHECK-SAME: (i32 [[X:%.*]]) {
4493 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[X]], 112
4494 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[A]], 16
4495 ; CHECK-NEXT:    ret i32 [[R]]
4497   %a = add i32 %x, 112 ; 01110000
4498   %r = or i32 %a, 16   ; 00010000
4499   ret i32 %r
4502 define i8 @canonicalize_logic_first_and0(i8 %x) {
4503 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0
4504 ; CHECK-SAME: (i8 [[X:%.*]]) {
4505 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -10
4506 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[TMP1]], 48
4507 ; CHECK-NEXT:    ret i8 [[R]]
4509   %b = add i8 %x, 48    ;  00110000
4510   %r = and i8 %b, -10   ;  11110110
4511   ret i8 %r
4514 define i8 @canonicalize_logic_first_and0_nsw(i8 %x) {
4515 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nsw
4516 ; CHECK-SAME: (i8 [[X:%.*]]) {
4517 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -10
4518 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[TMP1]], 48
4519 ; CHECK-NEXT:    ret i8 [[R]]
4521   %b = add nsw i8 %x, 48    ;  00110000
4522   %r = and i8 %b, -10   ;  11110110
4523   ret i8 %r
4526 define i8 @canonicalize_logic_first_and0_nswnuw(i8 %x) {
4527 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nswnuw
4528 ; CHECK-SAME: (i8 [[X:%.*]]) {
4529 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], -10
4530 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i8 [[TMP1]], 48
4531 ; CHECK-NEXT:    ret i8 [[R]]
4533   %b = add nsw nuw i8 %x, 48    ;  00110000
4534   %r = and i8 %b, -10   ;  11110110
4535   ret i8 %r
4538 define <2 x i8> @canonicalize_logic_first_and_vector0(<2 x i8> %x) {
4539 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0
4540 ; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4541 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)
4542 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[TMP1]], splat (i8 48)
4543 ; CHECK-NEXT:    ret <2 x i8> [[R]]
4545   %a = add <2 x i8> <i8 48, i8 48>, %x
4546   %r = and <2 x i8> <i8 -10, i8 -10>, %a
4547   ret <2 x i8> %r
4550 define <2 x i8> @canonicalize_logic_first_and_vector0_nsw(<2 x i8> %x) {
4551 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nsw
4552 ; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4553 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)
4554 ; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i8> [[TMP1]], splat (i8 48)
4555 ; CHECK-NEXT:    ret <2 x i8> [[R]]
4557   %a = add nsw <2 x i8> <i8 48, i8 48>, %x
4558   %r = and <2 x i8> <i8 -10, i8 -10>, %a
4559   ret <2 x i8> %r
4562 define <2 x i8> @canonicalize_logic_first_and_vector0_nswnuw(<2 x i8> %x) {
4563 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nswnuw
4564 ; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4565 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)
4566 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i8> [[TMP1]], splat (i8 48)
4567 ; CHECK-NEXT:    ret <2 x i8> [[R]]
4569   %a = add nsw nuw <2 x i8> <i8 48, i8 48>, %x
4570   %r = and <2 x i8> <i8 -10, i8 -10>, %a
4571   ret <2 x i8> %r
4574 ; element-wise the constants match constraints
4575 define <2 x i8> @canonicalize_logic_first_and_vector1(<2 x i8> %x) {
4576 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector1
4577 ; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
4578 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[X]], <i8 48, i8 32>
4579 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i8> [[A]], <i8 -10, i8 -4>
4580 ; CHECK-NEXT:    ret <2 x i8> [[R]]
4582   %a = add <2 x i8> <i8 48, i8 32>, %x
4583   %r = and <2 x i8> <i8 -10, i8 -4>, %a
4584   ret <2 x i8> %r
4587 ; elementwise these constants do match constraints needed to canonicalize
4588 ; logic op first then math op
4589 define <2 x i32> @canonicalize_logic_first_and_vector2(<2 x i32> %x) {
4590 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector2
4591 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4592 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], splat (i32 612368384)
4593 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768>
4594 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4596   %a = add <2 x i32> <i32 612368384, i32 612368384>, %x ; <0x24800000, 0x24800000>
4597   %r = and <2 x i32> <i32 -65536, i32 -32768>, %a       ; <0xFFFF0000, 0xFFFF8000>
4598   ret <2 x i32> %r
4601 define <2 x i32> @canonicalize_logic_first_and_vector3(<2 x i32> %x) {
4602 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector3
4603 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4604 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 32768, i32 16384>
4605 ; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768>
4606 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4608   %a = add <2 x i32> <i32 32768, i32 16384>, %x   ; <0x00008000, 0x00004000>
4609   %r = and <2 x i32> <i32 -65536, i32 -32768>, %a ; <0xFFFF0000, 0xFFFF8000>
4610   ret <2 x i32> %r
4613 define i8 @canonicalize_logic_first_and_mult_use1(i8 %x) {
4614 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_mult_use1
4615 ; CHECK-SAME: (i8 [[X:%.*]]) {
4616 ; CHECK-NEXT:    [[B:%.*]] = add i8 [[X]], 48
4617 ; CHECK-NEXT:    call void @use_i8(i8 [[B]])
4618 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], -10
4619 ; CHECK-NEXT:    ret i8 [[R]]
4621   %b = add i8 %x, 48    ;  00110000
4622   call void @use_i8(i8 %b)
4623   %r = and i8 %b, -10   ;  11110110
4624   ret i8 %r
4627 define i8 @canonicalize_logic_first_and_bad_constraints2(i8 %x) {
4628 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_bad_constraints2
4629 ; CHECK-SAME: (i8 [[X:%.*]]) {
4630 ; CHECK-NEXT:    [[B:%.*]] = add i8 [[X]], 48
4631 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[B]], -26
4632 ; CHECK-NEXT:    ret i8 [[R]]
4634   %b = add i8 %x, 48    ;  00110000
4635   %r = and i8 %b, -26   ;  11100110
4636   ret i8 %r
4639 define i8 @canonicalize_logic_first_xor_0(i8 %x) {
4640 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0
4641 ; CHECK-SAME: (i8 [[X:%.*]]) {
4642 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], 31
4643 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[TMP1]], 96
4644 ; CHECK-NEXT:    ret i8 [[R]]
4646   %a = add i8 %x, 96  ; 01100000
4647   %r = xor i8 %a, 31  ; 00011111
4648   ret i8 %r
4651 define i8 @canonicalize_logic_first_xor_0_nsw(i8 %x) {
4652 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nsw
4653 ; CHECK-SAME: (i8 [[X:%.*]]) {
4654 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], 31
4655 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[TMP1]], 96
4656 ; CHECK-NEXT:    ret i8 [[R]]
4658   %a = add nsw i8 %x, 96  ; 01100000
4659   %r = xor i8 %a, 31  ; 00011111
4660   ret i8 %r
4663 define i8 @canonicalize_logic_first_xor_0_nswnuw(i8 %x) {
4664 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nswnuw
4665 ; CHECK-SAME: (i8 [[X:%.*]]) {
4666 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X]], 31
4667 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i8 [[TMP1]], 96
4668 ; CHECK-NEXT:    ret i8 [[R]]
4670   %a = add nsw nuw i8 %x, 96  ; 01100000
4671   %r = xor i8 %a, 31  ; 00011111
4672   ret i8 %r
4675 define <2 x i32> @canonicalize_logic_first_xor_vector0(<2 x i32> %x) {
4676 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0
4677 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4678 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)
4679 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 -8388608)
4680 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4682   %a = add <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>
4683   %r = xor <2 x i32> <i32 32783, i32 32783>, %a       ; <0x0000800F, 0x0000800F>
4684   ret <2 x i32> %r
4687 define <2 x i32> @canonicalize_logic_first_xor_vector0_nsw(<2 x i32> %x) {
4688 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nsw
4689 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4690 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)
4691 ; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 -8388608)
4692 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4694   %a = add nsw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>
4695   %r = xor <2 x i32> <i32 32783, i32 32783>, %a       ; <0x0000800F, 0x0000800F>
4696   ret <2 x i32> %r
4699 define <2 x i32> @canonicalize_logic_first_xor_vector0_nswnuw(<2 x i32> %x) {
4700 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nswnuw
4701 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4702 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)
4703 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 -8388608)
4704 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4706   %a = add nsw nuw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>
4707   %r = xor <2 x i32> <i32 32783, i32 32783>, %a       ; <0x0000800F, 0x0000800F>
4708   ret <2 x i32> %r
4711 define <2 x i32> @canonicalize_logic_first_xor_vector1(<2 x i32> %x) {
4712 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector1
4713 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4714 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176>
4715 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063>
4716 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4718   %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>
4719   %r = xor <2 x i32> <i32 32783, i32 2063>, %a          ; <0x0000800F, 0x0000080F>
4720   ret <2 x i32> %r
4723 define <2 x i32> @canonicalize_logic_first_xor_vector2(<2 x i32> %x) {
4724 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector2
4725 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
4726 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640>
4727 ; CHECK-NEXT:    [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063>
4728 ; CHECK-NEXT:    ret <2 x i32> [[R]]
4730   %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8>
4731   %r = xor <2 x i32> <i32 32783, i32 2063>, %a            ; <0x0000800F, 0x0000080F>
4732   ret <2 x i32> %r
4735 define i8 @canonicalize_logic_first_xor_mult_use1(i8 %x) {
4736 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_mult_use1
4737 ; CHECK-SAME: (i8 [[X:%.*]]) {
4738 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[X]], 96
4739 ; CHECK-NEXT:    call void @use_i8(i8 [[A]])
4740 ; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], 31
4741 ; CHECK-NEXT:    ret i8 [[R]]
4743   %a = add i8 %x, 96  ; 01100000
4744   call void @use_i8(i8 %a)
4745   %r = xor i8 %a, 31  ; 00011111
4746   ret i8 %r
4749 define i8 @canonicalize_logic_first_xor_bad_constants2(i8 %x) {
4750 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_bad_constants2
4751 ; CHECK-SAME: (i8 [[X:%.*]]) {
4752 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[X]], 96
4753 ; CHECK-NEXT:    [[R:%.*]] = xor i8 [[A]], 32
4754 ; CHECK-NEXT:    ret i8 [[R]]
4756   %a = add i8 %x, 96  ; 01100000
4757   %r = xor i8 %a, 32  ; 00100000
4758   ret i8 %r
4761 @g = external global i8
4763 define i32 @canonicalize_logic_first_constexpr(i32 %x) {
4764 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr
4765 ; CHECK-SAME: (i32 [[X:%.*]]) {
4766 ; CHECK-NEXT:    [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -10
4767 ; CHECK-NEXT:    ret i32 [[R]]
4769   %a = add i32 ptrtoint (ptr @g to i32), 48
4770   %r = and i32 %a, -10
4771   ret i32 %r
4774 define i32 @canonicalize_logic_first_constexpr_nuw(i32 %x) {
4775 ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr_nuw
4776 ; CHECK-SAME: (i32 [[X:%.*]]) {
4777 ; CHECK-NEXT:    [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -10
4778 ; CHECK-NEXT:    ret i32 [[R]]
4780   %a = add nuw i32 ptrtoint (ptr @g to i32), 48
4781   %r = and i32 %a, -10
4782   ret i32 %r
4785 define i1 @test_and_xor_freely_invertable(i32 %x, i32 %y, i1 %z) {
4786 ; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable
4787 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) {
4788 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[X]], [[Y]]
4789 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP]], [[Z]]
4790 ; CHECK-NEXT:    ret i1 [[AND]]
4792   %cmp = icmp sgt i32 %x, %y
4793   %xor = xor i1 %cmp, %z
4794   %and = and i1 %xor, %z
4795   ret i1 %and
4798 define i1 @test_and_xor_freely_invertable_multiuse(i32 %x, i32 %y, i1 %z) {
4799 ; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable_multiuse
4800 ; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) {
4801 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]
4802 ; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])
4803 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[CMP]], true
4804 ; CHECK-NEXT:    [[AND:%.*]] = and i1 [[Z]], [[TMP1]]
4805 ; CHECK-NEXT:    ret i1 [[AND]]
4807   %cmp = icmp sgt i32 %x, %y
4808   call void @use_i1(i1 %cmp)
4809   %xor = xor i1 %cmp, %z
4810   %and = and i1 %xor, %z
4811   ret i1 %and