1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
6 ; a & (a ^ b) --> a & ~b
8 define i32 @and_xor_common_op(i32 %pa, i32 %pb) {
9 ; CHECK-LABEL: @and_xor_common_op(
10 ; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]]
11 ; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB:%.*]]
12 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
13 ; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]]
14 ; CHECK-NEXT: ret i32 [[R]]
16 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
17 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization
23 ; a & (b ^ a) --> a & ~b
25 define i32 @and_xor_common_op_commute1(i32 %pa, i32 %pb) {
26 ; CHECK-LABEL: @and_xor_common_op_commute1(
27 ; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]]
28 ; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB:%.*]]
29 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
30 ; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]]
31 ; CHECK-NEXT: ret i32 [[R]]
33 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
34 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization
40 ; (b ^ a) & a --> a & ~b
42 define i32 @and_xor_common_op_commute2(i32 %pa, i32 %pb) {
43 ; CHECK-LABEL: @and_xor_common_op_commute2(
44 ; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]]
45 ; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB:%.*]]
46 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
47 ; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]]
48 ; CHECK-NEXT: ret i32 [[R]]
50 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization
51 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization
57 ; (a ^ b) & a --> a & ~b
59 define <2 x i32> @and_xor_common_op_commute3(<2 x i32> %pa, <2 x i32> %pb) {
60 ; CHECK-LABEL: @and_xor_common_op_commute3(
61 ; CHECK-NEXT: [[A:%.*]] = udiv <2 x i32> <i32 42, i32 43>, [[PA:%.*]]
62 ; CHECK-NEXT: [[B:%.*]] = udiv <2 x i32> <i32 43, i32 42>, [[PB:%.*]]
63 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[B]], <i32 -1, i32 -1>
64 ; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], [[TMP1]]
65 ; CHECK-NEXT: ret <2 x i32> [[R]]
67 %a = udiv <2 x i32> <i32 42, i32 43>, %pa ; thwart complexity-based canonicalization
68 %b = udiv <2 x i32> <i32 43, i32 42>, %pb ; thwart complexity-based canonicalization
69 %xor = xor <2 x i32> %a, %b
70 %r = and <2 x i32> %xor, %a
74 ; It's ok to match a common constant.
75 ; The xor should be a 'not' op (-1 constant).
77 define <4 x i32> @and_xor_common_op_constant(<4 x i32> %A) {
78 ; CHECK-LABEL: @and_xor_common_op_constant(
79 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[A:%.*]], <i32 -1, i32 -1, i32 -1, i32 -1>
80 ; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[TMP1]], <i32 1, i32 2, i32 3, i32 4>
81 ; CHECK-NEXT: ret <4 x i32> [[TMP2]]
83 %1 = xor <4 x i32> %A, <i32 1, i32 2, i32 3, i32 4>
84 %2 = and <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %1
88 ; a & (a ^ ~b) --> a & b
90 define i32 @and_xor_not_common_op(i32 %a, i32 %b) {
91 ; CHECK-LABEL: @and_xor_not_common_op(
92 ; CHECK-NEXT: [[T4:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
93 ; CHECK-NEXT: ret i32 [[T4]]
101 ; a & (a ^ ~b) --> a & b
103 define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, i32* %dst) {
104 ; CHECK-LABEL: @and_xor_not_common_op_extrause(
105 ; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B:%.*]], -1
106 ; CHECK-NEXT: store i32 [[B2]], i32* [[DST:%.*]], align 4
107 ; CHECK-NEXT: [[T4:%.*]] = and i32 [[A:%.*]], [[B]]
108 ; CHECK-NEXT: ret i32 [[T4]]
111 store i32 %b2, i32* %dst
112 %t2 = xor i32 %a, %b2
113 %t4 = and i32 %t2, %a
117 ; a & ~(a ^ b) --> a & b
119 define i32 @and_not_xor_common_op(i32 %a, i32 %b) {
120 ; CHECK-LABEL: @and_not_xor_common_op(
121 ; CHECK-NEXT: [[T4:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
122 ; CHECK-NEXT: ret i32 [[T4]]
125 %t2 = xor i32 %b2, -1
126 %t4 = and i32 %t2, %a
131 define i32 @and_not_xor_common_op_commutative(i32 %b) {
132 ; CHECK-LABEL: @and_not_xor_common_op_commutative(
133 ; CHECK-NEXT: [[A:%.*]] = call i32 @gen32()
134 ; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B:%.*]]
135 ; CHECK-NEXT: ret i32 [[T4]]
137 %a = call i32 @gen32()
138 %b2 = xor i32 %a, %b ; swapped order
139 %t2 = xor i32 %b2, -1
140 %t4 = and i32 %a, %t2 ; swapped order
145 ; (x & y) | (x ^ y) -> x | y
147 define i64 @or(i64 %x, i64 %y) {
149 ; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y:%.*]], [[X:%.*]]
150 ; CHECK-NEXT: ret i64 [[TMP1]]
158 ; (x & y) + (x ^ y) -> x | y
160 define i64 @or2(i64 %x, i64 %y) {
162 ; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y:%.*]], [[X:%.*]]
163 ; CHECK-NEXT: ret i64 [[TMP1]]
171 ; PR37098 - https://bugs.llvm.org/show_bug.cgi?id=37098
172 ; Reassociate bitwise logic to eliminate a shift.
173 ; There are 4 commuted * 3 shift ops * 3 logic ops = 36 potential variations of this fold.
174 ; Mix the commutation options to provide coverage using less tests.
176 define i8 @and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
177 ; CHECK-LABEL: @and_shl(
178 ; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]]
179 ; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]]
180 ; CHECK-NEXT: [[A:%.*]] = and i8 [[SX]], [[Z:%.*]]
181 ; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]]
182 ; CHECK-NEXT: ret i8 [[R]]
184 %sx = shl i8 %x, %shamt
185 %sy = shl i8 %y, %shamt
191 define i8 @or_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
192 ; CHECK-LABEL: @or_shl(
193 ; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]]
194 ; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]]
195 ; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]]
196 ; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[SY]]
197 ; CHECK-NEXT: ret i8 [[R]]
199 %sx = shl i8 %x, %shamt
200 %sy = shl i8 %y, %shamt
206 define i8 @xor_shl(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
207 ; CHECK-LABEL: @xor_shl(
208 ; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]]
209 ; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]]
210 ; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]]
211 ; CHECK-NEXT: [[A:%.*]] = xor i8 [[Z]], [[SX]]
212 ; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[SY]]
213 ; CHECK-NEXT: ret i8 [[R]]
215 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
216 %sx = shl i8 %x, %shamt
217 %sy = shl i8 %y, %shamt
223 define i8 @and_lshr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
224 ; CHECK-LABEL: @and_lshr(
225 ; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]]
226 ; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
227 ; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
228 ; CHECK-NEXT: [[A:%.*]] = and i8 [[Z]], [[SX]]
229 ; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]]
230 ; CHECK-NEXT: ret i8 [[R]]
232 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
233 %sx = lshr i8 %x, %shamt
234 %sy = lshr i8 %y, %shamt
240 define i8 @or_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {
241 ; CHECK-LABEL: @or_lshr(
242 ; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
243 ; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
244 ; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]]
245 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]]
246 ; CHECK-NEXT: ret i8 [[R]]
248 %sx = lshr i8 %x, %shamt
249 %sy = lshr i8 %y, %shamt
255 define i8 @xor_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {
256 ; CHECK-LABEL: @xor_lshr(
257 ; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
258 ; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
259 ; CHECK-NEXT: [[A:%.*]] = xor i8 [[SX]], [[Z:%.*]]
260 ; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[SY]]
261 ; CHECK-NEXT: ret i8 [[R]]
263 %sx = lshr i8 %x, %shamt
264 %sy = lshr i8 %y, %shamt
270 define i8 @and_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
271 ; CHECK-LABEL: @and_ashr(
272 ; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]]
273 ; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
274 ; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
275 ; CHECK-NEXT: [[A:%.*]] = and i8 [[Z]], [[SX]]
276 ; CHECK-NEXT: [[R:%.*]] = and i8 [[A]], [[SY]]
277 ; CHECK-NEXT: ret i8 [[R]]
279 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
280 %sx = ashr i8 %x, %shamt
281 %sy = ashr i8 %y, %shamt
287 define i8 @or_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {
288 ; CHECK-LABEL: @or_ashr(
289 ; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]]
290 ; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]]
291 ; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]]
292 ; CHECK-NEXT: [[A:%.*]] = or i8 [[Z]], [[SX]]
293 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]]
294 ; CHECK-NEXT: ret i8 [[R]]
296 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization
297 %sx = ashr i8 %x, %shamt
298 %sy = ashr i8 %y, %shamt
304 define <2 x i8> @xor_ashr(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z, <2 x i8> %shamt) {
305 ; CHECK-LABEL: @xor_ashr(
306 ; CHECK-NEXT: [[SX:%.*]] = ashr <2 x i8> [[X:%.*]], [[SHAMT:%.*]]
307 ; CHECK-NEXT: [[SY:%.*]] = ashr <2 x i8> [[Y:%.*]], [[SHAMT]]
308 ; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> [[SX]], [[Z:%.*]]
309 ; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[A]], [[SY]]
310 ; CHECK-NEXT: ret <2 x i8> [[R]]
312 %sx = ashr <2 x i8> %x, %shamt
313 %sy = ashr <2 x i8> %y, %shamt
314 %a = xor <2 x i8> %sx, %z
315 %r = xor <2 x i8> %a, %sy
319 ; Negative test - different logic ops
321 define i8 @or_and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
322 ; CHECK-LABEL: @or_and_shl(
323 ; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]]
324 ; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]]
325 ; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]]
326 ; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]]
327 ; CHECK-NEXT: ret i8 [[R]]
329 %sx = shl i8 %x, %shamt
330 %sy = shl i8 %y, %shamt
336 ; Negative test - different shift ops
338 define i8 @or_lshr_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {
339 ; CHECK-LABEL: @or_lshr_shl(
340 ; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
341 ; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]]
342 ; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]]
343 ; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[SY]]
344 ; CHECK-NEXT: ret i8 [[R]]
346 %sx = lshr i8 %x, %shamt
347 %sy = shl i8 %y, %shamt
353 ; Negative test - different shift amounts
355 define i8 @or_lshr_shamt2(i8 %x, i8 %y, i8 %z, i8 %shamt) {
356 ; CHECK-LABEL: @or_lshr_shamt2(
357 ; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], 5
358 ; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT:%.*]]
359 ; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]]
360 ; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]]
361 ; CHECK-NEXT: ret i8 [[R]]
364 %sy = lshr i8 %y, %shamt
370 ; Negative test - multi-use
372 define i8 @xor_lshr_multiuse(i8 %x, i8 %y, i8 %z, i8 %shamt) {
373 ; CHECK-LABEL: @xor_lshr_multiuse(
374 ; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]]
375 ; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]]
376 ; CHECK-NEXT: [[A:%.*]] = xor i8 [[SX]], [[Z:%.*]]
377 ; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[SY]]
378 ; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[A]], [[R]]
379 ; CHECK-NEXT: ret i8 [[R2]]
381 %sx = lshr i8 %x, %shamt
382 %sy = lshr i8 %y, %shamt
389 ; Reassociate chains of extend(X) | (extend(Y) | Z).
390 ; Check that logical op is performed on a smaller type and then extended.
392 define i64 @sext_or_chain(i64 %a, i16 %b, i16 %c) {
393 ; CHECK-LABEL: @sext_or_chain(
394 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B:%.*]] to i64
395 ; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C:%.*]] to i64
396 ; CHECK-NEXT: [[OR:%.*]] = or i64 [[CONV]], [[A:%.*]]
397 ; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
398 ; CHECK-NEXT: ret i64 [[OR2]]
400 %conv = sext i16 %b to i64
401 %conv2 = sext i16 %c to i64
402 %or = or i64 %a, %conv
403 %or2 = or i64 %or, %conv2
407 define i64 @zext_or_chain(i64 %a, i16 %b, i16 %c) {
408 ; CHECK-LABEL: @zext_or_chain(
409 ; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B:%.*]] to i64
410 ; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C:%.*]] to i64
411 ; CHECK-NEXT: [[OR:%.*]] = or i64 [[CONV]], [[A:%.*]]
412 ; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
413 ; CHECK-NEXT: ret i64 [[OR2]]
415 %conv = zext i16 %b to i64
416 %conv2 = zext i16 %c to i64
417 %or = or i64 %a, %conv
418 %or2 = or i64 %or, %conv2
422 define i64 @sext_and_chain(i64 %a, i16 %b, i16 %c) {
423 ; CHECK-LABEL: @sext_and_chain(
424 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B:%.*]] to i64
425 ; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C:%.*]] to i64
426 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[CONV]], [[A:%.*]]
427 ; CHECK-NEXT: [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]
428 ; CHECK-NEXT: ret i64 [[AND2]]
430 %conv = sext i16 %b to i64
431 %conv2 = sext i16 %c to i64
432 %and = and i64 %a, %conv
433 %and2 = and i64 %and, %conv2
437 define i64 @zext_and_chain(i64 %a, i16 %b, i16 %c) {
438 ; CHECK-LABEL: @zext_and_chain(
439 ; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B:%.*]] to i64
440 ; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C:%.*]] to i64
441 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[CONV]], [[A:%.*]]
442 ; CHECK-NEXT: [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]
443 ; CHECK-NEXT: ret i64 [[AND2]]
445 %conv = zext i16 %b to i64
446 %conv2 = zext i16 %c to i64
447 %and = and i64 %a, %conv
448 %and2 = and i64 %and, %conv2
452 define i64 @sext_xor_chain(i64 %a, i16 %b, i16 %c) {
453 ; CHECK-LABEL: @sext_xor_chain(
454 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B:%.*]] to i64
455 ; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C:%.*]] to i64
456 ; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[CONV]], [[A:%.*]]
457 ; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]
458 ; CHECK-NEXT: ret i64 [[XOR2]]
460 %conv = sext i16 %b to i64
461 %conv2 = sext i16 %c to i64
462 %xor = xor i64 %a, %conv
463 %xor2 = xor i64 %xor, %conv2
467 define i64 @zext_xor_chain(i64 %a, i16 %b, i16 %c) {
468 ; CHECK-LABEL: @zext_xor_chain(
469 ; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B:%.*]] to i64
470 ; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C:%.*]] to i64
471 ; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[CONV]], [[A:%.*]]
472 ; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]
473 ; CHECK-NEXT: ret i64 [[XOR2]]
475 %conv = zext i16 %b to i64
476 %conv2 = zext i16 %c to i64
477 %xor = xor i64 %a, %conv
478 %xor2 = xor i64 %xor, %conv2
482 ; Negative test with more uses.
483 define i64 @sext_or_chain_two_uses1(i64 %a, i16 %b, i16 %c, i64 %d) {
484 ; CHECK-LABEL: @sext_or_chain_two_uses1(
485 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B:%.*]] to i64
486 ; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C:%.*]] to i64
487 ; CHECK-NEXT: [[OR:%.*]] = or i64 [[CONV]], [[A:%.*]]
488 ; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
489 ; CHECK-NEXT: [[USE:%.*]] = udiv i64 [[OR]], [[D:%.*]]
490 ; CHECK-NEXT: [[RETVAL:%.*]] = udiv i64 [[OR2]], [[USE]]
491 ; CHECK-NEXT: ret i64 [[RETVAL]]
493 %conv = sext i16 %b to i64
494 %conv2 = sext i16 %c to i64
496 %or = or i64 %a, %conv
497 %or2 = or i64 %or, %conv2
498 %use = udiv i64 %or, %d
499 %retval = udiv i64 %or2, %use
502 define i64 @sext_or_chain_two_uses2(i64 %a, i16 %b, i16 %c, i64 %d) {
503 ; CHECK-LABEL: @sext_or_chain_two_uses2(
504 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B:%.*]] to i64
505 ; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C:%.*]] to i64
506 ; CHECK-NEXT: [[OR:%.*]] = or i64 [[CONV]], [[A:%.*]]
507 ; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]
508 ; CHECK-NEXT: [[USE1:%.*]] = udiv i64 [[OR2]], [[D:%.*]]
509 ; CHECK-NEXT: [[USE2:%.*]] = udiv i64 [[OR2]], [[USE1]]
510 ; CHECK-NEXT: ret i64 [[USE2]]
512 %conv = sext i16 %b to i64
513 %conv2 = sext i16 %c to i64
514 %or = or i64 %a, %conv
516 %or2 = or i64 %or, %conv2
517 %use1 = udiv i64 %or2, %d
518 %use2 = udiv i64 %or2, %use1
522 ; (a & ~b) & ~c --> a & ~(b | c)
524 define i32 @not_and_and_not(i32 %a0, i32 %b, i32 %c) {
525 ; CHECK-LABEL: @not_and_and_not(
526 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
527 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
528 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
529 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
530 ; CHECK-NEXT: ret i32 [[AND2]]
532 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
533 %not1 = xor i32 %b, -1
534 %not2 = xor i32 %c, -1
535 %and1 = and i32 %a, %not1
536 %and2 = and i32 %and1, %not2
540 define <4 x i64> @not_and_and_not_4i64(<4 x i64> %a0, <4 x i64> %b, <4 x i64> %c) {
541 ; CHECK-LABEL: @not_and_and_not_4i64(
542 ; CHECK-NEXT: [[A:%.*]] = sdiv <4 x i64> <i64 42, i64 42, i64 42, i64 42>, [[A0:%.*]]
543 ; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i64> [[B:%.*]], [[C:%.*]]
544 ; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i64> [[TMP1]], <i64 -1, i64 -1, i64 -1, i64 -1>
545 ; CHECK-NEXT: [[AND2:%.*]] = and <4 x i64> [[A]], [[TMP2]]
546 ; CHECK-NEXT: ret <4 x i64> [[AND2]]
548 %a = sdiv <4 x i64> <i64 42, i64 42, i64 42, i64 42>, %a0 ; thwart complexity-based canonicalization
549 %not1 = xor <4 x i64> %b, <i64 -1, i64 -1, i64 -1, i64 -1>
550 %not2 = xor <4 x i64> %c, <i64 -1, i64 -1, i64 -1, i64 -1>
551 %and1 = and <4 x i64> %a, %not1
552 %and2 = and <4 x i64> %and1, %not2
556 ; (~b & a) & ~c --> a & ~(b | c)
558 define i32 @not_and_and_not_commute1(i32 %a, i32 %b, i32 %c) {
559 ; CHECK-LABEL: @not_and_and_not_commute1(
560 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
561 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
562 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP2]], [[A:%.*]]
563 ; CHECK-NEXT: ret i32 [[AND2]]
565 %not1 = xor i32 %b, -1
566 %not2 = xor i32 %c, -1
567 %and1 = and i32 %not1, %a
568 %and2 = and i32 %and1, %not2
572 ; ~c & (a & ~b) --> a & ~(b | c)
574 define i32 @not_and_and_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {
575 ; CHECK-LABEL: @not_and_and_not_commute2_extra_not_use(
576 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
577 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C:%.*]], -1
578 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], [[C]]
579 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
580 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]]
581 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
582 ; CHECK-NEXT: ret i32 [[AND2]]
584 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
585 %not1 = xor i32 %b, -1
586 %not2 = xor i32 %c, -1
587 %and1 = and i32 %a, %not1
588 %and2 = and i32 %not2, %and1
589 call void @use(i32 %not2)
593 define i32 @not_and_and_not_extra_and1_use(i32 %a0, i32 %b, i32 %c) {
594 ; CHECK-LABEL: @not_and_and_not_extra_and1_use(
595 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
596 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[B:%.*]], -1
597 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C:%.*]], -1
598 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]]
599 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[NOT2]]
600 ; CHECK-NEXT: call void @use(i32 [[AND1]])
601 ; CHECK-NEXT: ret i32 [[AND2]]
603 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
604 %not1 = xor i32 %b, -1
605 %not2 = xor i32 %c, -1
606 %and1 = and i32 %a, %not1
607 %and2 = and i32 %and1, %not2
608 call void @use(i32 %and1)
612 ; (a | ~b) | ~c --> a | ~(b & c)
614 define i32 @not_or_or_not(i32 %a0, i32 %b, i32 %c) {
615 ; CHECK-LABEL: @not_or_or_not(
616 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
617 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
618 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
619 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
620 ; CHECK-NEXT: ret i32 [[OR2]]
622 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
623 %not1 = xor i32 %b, -1
624 %not2 = xor i32 %c, -1
625 %or1 = or i32 %a, %not1
626 %or2 = or i32 %or1, %not2
630 define <2 x i6> @not_or_or_not_2i6(<2 x i6> %a0, <2 x i6> %b, <2 x i6> %c) {
631 ; CHECK-LABEL: @not_or_or_not_2i6(
632 ; CHECK-NEXT: [[A:%.*]] = sdiv <2 x i6> <i6 3, i6 3>, [[A0:%.*]]
633 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i6> [[B:%.*]], [[C:%.*]]
634 ; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i6> [[TMP1]], <i6 -1, i6 -1>
635 ; CHECK-NEXT: [[OR2:%.*]] = or <2 x i6> [[A]], [[TMP2]]
636 ; CHECK-NEXT: ret <2 x i6> [[OR2]]
638 %a = sdiv <2 x i6> <i6 3, i6 3>, %a0 ; thwart complexity-based canonicalization
639 %not1 = xor <2 x i6> %b, <i6 -1, i6 -1>
640 %not2 = xor <2 x i6> %c, <i6 -1, i6 undef>
641 %or1 = or <2 x i6> %a, %not1
642 %or2 = or <2 x i6> %or1, %not2
646 ; (~b | a) | ~c --> a | ~(b & c)
648 define i32 @not_or_or_not_commute1(i32 %a, i32 %b, i32 %c) {
649 ; CHECK-LABEL: @not_or_or_not_commute1(
650 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
651 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
652 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP2]], [[A:%.*]]
653 ; CHECK-NEXT: ret i32 [[OR2]]
655 %not1 = xor i32 %b, -1
656 %not2 = xor i32 %c, -1
657 %or1 = or i32 %not1, %a
658 %or2 = or i32 %or1, %not2
662 ; ~c | (a | ~b) --> a | ~(b & c)
664 define i32 @not_or_or_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {
665 ; CHECK-LABEL: @not_or_or_not_commute2_extra_not_use(
666 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
667 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C:%.*]], -1
668 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B:%.*]], [[C]]
669 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
670 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]]
671 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
672 ; CHECK-NEXT: ret i32 [[OR2]]
674 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
675 %not1 = xor i32 %b, -1
676 %not2 = xor i32 %c, -1
677 %or1 = or i32 %a, %not1
678 %or2 = or i32 %not2, %or1
679 call void @use(i32 %not2)
683 define i32 @not_or_or_not_extra_or1_use(i32 %a0, i32 %b, i32 %c) {
684 ; CHECK-LABEL: @not_or_or_not_extra_or1_use(
685 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
686 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[B:%.*]], -1
687 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C:%.*]], -1
688 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
689 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[NOT2]]
690 ; CHECK-NEXT: call void @use(i32 [[OR1]])
691 ; CHECK-NEXT: ret i32 [[OR2]]
693 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
694 %not1 = xor i32 %b, -1
695 %not2 = xor i32 %c, -1
696 %or1 = or i32 %a, %not1
697 %or2 = or i32 %or1, %not2
698 call void @use(i32 %or1)
702 ; (c & ~(a | b)) | (b & ~(a | c)) --> ~a & (b ^ c)
704 define i32 @or_not_and(i32 %a, i32 %b, i32 %c) {
705 ; CHECK-LABEL: @or_not_and(
706 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
707 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
708 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
709 ; CHECK-NEXT: ret i32 [[OR3]]
712 %not1 = xor i32 %or1, -1
713 %and1 = and i32 %not1, %c
715 %not2 = xor i32 %or2, -1
716 %and2 = and i32 %not2, %b
717 %or3 = or i32 %and1, %and2
721 define i32 @or_not_and_commute1(i32 %a, i32 %b0, i32 %c) {
722 ; CHECK-LABEL: @or_not_and_commute1(
723 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
724 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
725 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
726 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
727 ; CHECK-NEXT: ret i32 [[OR3]]
729 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
731 %not1 = xor i32 %or1, -1
732 %and1 = and i32 %not1, %c
734 %not2 = xor i32 %or2, -1
735 %and2 = and i32 %b, %not2
736 %or3 = or i32 %and1, %and2
740 define i32 @or_not_and_commute2(i32 %a, i32 %b0, i32 %c) {
741 ; CHECK-LABEL: @or_not_and_commute2(
742 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
743 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
744 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
745 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
746 ; CHECK-NEXT: ret i32 [[OR3]]
748 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
750 %not1 = xor i32 %or1, -1
751 %and1 = and i32 %not1, %c
753 %not2 = xor i32 %or2, -1
754 %and2 = and i32 %b, %not2
755 %or3 = or i32 %and2, %and1
759 define i32 @or_not_and_commute3(i32 %a, i32 %b, i32 %c) {
760 ; CHECK-LABEL: @or_not_and_commute3(
761 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
762 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
763 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
764 ; CHECK-NEXT: ret i32 [[OR3]]
767 %not1 = xor i32 %or1, -1
768 %and1 = and i32 %not1, %c
770 %not2 = xor i32 %or2, -1
771 %and2 = and i32 %not2, %b
772 %or3 = or i32 %and1, %and2
776 define i32 @or_not_and_commute4(i32 %a, i32 %b, i32 %c0) {
777 ; CHECK-LABEL: @or_not_and_commute4(
778 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
779 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
780 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
781 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
782 ; CHECK-NEXT: ret i32 [[OR3]]
784 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
786 %not1 = xor i32 %or1, -1
787 %and1 = and i32 %c, %not1
789 %not2 = xor i32 %or2, -1
790 %and2 = and i32 %not2, %b
791 %or3 = or i32 %and1, %and2
795 define i32 @or_not_and_commute5(i32 %a0, i32 %b, i32 %c0) {
796 ; CHECK-LABEL: @or_not_and_commute5(
797 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
798 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
799 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
800 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
801 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
802 ; CHECK-NEXT: ret i32 [[OR3]]
804 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
805 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
807 %not1 = xor i32 %or1, -1
808 %and1 = and i32 %c, %not1
810 %not2 = xor i32 %or2, -1
811 %and2 = and i32 %not2, %b
812 %or3 = or i32 %and1, %and2
816 define i32 @or_not_and_commute6(i32 %a, i32 %b, i32 %c) {
817 ; CHECK-LABEL: @or_not_and_commute6(
818 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
819 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
820 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
821 ; CHECK-NEXT: ret i32 [[OR3]]
824 %not1 = xor i32 %or1, -1
825 %and1 = and i32 %not1, %c
827 %not2 = xor i32 %or2, -1
828 %and2 = and i32 %not2, %b
829 %or3 = or i32 %and1, %and2
833 define i32 @or_not_and_commute7(i32 %a, i32 %b, i32 %c) {
834 ; CHECK-LABEL: @or_not_and_commute7(
835 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
836 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A:%.*]], -1
837 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
838 ; CHECK-NEXT: ret i32 [[OR3]]
841 %not1 = xor i32 %or1, -1
842 %and1 = and i32 %not1, %c
844 %not2 = xor i32 %or2, -1
845 %and2 = and i32 %not2, %b
846 %or3 = or i32 %and1, %and2
850 define i32 @or_not_and_commute8(i32 %a0, i32 %b0, i32 %c) {
851 ; CHECK-LABEL: @or_not_and_commute8(
852 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
853 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
854 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
855 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
856 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
857 ; CHECK-NEXT: ret i32 [[OR3]]
859 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
860 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
862 %not1 = xor i32 %or1, -1
863 %and1 = and i32 %not1, %c
865 %not2 = xor i32 %or2, -1
866 %and2 = and i32 %b, %not2
867 %or3 = or i32 %and1, %and2
871 define i32 @or_not_and_commute9(i32 %a0, i32 %b0, i32 %c0) {
872 ; CHECK-LABEL: @or_not_and_commute9(
873 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
874 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
875 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
876 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]
877 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
878 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
879 ; CHECK-NEXT: ret i32 [[OR3]]
881 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
882 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
883 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
885 %not1 = xor i32 %or1, -1
886 %and1 = and i32 %not1, %c
888 %not2 = xor i32 %or2, -1
889 %and2 = and i32 %b, %not2
890 %or3 = or i32 %and1, %and2
894 define i32 @or_not_and_extra_not_use1(i32 %a, i32 %b, i32 %c) {
895 ; CHECK-LABEL: @or_not_and_extra_not_use1(
896 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
897 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
898 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
899 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
900 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
901 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
902 ; CHECK-NEXT: ret i32 [[OR3]]
905 %not1 = xor i32 %or1, -1
906 %and1 = and i32 %not1, %c
908 %not2 = xor i32 %or2, -1
909 %and2 = and i32 %not2, %b
910 %or3 = or i32 %and1, %and2
911 call void @use(i32 %not1)
915 define i32 @or_not_and_extra_not_use2(i32 %a, i32 %b, i32 %c) {
916 ; CHECK-LABEL: @or_not_and_extra_not_use2(
917 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
918 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
919 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[C:%.*]]
920 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]
921 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
922 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NOT2]], [[B]]
923 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
924 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
925 ; CHECK-NEXT: ret i32 [[OR3]]
928 %not1 = xor i32 %or1, -1
929 %and1 = and i32 %not1, %c
931 %not2 = xor i32 %or2, -1
932 %and2 = and i32 %not2, %b
933 %or3 = or i32 %and1, %and2
934 call void @use(i32 %not2)
938 define i32 @or_not_and_extra_and_use1(i32 %a, i32 %b, i32 %c) {
939 ; CHECK-LABEL: @or_not_and_extra_and_use1(
940 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
941 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
942 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[C:%.*]]
943 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]
944 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
945 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
946 ; CHECK-NEXT: call void @use(i32 [[AND1]])
947 ; CHECK-NEXT: ret i32 [[OR3]]
950 %not1 = xor i32 %or1, -1
951 %and1 = and i32 %not1, %c
953 %not2 = xor i32 %or2, -1
954 %and2 = and i32 %not2, %b
955 %or3 = or i32 %and1, %and2
956 call void @use(i32 %and1)
960 define i32 @or_not_and_extra_and_use2(i32 %a, i32 %b, i32 %c) {
961 ; CHECK-LABEL: @or_not_and_extra_and_use2(
962 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
963 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
964 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[C:%.*]]
965 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]
966 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
967 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NOT2]], [[B]]
968 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
969 ; CHECK-NEXT: call void @use(i32 [[AND2]])
970 ; CHECK-NEXT: ret i32 [[OR3]]
973 %not1 = xor i32 %or1, -1
974 %and1 = and i32 %not1, %c
976 %not2 = xor i32 %or2, -1
977 %and2 = and i32 %not2, %b
978 %or3 = or i32 %and1, %and2
979 call void @use(i32 %and2)
983 define i32 @or_not_and_extra_or_use1(i32 %a, i32 %b, i32 %c) {
984 ; CHECK-LABEL: @or_not_and_extra_or_use1(
985 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
986 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
987 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
988 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
989 ; CHECK-NEXT: call void @use(i32 [[OR1]])
990 ; CHECK-NEXT: ret i32 [[OR3]]
993 %not1 = xor i32 %or1, -1
994 %and1 = and i32 %not1, %c
996 %not2 = xor i32 %or2, -1
997 %and2 = and i32 %not2, %b
998 %or3 = or i32 %and1, %and2
999 call void @use(i32 %or1)
1003 define i32 @or_not_and_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1004 ; CHECK-LABEL: @or_not_and_extra_or_use2(
1005 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A:%.*]], [[C:%.*]]
1006 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C]]
1007 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1
1008 ; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]
1009 ; CHECK-NEXT: call void @use(i32 [[OR2]])
1010 ; CHECK-NEXT: ret i32 [[OR3]]
1012 %or1 = or i32 %a, %b
1013 %not1 = xor i32 %or1, -1
1014 %and1 = and i32 %not1, %c
1015 %or2 = or i32 %a, %c
1016 %not2 = xor i32 %or2, -1
1017 %and2 = and i32 %not2, %b
1018 %or3 = or i32 %and1, %and2
1019 call void @use(i32 %or2)
1023 define i32 @or_not_and_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {
1024 ; CHECK-LABEL: @or_not_and_wrong_c(
1025 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
1026 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1027 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[C:%.*]]
1028 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[D:%.*]]
1029 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1030 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NOT2]], [[B]]
1031 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1032 ; CHECK-NEXT: ret i32 [[OR3]]
1034 %or1 = or i32 %a, %b
1035 %not1 = xor i32 %or1, -1
1036 %and1 = and i32 %not1, %c
1037 %or2 = or i32 %a, %d
1038 %not2 = xor i32 %or2, -1
1039 %and2 = and i32 %not2, %b
1040 %or3 = or i32 %and1, %and2
1044 define i32 @or_not_and_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1045 ; CHECK-LABEL: @or_not_and_wrong_b(
1046 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
1047 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1048 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[C:%.*]]
1049 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]
1050 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1051 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NOT2]], [[D:%.*]]
1052 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]
1053 ; CHECK-NEXT: ret i32 [[OR3]]
1055 %or1 = or i32 %a, %b
1056 %not1 = xor i32 %or1, -1
1057 %and1 = and i32 %not1, %c
1058 %or2 = or i32 %a, %c
1059 %not2 = xor i32 %or2, -1
1060 %and2 = and i32 %not2, %d
1061 %or3 = or i32 %and1, %and2
1065 ; (c | ~(a & b)) & (b | ~(a & c)) --> ~(a & (b ^ c))
1067 define i32 @and_not_or(i32 %a, i32 %b, i32 %c) {
1068 ; CHECK-LABEL: @and_not_or(
1069 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
1070 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1071 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1072 ; CHECK-NEXT: ret i32 [[AND3]]
1074 %and1 = and i32 %a, %b
1075 %not1 = xor i32 %and1, -1
1076 %or1 = or i32 %not1, %c
1077 %and2 = and i32 %a, %c
1078 %not2 = xor i32 %and2, -1
1079 %or2 = or i32 %not2, %b
1080 %and3 = and i32 %or1, %or2
1084 define i32 @and_not_or_commute1(i32 %a, i32 %b0, i32 %c) {
1085 ; CHECK-LABEL: @and_not_or_commute1(
1086 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1087 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
1088 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1089 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1090 ; CHECK-NEXT: ret i32 [[AND3]]
1092 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1093 %and1 = and i32 %a, %b
1094 %not1 = xor i32 %and1, -1
1095 %or1 = or i32 %not1, %c
1096 %and2 = and i32 %a, %c
1097 %not2 = xor i32 %and2, -1
1098 %or2 = or i32 %b, %not2
1099 %and3 = and i32 %or1, %or2
1103 define i32 @and_not_or_commute2(i32 %a, i32 %b0, i32 %c) {
1104 ; CHECK-LABEL: @and_not_or_commute2(
1105 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1106 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
1107 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1108 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1109 ; CHECK-NEXT: ret i32 [[AND3]]
1111 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1112 %and1 = and i32 %a, %b
1113 %not1 = xor i32 %and1, -1
1114 %or1 = or i32 %not1, %c
1115 %and2 = and i32 %a, %c
1116 %not2 = xor i32 %and2, -1
1117 %or2 = or i32 %b, %not2
1118 %and3 = and i32 %or2, %or1
1122 define i32 @and_not_or_commute3(i32 %a, i32 %b, i32 %c) {
1123 ; CHECK-LABEL: @and_not_or_commute3(
1124 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
1125 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1126 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1127 ; CHECK-NEXT: ret i32 [[AND3]]
1129 %and1 = and i32 %b, %a
1130 %not1 = xor i32 %and1, -1
1131 %or1 = or i32 %not1, %c
1132 %and2 = and i32 %c, %a
1133 %not2 = xor i32 %and2, -1
1134 %or2 = or i32 %not2, %b
1135 %and3 = and i32 %or1, %or2
1139 define i32 @and_not_or_commute4(i32 %a, i32 %b, i32 %c0) {
1140 ; CHECK-LABEL: @and_not_or_commute4(
1141 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
1142 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
1143 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1144 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1145 ; CHECK-NEXT: ret i32 [[AND3]]
1147 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1148 %and1 = and i32 %a, %b
1149 %not1 = xor i32 %and1, -1
1150 %or1 = or i32 %c, %not1
1151 %and2 = and i32 %a, %c
1152 %not2 = xor i32 %and2, -1
1153 %or2 = or i32 %not2, %b
1154 %and3 = and i32 %or1, %or2
1158 define i32 @and_not_or_commute5(i32 %a0, i32 %b, i32 %c0) {
1159 ; CHECK-LABEL: @and_not_or_commute5(
1160 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
1161 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
1162 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
1163 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1164 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1165 ; CHECK-NEXT: ret i32 [[AND3]]
1167 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1168 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1169 %and1 = and i32 %a, %b
1170 %not1 = xor i32 %and1, -1
1171 %or1 = or i32 %c, %not1
1172 %and2 = and i32 %a, %c
1173 %not2 = xor i32 %and2, -1
1174 %or2 = or i32 %not2, %b
1175 %and3 = and i32 %or1, %or2
1179 define i32 @and_not_or_commute6(i32 %a, i32 %b, i32 %c) {
1180 ; CHECK-LABEL: @and_not_or_commute6(
1181 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
1182 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1183 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1184 ; CHECK-NEXT: ret i32 [[AND3]]
1186 %and1 = and i32 %a, %b
1187 %not1 = xor i32 %and1, -1
1188 %or1 = or i32 %not1, %c
1189 %and2 = and i32 %c, %a
1190 %not2 = xor i32 %and2, -1
1191 %or2 = or i32 %not2, %b
1192 %and3 = and i32 %or1, %or2
1196 define i32 @and_not_or_commute7(i32 %a, i32 %b, i32 %c) {
1197 ; CHECK-LABEL: @and_not_or_commute7(
1198 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
1199 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1200 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1201 ; CHECK-NEXT: ret i32 [[AND3]]
1203 %and1 = and i32 %b, %a
1204 %not1 = xor i32 %and1, -1
1205 %or1 = or i32 %not1, %c
1206 %and2 = and i32 %a, %c
1207 %not2 = xor i32 %and2, -1
1208 %or2 = or i32 %not2, %b
1209 %and3 = and i32 %or1, %or2
1213 define i32 @and_not_or_commute8(i32 %a0, i32 %b0, i32 %c) {
1214 ; CHECK-LABEL: @and_not_or_commute8(
1215 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
1216 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1217 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
1218 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1219 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1220 ; CHECK-NEXT: ret i32 [[AND3]]
1222 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1223 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1224 %and1 = and i32 %a, %b
1225 %not1 = xor i32 %and1, -1
1226 %or1 = or i32 %not1, %c
1227 %and2 = and i32 %c, %a
1228 %not2 = xor i32 %and2, -1
1229 %or2 = or i32 %b, %not2
1230 %and3 = and i32 %or1, %or2
1234 define i32 @and_not_or_commute9(i32 %a0, i32 %b0, i32 %c0) {
1235 ; CHECK-LABEL: @and_not_or_commute9(
1236 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
1237 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1238 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
1239 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1240 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1241 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1242 ; CHECK-NEXT: ret i32 [[AND3]]
1244 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
1245 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1246 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
1247 %and1 = and i32 %a, %b
1248 %not1 = xor i32 %and1, -1
1249 %or1 = or i32 %not1, %c
1250 %and2 = and i32 %a, %c
1251 %not2 = xor i32 %and2, -1
1252 %or2 = or i32 %b, %not2
1253 %and3 = and i32 %or1, %or2
1257 define i32 @and_not_or_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1258 ; CHECK-LABEL: @and_not_or_extra_not_use1(
1259 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1260 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1261 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
1262 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1263 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1264 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
1265 ; CHECK-NEXT: ret i32 [[AND3]]
1267 %and1 = and i32 %a, %b
1268 %not1 = xor i32 %and1, -1
1269 %or1 = or i32 %not1, %c
1270 %and2 = and i32 %a, %c
1271 %not2 = xor i32 %and2, -1
1272 %or2 = or i32 %not2, %b
1273 %and3 = and i32 %or1, %or2
1274 call void @use(i32 %not1)
1278 define i32 @and_not_or_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1279 ; CHECK-LABEL: @and_not_or_extra_not_use2(
1280 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1281 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1282 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[C:%.*]]
1283 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]
1284 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1285 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOT2]], [[B]]
1286 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1287 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
1288 ; CHECK-NEXT: ret i32 [[AND3]]
1290 %and1 = and i32 %a, %b
1291 %not1 = xor i32 %and1, -1
1292 %or1 = or i32 %not1, %c
1293 %and2 = and i32 %a, %c
1294 %not2 = xor i32 %and2, -1
1295 %or2 = or i32 %not2, %b
1296 %and3 = and i32 %or1, %or2
1297 call void @use(i32 %not2)
1301 define i32 @and_not_or_extra_and_use1(i32 %a, i32 %b, i32 %c) {
1302 ; CHECK-LABEL: @and_not_or_extra_and_use1(
1303 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1304 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1305 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[C:%.*]]
1306 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]
1307 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1308 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1309 ; CHECK-NEXT: call void @use(i32 [[OR1]])
1310 ; CHECK-NEXT: ret i32 [[AND3]]
1312 %and1 = and i32 %a, %b
1313 %not1 = xor i32 %and1, -1
1314 %or1 = or i32 %not1, %c
1315 %and2 = and i32 %a, %c
1316 %not2 = xor i32 %and2, -1
1317 %or2 = or i32 %not2, %b
1318 %and3 = and i32 %or1, %or2
1319 call void @use(i32 %or1)
1323 define i32 @and_not_or_extra_and_use2(i32 %a, i32 %b, i32 %c) {
1324 ; CHECK-LABEL: @and_not_or_extra_and_use2(
1325 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1326 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1327 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[C:%.*]]
1328 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]
1329 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1330 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOT2]], [[B]]
1331 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1332 ; CHECK-NEXT: call void @use(i32 [[OR2]])
1333 ; CHECK-NEXT: ret i32 [[AND3]]
1335 %and1 = and i32 %a, %b
1336 %not1 = xor i32 %and1, -1
1337 %or1 = or i32 %not1, %c
1338 %and2 = and i32 %a, %c
1339 %not2 = xor i32 %and2, -1
1340 %or2 = or i32 %not2, %b
1341 %and3 = and i32 %or1, %or2
1342 call void @use(i32 %or2)
1346 define i32 @and_not_or_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1347 ; CHECK-LABEL: @and_not_or_extra_or_use1(
1348 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1349 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
1350 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1351 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1352 ; CHECK-NEXT: call void @use(i32 [[AND1]])
1353 ; CHECK-NEXT: ret i32 [[AND3]]
1355 %and1 = and i32 %a, %b
1356 %not1 = xor i32 %and1, -1
1357 %or1 = or i32 %not1, %c
1358 %and2 = and i32 %a, %c
1359 %not2 = xor i32 %and2, -1
1360 %or2 = or i32 %not2, %b
1361 %and3 = and i32 %or1, %or2
1362 call void @use(i32 %and1)
1366 define i32 @and_not_or_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1367 ; CHECK-LABEL: @and_not_or_extra_or_use2(
1368 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A:%.*]], [[C:%.*]]
1369 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C]]
1370 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1371 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1372 ; CHECK-NEXT: call void @use(i32 [[AND2]])
1373 ; CHECK-NEXT: ret i32 [[AND3]]
1375 %and1 = and i32 %a, %b
1376 %not1 = xor i32 %and1, -1
1377 %or1 = or i32 %not1, %c
1378 %and2 = and i32 %a, %c
1379 %not2 = xor i32 %and2, -1
1380 %or2 = or i32 %not2, %b
1381 %and3 = and i32 %or1, %or2
1382 call void @use(i32 %and2)
1386 define i32 @and_not_or_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {
1387 ; CHECK-LABEL: @and_not_or_wrong_c(
1388 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1389 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1390 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[C:%.*]]
1391 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[D:%.*]]
1392 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1393 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOT2]], [[B]]
1394 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1395 ; CHECK-NEXT: ret i32 [[AND3]]
1397 %and1 = and i32 %a, %b
1398 %not1 = xor i32 %and1, -1
1399 %or1 = or i32 %not1, %c
1400 %and2 = and i32 %a, %d
1401 %not2 = xor i32 %and2, -1
1402 %or2 = or i32 %not2, %b
1403 %and3 = and i32 %or1, %or2
1407 define i32 @and_not_or_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1408 ; CHECK-LABEL: @and_not_or_wrong_b(
1409 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1410 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1411 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[C:%.*]]
1412 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]
1413 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1414 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOT2]], [[D:%.*]]
1415 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]
1416 ; CHECK-NEXT: ret i32 [[AND3]]
1418 %and1 = and i32 %a, %b
1419 %not1 = xor i32 %and1, -1
1420 %or1 = or i32 %not1, %c
1421 %and2 = and i32 %a, %c
1422 %not2 = xor i32 %and2, -1
1423 %or2 = or i32 %not2, %d
1424 %and3 = and i32 %or1, %or2
1428 ; (b & ~(a | c)) | ~(a | b) --> ~((b & c) | a)
1430 define i32 @or_and_not_not(i32 %a, i32 %b, i32 %c) {
1431 ; CHECK-LABEL: @or_and_not_not(
1432 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
1433 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1434 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1435 ; CHECK-NEXT: ret i32 [[OR3]]
1437 %or1 = or i32 %b, %a
1438 %not1 = xor i32 %or1, -1
1439 %or2 = or i32 %a, %c
1440 %not2 = xor i32 %or2, -1
1441 %and = and i32 %not2, %b
1442 %or3 = or i32 %and, %not1
1446 define i32 @or_and_not_not_commute1(i32 %a, i32 %b0, i32 %c) {
1447 ; CHECK-LABEL: @or_and_not_not_commute1(
1448 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1449 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C:%.*]]
1450 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1451 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1452 ; CHECK-NEXT: ret i32 [[OR3]]
1454 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1455 %or1 = or i32 %b, %a
1456 %not1 = xor i32 %or1, -1
1457 %or2 = or i32 %a, %c
1458 %not2 = xor i32 %or2, -1
1459 %and = and i32 %b, %not2
1460 %or3 = or i32 %and, %not1
1464 define i32 @or_and_not_not_commute2(i32 %a, i32 %b, i32 %c) {
1465 ; CHECK-LABEL: @or_and_not_not_commute2(
1466 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
1467 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1468 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1469 ; CHECK-NEXT: ret i32 [[OR3]]
1471 %or1 = or i32 %b, %a
1472 %not1 = xor i32 %or1, -1
1473 %or2 = or i32 %a, %c
1474 %not2 = xor i32 %or2, -1
1475 %and = and i32 %not2, %b
1476 %or3 = or i32 %and, %not1
1480 define i32 @or_and_not_not_commute3(i32 %a, i32 %b, i32 %c) {
1481 ; CHECK-LABEL: @or_and_not_not_commute3(
1482 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
1483 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1484 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1485 ; CHECK-NEXT: ret i32 [[OR3]]
1487 %or1 = or i32 %b, %a
1488 %not1 = xor i32 %or1, -1
1489 %or2 = or i32 %c, %a
1490 %not2 = xor i32 %or2, -1
1491 %and = and i32 %not2, %b
1492 %or3 = or i32 %and, %not1
1496 define i32 @or_and_not_not_commute4(i32 %a, i32 %b, i32 %c) {
1497 ; CHECK-LABEL: @or_and_not_not_commute4(
1498 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
1499 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1500 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1501 ; CHECK-NEXT: ret i32 [[OR3]]
1503 %or1 = or i32 %a, %b
1504 %not1 = xor i32 %or1, -1
1505 %or2 = or i32 %a, %c
1506 %not2 = xor i32 %or2, -1
1507 %and = and i32 %not2, %b
1508 %or3 = or i32 %and, %not1
1512 define i32 @or_and_not_not_commute5(i32 %a, i32 %b, i32 %c) {
1513 ; CHECK-LABEL: @or_and_not_not_commute5(
1514 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
1515 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1516 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1517 ; CHECK-NEXT: ret i32 [[OR3]]
1519 %or1 = or i32 %b, %a
1520 %not1 = xor i32 %or1, -1
1521 %or2 = or i32 %a, %c
1522 %not2 = xor i32 %or2, -1
1523 %and = and i32 %not2, %b
1524 %or3 = or i32 %not1, %and
1528 define i32 @or_and_not_not_commute6(i32 %a, i32 %b0, i32 %c) {
1529 ; CHECK-LABEL: @or_and_not_not_commute6(
1530 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1531 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C:%.*]]
1532 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1533 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1534 ; CHECK-NEXT: ret i32 [[OR3]]
1536 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1537 %or1 = or i32 %b, %a
1538 %not1 = xor i32 %or1, -1
1539 %or2 = or i32 %c, %a
1540 %not2 = xor i32 %or2, -1
1541 %and = and i32 %b, %not2
1542 %or3 = or i32 %and, %not1
1546 define i32 @or_and_not_not_commute7(i32 %a, i32 %b, i32 %c) {
1547 ; CHECK-LABEL: @or_and_not_not_commute7(
1548 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
1549 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1550 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1551 ; CHECK-NEXT: ret i32 [[OR3]]
1553 %or1 = or i32 %a, %b
1554 %not1 = xor i32 %or1, -1
1555 %or2 = or i32 %c, %a
1556 %not2 = xor i32 %or2, -1
1557 %and = and i32 %not2, %b
1558 %or3 = or i32 %and, %not1
1562 define i32 @or_and_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1563 ; CHECK-LABEL: @or_and_not_not_extra_not_use1(
1564 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
1565 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1566 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C:%.*]]
1567 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1568 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NOT2]], [[B]]
1569 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1570 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
1571 ; CHECK-NEXT: ret i32 [[OR3]]
1573 %or1 = or i32 %b, %a
1574 %not1 = xor i32 %or1, -1
1575 %or2 = or i32 %a, %c
1576 %not2 = xor i32 %or2, -1
1577 %and = and i32 %not2, %b
1578 %or3 = or i32 %and, %not1
1579 call void @use(i32 %not1)
1583 define i32 @or_and_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1584 ; CHECK-LABEL: @or_and_not_not_extra_not_use2(
1585 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A:%.*]], [[C:%.*]]
1586 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1587 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B:%.*]]
1588 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1589 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1590 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
1591 ; CHECK-NEXT: ret i32 [[OR3]]
1593 %or1 = or i32 %b, %a
1594 %not1 = xor i32 %or1, -1
1595 %or2 = or i32 %a, %c
1596 %not2 = xor i32 %or2, -1
1597 %and = and i32 %not2, %b
1598 %or3 = or i32 %and, %not1
1599 call void @use(i32 %not2)
1603 define i32 @or_and_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {
1604 ; CHECK-LABEL: @or_and_not_not_extra_and_use(
1605 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A:%.*]], [[C:%.*]]
1606 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1607 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NOT2]], [[B:%.*]]
1608 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]
1609 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1610 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1611 ; CHECK-NEXT: call void @use(i32 [[AND]])
1612 ; CHECK-NEXT: ret i32 [[OR3]]
1614 %or1 = or i32 %b, %a
1615 %not1 = xor i32 %or1, -1
1616 %or2 = or i32 %a, %c
1617 %not2 = xor i32 %or2, -1
1618 %and = and i32 %not2, %b
1619 %or3 = or i32 %and, %not1
1620 call void @use(i32 %and)
1624 define i32 @or_and_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1625 ; CHECK-LABEL: @or_and_not_not_extra_or_use1(
1626 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
1627 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1628 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C:%.*]]
1629 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1630 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NOT2]], [[B]]
1631 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1632 ; CHECK-NEXT: call void @use(i32 [[OR1]])
1633 ; CHECK-NEXT: ret i32 [[OR3]]
1635 %or1 = or i32 %b, %a
1636 %not1 = xor i32 %or1, -1
1637 %or2 = or i32 %a, %c
1638 %not2 = xor i32 %or2, -1
1639 %and = and i32 %not2, %b
1640 %or3 = or i32 %and, %not1
1641 call void @use(i32 %or1)
1645 define i32 @or_and_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1646 ; CHECK-LABEL: @or_and_not_not_extra_or_use2(
1647 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A:%.*]], [[C:%.*]]
1648 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B:%.*]]
1649 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
1650 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
1651 ; CHECK-NEXT: call void @use(i32 [[OR2]])
1652 ; CHECK-NEXT: ret i32 [[OR3]]
1654 %or1 = or i32 %b, %a
1655 %not1 = xor i32 %or1, -1
1656 %or2 = or i32 %a, %c
1657 %not2 = xor i32 %or2, -1
1658 %and = and i32 %not2, %b
1659 %or3 = or i32 %and, %not1
1660 call void @use(i32 %or2)
1664 ; Check the use limit. It can be adjusted in the future in terms of
1665 ; LHS and RHS uses distribution to be more flexible.
1666 define i32 @or_and_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {
1667 ; CHECK-LABEL: @or_and_not_not_2_extra_uses(
1668 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
1669 ; CHECK-NEXT: call void @use(i32 [[OR1]])
1670 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1671 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C:%.*]]
1672 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1673 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NOT2]], [[B]]
1674 ; CHECK-NEXT: call void @use(i32 [[AND]])
1675 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1676 ; CHECK-NEXT: ret i32 [[OR3]]
1678 %or1 = or i32 %b, %a
1679 call void @use(i32 %or1)
1680 %not1 = xor i32 %or1, -1
1681 %or2 = or i32 %a, %c
1682 %not2 = xor i32 %or2, -1
1683 %and = and i32 %not2, %b
1684 call void @use(i32 %and)
1685 %or3 = or i32 %not1, %and
1689 define i32 @or_and_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {
1690 ; CHECK-LABEL: @or_and_not_not_wrong_a(
1691 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[D:%.*]]
1692 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1693 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A:%.*]], [[C:%.*]]
1694 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1695 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NOT2]], [[B]]
1696 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1697 ; CHECK-NEXT: ret i32 [[OR3]]
1699 %or1 = or i32 %b, %d
1700 %not1 = xor i32 %or1, -1
1701 %or2 = or i32 %a, %c
1702 %not2 = xor i32 %or2, -1
1703 %and = and i32 %not2, %b
1704 %or3 = or i32 %and, %not1
1708 define i32 @or_and_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
1709 ; CHECK-LABEL: @or_and_not_not_wrong_b(
1710 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[D:%.*]], [[A:%.*]]
1711 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
1712 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C:%.*]]
1713 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
1714 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[NOT2]], [[B:%.*]]
1715 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]
1716 ; CHECK-NEXT: ret i32 [[OR3]]
1718 %or1 = or i32 %d, %a
1719 %not1 = xor i32 %or1, -1
1720 %or2 = or i32 %a, %c
1721 %not2 = xor i32 %or2, -1
1722 %and = and i32 %not2, %b
1723 %or3 = or i32 %and, %not1
1727 ; (b | ~(a & c)) & ~(a & b) --> ~((b | c) & a)
1729 define i32 @and_or_not_not(i32 %a, i32 %b, i32 %c) {
1730 ; CHECK-LABEL: @and_or_not_not(
1731 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
1732 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1733 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1734 ; CHECK-NEXT: ret i32 [[AND3]]
1736 %and1 = and i32 %b, %a
1737 %not1 = xor i32 %and1, -1
1738 %and2 = and i32 %a, %c
1739 %not2 = xor i32 %and2, -1
1740 %or = or i32 %not2, %b
1741 %and3 = and i32 %or, %not1
1745 define i32 @and_or_not_not_commute1(i32 %a, i32 %b0, i32 %c) {
1746 ; CHECK-LABEL: @and_or_not_not_commute1(
1747 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1748 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C:%.*]]
1749 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1750 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1751 ; CHECK-NEXT: ret i32 [[AND3]]
1753 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1754 %and1 = and i32 %b, %a
1755 %not1 = xor i32 %and1, -1
1756 %and2 = and i32 %a, %c
1757 %not2 = xor i32 %and2, -1
1758 %or = or i32 %b, %not2
1759 %and3 = and i32 %or, %not1
1763 define i32 @and_or_not_not_commute2(i32 %a, i32 %b, i32 %c) {
1764 ; CHECK-LABEL: @and_or_not_not_commute2(
1765 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
1766 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1767 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1768 ; CHECK-NEXT: ret i32 [[AND3]]
1770 %and1 = and i32 %b, %a
1771 %not1 = xor i32 %and1, -1
1772 %and2 = and i32 %a, %c
1773 %not2 = xor i32 %and2, -1
1774 %or = or i32 %not2, %b
1775 %and3 = and i32 %or, %not1
1779 define i32 @and_or_not_not_commute3(i32 %a, i32 %b, i32 %c) {
1780 ; CHECK-LABEL: @and_or_not_not_commute3(
1781 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
1782 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1783 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1784 ; CHECK-NEXT: ret i32 [[AND3]]
1786 %and1 = and i32 %b, %a
1787 %not1 = xor i32 %and1, -1
1788 %and2 = and i32 %c, %a
1789 %not2 = xor i32 %and2, -1
1790 %or = or i32 %not2, %b
1791 %and3 = and i32 %or, %not1
1795 define i32 @and_or_not_not_commute4(i32 %a, i32 %b, i32 %c) {
1796 ; CHECK-LABEL: @and_or_not_not_commute4(
1797 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
1798 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1799 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1800 ; CHECK-NEXT: ret i32 [[AND3]]
1802 %and1 = and i32 %a, %b
1803 %not1 = xor i32 %and1, -1
1804 %and2 = and i32 %a, %c
1805 %not2 = xor i32 %and2, -1
1806 %or = or i32 %not2, %b
1807 %and3 = and i32 %or, %not1
1811 define i32 @and_or_not_not_commute5(i32 %a, i32 %b, i32 %c) {
1812 ; CHECK-LABEL: @and_or_not_not_commute5(
1813 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
1814 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1815 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1816 ; CHECK-NEXT: ret i32 [[AND3]]
1818 %and1 = and i32 %b, %a
1819 %not1 = xor i32 %and1, -1
1820 %and2 = and i32 %a, %c
1821 %not2 = xor i32 %and2, -1
1822 %or = or i32 %not2, %b
1823 %and3 = and i32 %not1, %or
1827 define i32 @and_or_not_not_commute6(i32 %a, i32 %b0, i32 %c) {
1828 ; CHECK-LABEL: @and_or_not_not_commute6(
1829 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
1830 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C:%.*]]
1831 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1832 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1833 ; CHECK-NEXT: ret i32 [[AND3]]
1835 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
1836 %and1 = and i32 %b, %a
1837 %not1 = xor i32 %and1, -1
1838 %and2 = and i32 %c, %a
1839 %not2 = xor i32 %and2, -1
1840 %or = or i32 %b, %not2
1841 %and3 = and i32 %or, %not1
1845 define i32 @and_or_not_not_commute7(i32 %a, i32 %b, i32 %c) {
1846 ; CHECK-LABEL: @and_or_not_not_commute7(
1847 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
1848 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A:%.*]]
1849 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1850 ; CHECK-NEXT: ret i32 [[AND3]]
1852 %and1 = and i32 %a, %b
1853 %not1 = xor i32 %and1, -1
1854 %and2 = and i32 %c, %a
1855 %not2 = xor i32 %and2, -1
1856 %or = or i32 %not2, %b
1857 %and3 = and i32 %or, %not1
1861 define i32 @and_or_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {
1862 ; CHECK-LABEL: @and_or_not_not_extra_not_use1(
1863 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
1864 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
1865 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C:%.*]]
1866 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1867 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOT2]], [[B]]
1868 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
1869 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
1870 ; CHECK-NEXT: ret i32 [[AND3]]
1872 %and1 = and i32 %b, %a
1873 %not1 = xor i32 %and1, -1
1874 %and2 = and i32 %a, %c
1875 %not2 = xor i32 %and2, -1
1876 %or = or i32 %not2, %b
1877 %and3 = and i32 %or, %not1
1878 call void @use(i32 %not1)
1882 define i32 @and_or_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {
1883 ; CHECK-LABEL: @and_or_not_not_extra_not_use2(
1884 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A:%.*]], [[C:%.*]]
1885 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1886 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B:%.*]]
1887 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1888 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1889 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
1890 ; CHECK-NEXT: ret i32 [[AND3]]
1892 %and1 = and i32 %b, %a
1893 %not1 = xor i32 %and1, -1
1894 %and2 = and i32 %a, %c
1895 %not2 = xor i32 %and2, -1
1896 %or = or i32 %not2, %b
1897 %and3 = and i32 %or, %not1
1898 call void @use(i32 %not2)
1902 define i32 @and_or_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {
1903 ; CHECK-LABEL: @and_or_not_not_extra_and_use(
1904 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A:%.*]], [[C:%.*]]
1905 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1906 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOT2]], [[B:%.*]]
1907 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]
1908 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1909 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1910 ; CHECK-NEXT: call void @use(i32 [[OR]])
1911 ; CHECK-NEXT: ret i32 [[AND3]]
1913 %and1 = and i32 %b, %a
1914 %not1 = xor i32 %and1, -1
1915 %and2 = and i32 %a, %c
1916 %not2 = xor i32 %and2, -1
1917 %or = or i32 %not2, %b
1918 %and3 = and i32 %or, %not1
1919 call void @use(i32 %or)
1923 define i32 @and_or_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {
1924 ; CHECK-LABEL: @and_or_not_not_extra_or_use1(
1925 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
1926 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C:%.*]]
1927 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1928 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOT2]], [[B]]
1929 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
1930 ; CHECK-NEXT: call void @use(i32 [[AND1]])
1931 ; CHECK-NEXT: ret i32 [[AND3]]
1933 %and1 = and i32 %b, %a
1934 %not1 = xor i32 %and1, -1
1935 %and2 = and i32 %a, %c
1936 %not2 = xor i32 %and2, -1
1937 %or = or i32 %not2, %b
1938 %and3 = and i32 %or, %not1
1939 call void @use(i32 %and1)
1943 define i32 @and_or_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {
1944 ; CHECK-LABEL: @and_or_not_not_extra_or_use2(
1945 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A:%.*]], [[C:%.*]]
1946 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B:%.*]]
1947 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]
1948 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -1
1949 ; CHECK-NEXT: call void @use(i32 [[AND2]])
1950 ; CHECK-NEXT: ret i32 [[AND3]]
1952 %and1 = and i32 %b, %a
1953 %not1 = xor i32 %and1, -1
1954 %and2 = and i32 %a, %c
1955 %not2 = xor i32 %and2, -1
1956 %or = or i32 %not2, %b
1957 %and3 = and i32 %or, %not1
1958 call void @use(i32 %and2)
1962 define i32 @and_or_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {
1963 ; CHECK-LABEL: @and_or_not_not_2_extra_uses(
1964 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
1965 ; CHECK-NEXT: call void @use(i32 [[AND1]])
1966 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C:%.*]]
1967 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1968 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOT2]], [[B]]
1969 ; CHECK-NEXT: call void @use(i32 [[OR]])
1970 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
1971 ; CHECK-NEXT: ret i32 [[AND3]]
1973 %and1 = and i32 %b, %a
1974 call void @use(i32 %and1)
1975 %not1 = xor i32 %and1, -1
1976 %and2 = and i32 %a, %c
1977 %not2 = xor i32 %and2, -1
1978 %or = or i32 %not2, %b
1979 call void @use(i32 %or)
1980 %and3 = and i32 %not1, %or
1984 define i32 @and_or_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {
1985 ; CHECK-LABEL: @and_or_not_not_wrong_a(
1986 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[D:%.*]]
1987 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A:%.*]], [[C:%.*]]
1988 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
1989 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOT2]], [[B]]
1990 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]
1991 ; CHECK-NEXT: ret i32 [[AND3]]
1993 %and1 = and i32 %b, %d
1994 %not1 = xor i32 %and1, -1
1995 %and2 = and i32 %a, %c
1996 %not2 = xor i32 %and2, -1
1997 %or = or i32 %not2, %b
1998 %and3 = and i32 %or, %not1
2002 define i32 @and_or_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {
2003 ; CHECK-LABEL: @and_or_not_not_wrong_b(
2004 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[D:%.*]], [[A:%.*]]
2005 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2006 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C:%.*]]
2007 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
2008 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOT2]], [[B:%.*]]
2009 ; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR]], [[NOT1]]
2010 ; CHECK-NEXT: ret i32 [[AND3]]
2012 %and1 = and i32 %d, %a
2013 %not1 = xor i32 %and1, -1
2014 %and2 = and i32 %a, %c
2015 %not2 = xor i32 %and2, -1
2016 %or = or i32 %not2, %b
2017 %and3 = and i32 %or, %not1
2021 ; (a & ~(b | c)) | ~(a | (b ^ c)) --> (~a & b & c) | ~(b | c)
2023 define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) {
2024 ; CHECK-LABEL: @and_not_or_or_not_or_xor(
2025 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2026 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2027 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2028 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2029 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2030 ; CHECK-NEXT: ret i32 [[OR3]]
2032 %or1 = or i32 %b, %c
2033 %not1 = xor i32 %or1, -1
2034 %and1 = and i32 %not1, %a
2035 %xor1 = xor i32 %b, %c
2036 %or2 = or i32 %xor1, %a
2037 %not2 = xor i32 %or2, -1
2038 %or3 = or i32 %and1, %not2
2042 define i32 @and_not_or_or_not_or_xor_commute1(i32 %a, i32 %b, i32 %c) {
2043 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute1(
2044 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C:%.*]], [[B:%.*]]
2045 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2046 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2047 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2048 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2049 ; CHECK-NEXT: ret i32 [[OR3]]
2051 %or1 = or i32 %c, %b
2052 %not1 = xor i32 %or1, -1
2053 %and1 = and i32 %not1, %a
2054 %xor1 = xor i32 %b, %c
2055 %or2 = or i32 %xor1, %a
2056 %not2 = xor i32 %or2, -1
2057 %or3 = or i32 %and1, %not2
2061 define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) {
2062 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute2(
2063 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
2064 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2065 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2066 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2067 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2068 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2069 ; CHECK-NEXT: ret i32 [[OR3]]
2071 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2072 %or1 = or i32 %b, %c
2073 %not1 = xor i32 %or1, -1
2074 %and1 = and i32 %a, %not1
2075 %xor1 = xor i32 %b, %c
2076 %or2 = or i32 %xor1, %a
2077 %not2 = xor i32 %or2, -1
2078 %or3 = or i32 %and1, %not2
2082 define i32 @and_not_or_or_not_or_xor_commute3(i32 %a, i32 %b, i32 %c) {
2083 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute3(
2084 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2085 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[C]], [[B]]
2086 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2087 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2088 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2089 ; CHECK-NEXT: ret i32 [[OR3]]
2091 %or1 = or i32 %b, %c
2092 %not1 = xor i32 %or1, -1
2093 %and1 = and i32 %not1, %a
2094 %xor1 = xor i32 %c, %b
2095 %or2 = or i32 %xor1, %a
2096 %not2 = xor i32 %or2, -1
2097 %or3 = or i32 %and1, %not2
2101 define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) {
2102 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute4(
2103 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
2104 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2105 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2106 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[XOR1]]
2107 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2108 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2109 ; CHECK-NEXT: ret i32 [[OR3]]
2111 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2112 %or1 = or i32 %b, %c
2113 %not1 = xor i32 %or1, -1
2114 %and1 = and i32 %a, %not1
2115 %xor1 = xor i32 %b, %c
2116 %or2 = or i32 %a, %xor1
2117 %not2 = xor i32 %or2, -1
2118 %or3 = or i32 %and1, %not2
2122 define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) {
2123 ; CHECK-LABEL: @and_not_or_or_not_or_xor_commute5(
2124 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2125 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2126 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2127 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2128 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2129 ; CHECK-NEXT: ret i32 [[OR3]]
2131 %or1 = or i32 %b, %c
2132 %not1 = xor i32 %or1, -1
2133 %and1 = and i32 %not1, %a
2134 %xor1 = xor i32 %b, %c
2135 %or2 = or i32 %xor1, %a
2136 %not2 = xor i32 %or2, -1
2137 %or3 = or i32 %not2, %and1
2141 define i32 @and_not_or_or_not_or_xor_use1(i32 %a, i32 %b, i32 %c) {
2142 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use1(
2143 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2144 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2145 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2146 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2147 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2148 ; CHECK-NEXT: call void @use(i32 [[OR1]])
2149 ; CHECK-NEXT: ret i32 [[OR3]]
2151 %or1 = or i32 %b, %c
2152 %not1 = xor i32 %or1, -1
2153 %and1 = and i32 %not1, %a
2154 %xor1 = xor i32 %b, %c
2155 %or2 = or i32 %xor1, %a
2156 %not2 = xor i32 %or2, -1
2157 %or3 = or i32 %and1, %not2
2158 call void @use(i32 %or1)
2162 define i32 @and_not_or_or_not_or_xor_use2(i32 %a, i32 %b, i32 %c) {
2163 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use2(
2164 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2165 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
2166 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2167 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2168 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2169 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2170 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
2171 ; CHECK-NEXT: ret i32 [[OR3]]
2173 %or1 = or i32 %b, %c
2174 %not1 = xor i32 %or1, -1
2175 %and1 = and i32 %not1, %a
2176 %xor1 = xor i32 %b, %c
2177 %or2 = or i32 %xor1, %a
2178 %not2 = xor i32 %or2, -1
2179 %or3 = or i32 %and1, %not2
2180 call void @use(i32 %not1)
2184 define i32 @and_not_or_or_not_or_xor_use3(i32 %a, i32 %b, i32 %c) {
2185 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use3(
2186 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2187 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
2188 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
2189 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2190 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2191 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
2192 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
2193 ; CHECK-NEXT: call void @use(i32 [[AND1]])
2194 ; CHECK-NEXT: ret i32 [[OR3]]
2196 %or1 = or i32 %b, %c
2197 %not1 = xor i32 %or1, -1
2198 %and1 = and i32 %not1, %a
2199 %xor1 = xor i32 %b, %c
2200 %or2 = or i32 %xor1, %a
2201 %not2 = xor i32 %or2, -1
2202 %or3 = or i32 %and1, %not2
2203 call void @use(i32 %and1)
2207 define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) {
2208 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use4(
2209 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2210 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2211 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2212 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2213 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2214 ; CHECK-NEXT: call void @use(i32 [[XOR1]])
2215 ; CHECK-NEXT: ret i32 [[OR3]]
2217 %or1 = or i32 %b, %c
2218 %not1 = xor i32 %or1, -1
2219 %and1 = and i32 %not1, %a
2220 %xor1 = xor i32 %b, %c
2221 %or2 = or i32 %xor1, %a
2222 %not2 = xor i32 %or2, -1
2223 %or3 = or i32 %and1, %not2
2224 call void @use(i32 %xor1)
2228 define i32 @and_not_or_or_not_or_xor_use5(i32 %a, i32 %b, i32 %c) {
2229 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use5(
2230 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2231 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2232 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A:%.*]]
2233 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]
2234 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -1
2235 ; CHECK-NEXT: call void @use(i32 [[OR2]])
2236 ; CHECK-NEXT: ret i32 [[OR3]]
2238 %or1 = or i32 %b, %c
2239 %not1 = xor i32 %or1, -1
2240 %and1 = and i32 %not1, %a
2241 %xor1 = xor i32 %b, %c
2242 %or2 = or i32 %xor1, %a
2243 %not2 = xor i32 %or2, -1
2244 %or3 = or i32 %and1, %not2
2245 call void @use(i32 %or2)
2249 define i32 @and_not_or_or_not_or_xor_use6(i32 %a, i32 %b, i32 %c) {
2250 ; CHECK-LABEL: @and_not_or_or_not_or_xor_use6(
2251 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[C:%.*]]
2252 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
2253 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT1]], [[A:%.*]]
2254 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2255 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]
2256 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -1
2257 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]
2258 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
2259 ; CHECK-NEXT: ret i32 [[OR3]]
2261 %or1 = or i32 %b, %c
2262 %not1 = xor i32 %or1, -1
2263 %and1 = and i32 %not1, %a
2264 %xor1 = xor i32 %b, %c
2265 %or2 = or i32 %xor1, %a
2266 %not2 = xor i32 %or2, -1
2267 %or3 = or i32 %and1, %not2
2268 call void @use(i32 %not2)
2272 ; (a | ~(b & c)) & ~(a & (b ^ c)) --> ~(a | b) | (a ^ b ^ c)
2273 ; This pattern is not handled because the result is more undefined than a source.
2274 ; It is invalid as is, but feezing %a and %b will make it valid.
2276 define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) {
2277 ; CHECK-LABEL: @or_not_and_and_not_and_xor(
2278 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2279 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2280 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2281 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2282 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2283 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2284 ; CHECK-NEXT: ret i32 [[AND3]]
2286 %and1 = and i32 %b, %c
2287 %not1 = xor i32 %and1, -1
2288 %or1 = or i32 %not1, %a
2289 %xor1 = xor i32 %b, %c
2290 %and2 = and i32 %xor1, %a
2291 %not2 = xor i32 %and2, -1
2292 %and3 = and i32 %or1, %not2
2296 define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) {
2297 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute1(
2298 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C:%.*]], [[B:%.*]]
2299 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2300 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2301 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2302 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2303 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2304 ; CHECK-NEXT: ret i32 [[AND3]]
2306 %and1 = and i32 %c, %b
2307 %not1 = xor i32 %and1, -1
2308 %or1 = or i32 %not1, %a
2309 %xor1 = xor i32 %b, %c
2310 %and2 = and i32 %xor1, %a
2311 %not2 = xor i32 %and2, -1
2312 %and3 = and i32 %or1, %not2
2316 define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) {
2317 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute2(
2318 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
2319 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2320 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2321 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2322 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2323 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2324 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2325 ; CHECK-NEXT: ret i32 [[AND3]]
2327 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2328 %and1 = and i32 %b, %c
2329 %not1 = xor i32 %and1, -1
2330 %or1 = or i32 %a, %not1
2331 %xor1 = xor i32 %b, %c
2332 %and2 = and i32 %xor1, %a
2333 %not2 = xor i32 %and2, -1
2334 %and3 = and i32 %or1, %not2
2338 define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) {
2339 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute3(
2340 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2341 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2342 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2343 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[C]], [[B]]
2344 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2345 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2346 ; CHECK-NEXT: ret i32 [[AND3]]
2348 %and1 = and i32 %b, %c
2349 %not1 = xor i32 %and1, -1
2350 %or1 = or i32 %not1, %a
2351 %xor1 = xor i32 %c, %b
2352 %and2 = and i32 %xor1, %a
2353 %not2 = xor i32 %and2, -1
2354 %and3 = and i32 %or1, %not2
2358 define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) {
2359 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute4(
2360 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0:%.*]]
2361 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2362 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2363 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]
2364 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2365 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[XOR1]]
2366 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2367 ; CHECK-NEXT: ret i32 [[AND3]]
2369 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization
2370 %and1 = and i32 %b, %c
2371 %not1 = xor i32 %and1, -1
2372 %or1 = or i32 %a, %not1
2373 %xor1 = xor i32 %b, %c
2374 %and2 = and i32 %a, %xor1
2375 %not2 = xor i32 %and2, -1
2376 %and3 = and i32 %or1, %not2
2380 define i32 @or_not_and_and_not_and_xor_commute5(i32 %a, i32 %b, i32 %c) {
2381 ; CHECK-LABEL: @or_not_and_and_not_and_xor_commute5(
2382 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2383 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2384 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2385 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2386 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2387 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2388 ; CHECK-NEXT: ret i32 [[AND3]]
2390 %and1 = and i32 %b, %c
2391 %not1 = xor i32 %and1, -1
2392 %or1 = or i32 %not1, %a
2393 %xor1 = xor i32 %b, %c
2394 %and2 = and i32 %xor1, %a
2395 %not2 = xor i32 %and2, -1
2396 %and3 = and i32 %not2, %or1
2400 define i32 @or_not_and_and_not_and_xor_use1(i32 %a, i32 %b, i32 %c) {
2401 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use1(
2402 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2403 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2404 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2405 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2406 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2407 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2408 ; CHECK-NEXT: call void @use(i32 [[AND1]])
2409 ; CHECK-NEXT: ret i32 [[AND3]]
2411 %and1 = and i32 %b, %c
2412 %not1 = xor i32 %and1, -1
2413 %or1 = or i32 %not1, %a
2414 %xor1 = xor i32 %b, %c
2415 %and2 = and i32 %xor1, %a
2416 %not2 = xor i32 %and2, -1
2417 %and3 = and i32 %or1, %not2
2418 call void @use(i32 %and1)
2422 define i32 @or_not_and_and_not_and_xor_use2(i32 %a, i32 %b, i32 %c) {
2423 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use2(
2424 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2425 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2426 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2427 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2428 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2429 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2430 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
2431 ; CHECK-NEXT: ret i32 [[AND3]]
2433 %and1 = and i32 %b, %c
2434 %not1 = xor i32 %and1, -1
2435 %or1 = or i32 %not1, %a
2436 %xor1 = xor i32 %b, %c
2437 %and2 = and i32 %xor1, %a
2438 %not2 = xor i32 %and2, -1
2439 %and3 = and i32 %or1, %not2
2440 call void @use(i32 %not1)
2444 define i32 @or_not_and_and_not_and_xor_use3(i32 %a, i32 %b, i32 %c) {
2445 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use3(
2446 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2447 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2448 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2449 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2450 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2451 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2452 ; CHECK-NEXT: call void @use(i32 [[OR1]])
2453 ; CHECK-NEXT: ret i32 [[AND3]]
2455 %and1 = and i32 %b, %c
2456 %not1 = xor i32 %and1, -1
2457 %or1 = or i32 %not1, %a
2458 %xor1 = xor i32 %b, %c
2459 %and2 = and i32 %xor1, %a
2460 %not2 = xor i32 %and2, -1
2461 %and3 = and i32 %or1, %not2
2462 call void @use(i32 %or1)
2466 define i32 @or_not_and_and_not_and_xor_use4(i32 %a, i32 %b, i32 %c) {
2467 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use4(
2468 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2469 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2470 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2471 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2472 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2473 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2474 ; CHECK-NEXT: call void @use(i32 [[XOR1]])
2475 ; CHECK-NEXT: ret i32 [[AND3]]
2477 %and1 = and i32 %b, %c
2478 %not1 = xor i32 %and1, -1
2479 %or1 = or i32 %not1, %a
2480 %xor1 = xor i32 %b, %c
2481 %and2 = and i32 %xor1, %a
2482 %not2 = xor i32 %and2, -1
2483 %and3 = and i32 %or1, %not2
2484 call void @use(i32 %xor1)
2488 define i32 @or_not_and_and_not_and_xor_use5(i32 %a, i32 %b, i32 %c) {
2489 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use5(
2490 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2491 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2492 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2493 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2494 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2495 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2496 ; CHECK-NEXT: call void @use(i32 [[AND2]])
2497 ; CHECK-NEXT: ret i32 [[AND3]]
2499 %and1 = and i32 %b, %c
2500 %not1 = xor i32 %and1, -1
2501 %or1 = or i32 %not1, %a
2502 %xor1 = xor i32 %b, %c
2503 %and2 = and i32 %xor1, %a
2504 %not2 = xor i32 %and2, -1
2505 %and3 = and i32 %or1, %not2
2506 call void @use(i32 %and2)
2510 define i32 @or_not_and_and_not_and_xor_use6(i32 %a, i32 %b, i32 %c) {
2511 ; CHECK-LABEL: @or_not_and_and_not_and_xor_use6(
2512 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
2513 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
2514 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT1]], [[A:%.*]]
2515 ; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]
2516 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]
2517 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -1
2518 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]
2519 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
2520 ; CHECK-NEXT: ret i32 [[AND3]]
2522 %and1 = and i32 %b, %c
2523 %not1 = xor i32 %and1, -1
2524 %or1 = or i32 %not1, %a
2525 %xor1 = xor i32 %b, %c
2526 %and2 = and i32 %xor1, %a
2527 %not2 = xor i32 %and2, -1
2528 %and3 = and i32 %or1, %not2
2529 call void @use(i32 %not2)
2533 ; (~a & b & c) | ~(a | b | c) -> ~(a | (b ^ c))
2535 define i32 @not_and_and_or_not_or_or(i32 %a, i32 %b, i32 %c) {
2536 ; CHECK-LABEL: @not_and_and_or_not_or_or(
2537 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2538 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2539 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2540 ; CHECK-NEXT: ret i32 [[OR3]]
2542 %or1 = or i32 %b, %a
2543 %or2 = or i32 %or1, %c
2544 %not1 = xor i32 %or2, -1
2545 %not2 = xor i32 %a, -1
2546 %and1 = and i32 %not2, %b
2547 %and2 = and i32 %and1, %c
2548 %or3 = or i32 %and2, %not1
2552 define i32 @not_and_and_or_not_or_or_commute1_or(i32 %a, i32 %b, i32 %c) {
2553 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute1_or(
2554 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2555 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2556 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2557 ; CHECK-NEXT: ret i32 [[OR3]]
2559 %or1 = or i32 %c, %a
2560 %or2 = or i32 %or1, %b
2561 %not1 = xor i32 %or2, -1
2562 %not2 = xor i32 %a, -1
2563 %and1 = and i32 %not2, %b
2564 %and2 = and i32 %and1, %c
2565 %or3 = or i32 %and2, %not1
2569 define i32 @not_and_and_or_not_or_or_commute2_or(i32 %a, i32 %b, i32 %c) {
2570 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute2_or(
2571 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2572 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2573 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2574 ; CHECK-NEXT: ret i32 [[OR3]]
2576 %or1 = or i32 %b, %c
2577 %or2 = or i32 %or1, %a
2578 %not1 = xor i32 %or2, -1
2579 %not2 = xor i32 %a, -1
2580 %and1 = and i32 %not2, %b
2581 %and2 = and i32 %and1, %c
2582 %or3 = or i32 %and2, %not1
2586 define i32 @not_and_and_or_not_or_or_commute1_and(i32 %a, i32 %b, i32 %c) {
2587 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute1_and(
2588 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
2589 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2590 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2591 ; CHECK-NEXT: ret i32 [[OR3]]
2593 %or1 = or i32 %b, %a
2594 %or2 = or i32 %or1, %c
2595 %not1 = xor i32 %or2, -1
2596 %not2 = xor i32 %a, -1
2597 %and1 = and i32 %not2, %c
2598 %and2 = and i32 %and1, %b
2599 %or3 = or i32 %and2, %not1
2603 define i32 @not_and_and_or_not_or_or_commute2_and(i32 %a, i32 %b, i32 %c) {
2604 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute2_and(
2605 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
2606 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2607 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2608 ; CHECK-NEXT: ret i32 [[OR3]]
2610 %or1 = or i32 %b, %a
2611 %or2 = or i32 %or1, %c
2612 %not1 = xor i32 %or2, -1
2613 %not2 = xor i32 %a, -1
2614 %and1 = and i32 %b, %c
2615 %and2 = and i32 %and1, %not2
2616 %or3 = or i32 %and2, %not1
2620 define i32 @not_and_and_or_not_or_or_commute1(i32 %a, i32 %b, i32 %c) {
2621 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute1(
2622 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2623 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2624 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2625 ; CHECK-NEXT: ret i32 [[OR3]]
2627 %or1 = or i32 %a, %b
2628 %or2 = or i32 %or1, %c
2629 %not1 = xor i32 %or2, -1
2630 %not2 = xor i32 %a, -1
2631 %and1 = and i32 %not2, %b
2632 %and2 = and i32 %and1, %c
2633 %or3 = or i32 %and2, %not1
2637 define i32 @not_and_and_or_not_or_or_commute2(i32 %a, i32 %b, i32 %c0) {
2638 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute2(
2639 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
2640 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
2641 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2642 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2643 ; CHECK-NEXT: ret i32 [[OR3]]
2645 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2646 %or1 = or i32 %b, %a
2647 %or2 = or i32 %c, %or1
2648 %not1 = xor i32 %or2, -1
2649 %not2 = xor i32 %a, -1
2650 %and1 = and i32 %not2, %b
2651 %and2 = and i32 %and1, %c
2652 %or3 = or i32 %and2, %not1
2656 define i32 @not_and_and_or_not_or_or_commute3(i32 %a, i32 %b0, i32 %c) {
2657 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute3(
2658 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
2659 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
2660 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2661 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2662 ; CHECK-NEXT: ret i32 [[OR3]]
2664 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2665 %or1 = or i32 %b, %a
2666 %or2 = or i32 %or1, %c
2667 %not1 = xor i32 %or2, -1
2668 %not2 = xor i32 %a, -1
2669 %and1 = and i32 %b, %not2
2670 %and2 = and i32 %and1, %c
2671 %or3 = or i32 %and2, %not1
2675 define i32 @not_and_and_or_not_or_or_commute4(i32 %a, i32 %b, i32 %c0) {
2676 ; CHECK-LABEL: @not_and_and_or_not_or_or_commute4(
2677 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
2678 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
2679 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A:%.*]]
2680 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2681 ; CHECK-NEXT: ret i32 [[OR3]]
2683 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2684 %or1 = or i32 %b, %a
2685 %or2 = or i32 %or1, %c
2686 %not1 = xor i32 %or2, -1
2687 %not2 = xor i32 %a, -1
2688 %and1 = and i32 %not2, %b
2689 %and2 = and i32 %c, %and1
2690 %or3 = or i32 %and2, %not1
2694 define i32 @not_and_and_or_not_or_or_use1(i32 %a, i32 %b, i32 %c) {
2695 ; CHECK-LABEL: @not_and_and_or_not_or_or_use1(
2696 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
2697 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B]]
2698 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2699 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2700 ; CHECK-NEXT: call void @use(i32 [[OR1]])
2701 ; CHECK-NEXT: ret i32 [[OR3]]
2703 %or1 = or i32 %b, %a
2704 %or2 = or i32 %or1, %c
2705 %not1 = xor i32 %or2, -1
2706 %not2 = xor i32 %a, -1
2707 %and1 = and i32 %not2, %b
2708 %and2 = and i32 %and1, %c
2709 %or3 = or i32 %and2, %not1
2710 call void @use(i32 %or1)
2714 define i32 @not_and_and_or_not_or_or_use2(i32 %a, i32 %b, i32 %c) {
2715 ; CHECK-LABEL: @not_and_and_or_not_or_or_use2(
2716 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
2717 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
2718 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]
2719 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2720 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2721 ; CHECK-NEXT: call void @use(i32 [[OR2]])
2722 ; CHECK-NEXT: ret i32 [[OR3]]
2724 %or1 = or i32 %b, %a
2725 %or2 = or i32 %or1, %c
2726 %not1 = xor i32 %or2, -1
2727 %not2 = xor i32 %a, -1
2728 %and1 = and i32 %not2, %b
2729 %and2 = and i32 %and1, %c
2730 %or3 = or i32 %and2, %not1
2731 call void @use(i32 %or2)
2735 define i32 @not_and_and_or_not_or_or_use3(i32 %a, i32 %b, i32 %c) {
2736 ; CHECK-LABEL: @not_and_and_or_not_or_or_use3(
2737 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
2738 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
2739 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -1
2740 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
2741 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B]]
2742 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]
2743 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]
2744 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
2745 ; CHECK-NEXT: ret i32 [[OR3]]
2747 %or1 = or i32 %b, %a
2748 %or2 = or i32 %or1, %c
2749 %not1 = xor i32 %or2, -1
2750 %not2 = xor i32 %a, -1
2751 %and1 = and i32 %not2, %b
2752 %and2 = and i32 %and1, %c
2753 %or3 = or i32 %and2, %not1
2754 call void @use(i32 %not1)
2758 define i32 @not_and_and_or_not_or_or_use4(i32 %a, i32 %b, i32 %c) {
2759 ; CHECK-LABEL: @not_and_and_or_not_or_or_use4(
2760 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2761 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2762 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2763 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2764 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
2765 ; CHECK-NEXT: ret i32 [[OR3]]
2767 %or1 = or i32 %b, %a
2768 %or2 = or i32 %or1, %c
2769 %not1 = xor i32 %or2, -1
2770 %not2 = xor i32 %a, -1
2771 %and1 = and i32 %not2, %b
2772 %and2 = and i32 %and1, %c
2773 %or3 = or i32 %and2, %not1
2774 call void @use(i32 %not2)
2778 define i32 @not_and_and_or_not_or_or_use5(i32 %a, i32 %b, i32 %c) {
2779 ; CHECK-LABEL: @not_and_and_or_not_or_or_use5(
2780 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2781 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B:%.*]]
2782 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B]]
2783 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]
2784 ; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -1
2785 ; CHECK-NEXT: call void @use(i32 [[AND1]])
2786 ; CHECK-NEXT: ret i32 [[OR3]]
2788 %or1 = or i32 %b, %a
2789 %or2 = or i32 %or1, %c
2790 %not1 = xor i32 %or2, -1
2791 %not2 = xor i32 %a, -1
2792 %and1 = and i32 %not2, %b
2793 %and2 = and i32 %and1, %c
2794 %or3 = or i32 %and2, %not1
2795 call void @use(i32 %and1)
2799 define i32 @not_and_and_or_not_or_or_use6(i32 %a, i32 %b, i32 %c) {
2800 ; CHECK-LABEL: @not_and_and_or_not_or_or_use6(
2801 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
2802 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
2803 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -1
2804 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
2805 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B]]
2806 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]
2807 ; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]
2808 ; CHECK-NEXT: call void @use(i32 [[AND2]])
2809 ; CHECK-NEXT: ret i32 [[OR3]]
2811 %or1 = or i32 %b, %a
2812 %or2 = or i32 %or1, %c
2813 %not1 = xor i32 %or2, -1
2814 %not2 = xor i32 %a, -1
2815 %and1 = and i32 %not2, %b
2816 %and2 = and i32 %and1, %c
2817 %or3 = or i32 %and2, %not1
2818 call void @use(i32 %and2)
2822 ; (~a | b | c) & ~(a & b & c) -> ~a | (b ^ c)
2824 define i32 @not_or_or_and_not_and_and(i32 %a, i32 %b, i32 %c) {
2825 ; CHECK-LABEL: @not_or_or_and_not_and_and(
2826 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2827 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2828 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2829 ; CHECK-NEXT: ret i32 [[AND3]]
2831 %and1 = and i32 %b, %a
2832 %and2 = and i32 %and1, %c
2833 %not1 = xor i32 %and2, -1
2834 %not2 = xor i32 %a, -1
2835 %or1 = or i32 %not2, %b
2836 %or2 = or i32 %or1, %c
2837 %and3 = and i32 %or2, %not1
2841 define i32 @not_or_or_and_not_and_and_commute1_and(i32 %a, i32 %b, i32 %c) {
2842 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute1_and(
2843 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2844 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2845 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2846 ; CHECK-NEXT: ret i32 [[AND3]]
2848 %and1 = and i32 %c, %a
2849 %and2 = and i32 %and1, %b
2850 %not1 = xor i32 %and2, -1
2851 %not2 = xor i32 %a, -1
2852 %or1 = or i32 %not2, %b
2853 %or2 = or i32 %or1, %c
2854 %and3 = and i32 %or2, %not1
2858 define i32 @not_or_or_and_not_and_and_commute2_and(i32 %a, i32 %b, i32 %c) {
2859 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute2_and(
2860 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2861 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2862 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2863 ; CHECK-NEXT: ret i32 [[AND3]]
2865 %and1 = and i32 %b, %c
2866 %and2 = and i32 %and1, %a
2867 %not1 = xor i32 %and2, -1
2868 %not2 = xor i32 %a, -1
2869 %or1 = or i32 %not2, %b
2870 %or2 = or i32 %or1, %c
2871 %and3 = and i32 %or2, %not1
2875 define i32 @not_or_or_and_not_and_and_commute1_or(i32 %a, i32 %b, i32 %c) {
2876 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute1_or(
2877 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2878 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
2879 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2880 ; CHECK-NEXT: ret i32 [[AND3]]
2882 %and1 = and i32 %b, %a
2883 %and2 = and i32 %and1, %c
2884 %not1 = xor i32 %and2, -1
2885 %not2 = xor i32 %a, -1
2886 %or1 = or i32 %not2, %c
2887 %or2 = or i32 %or1, %b
2888 %and3 = and i32 %or2, %not1
2892 define i32 @not_or_or_and_not_and_and_commute2_or(i32 %a, i32 %b, i32 %c) {
2893 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute2_or(
2894 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2895 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[C:%.*]]
2896 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2897 ; CHECK-NEXT: ret i32 [[AND3]]
2899 %and1 = and i32 %b, %a
2900 %and2 = and i32 %and1, %c
2901 %not1 = xor i32 %and2, -1
2902 %not2 = xor i32 %a, -1
2903 %or1 = or i32 %b, %c
2904 %or2 = or i32 %or1, %not2
2905 %and3 = and i32 %or2, %not1
2909 define i32 @not_or_or_and_not_and_and_commute1(i32 %a, i32 %b, i32 %c) {
2910 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute1(
2911 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2912 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
2913 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2914 ; CHECK-NEXT: ret i32 [[AND3]]
2916 %and1 = and i32 %a, %b
2917 %and2 = and i32 %and1, %c
2918 %not1 = xor i32 %and2, -1
2919 %not2 = xor i32 %a, -1
2920 %or1 = or i32 %not2, %b
2921 %or2 = or i32 %or1, %c
2922 %and3 = and i32 %or2, %not1
2926 define i32 @not_or_or_and_not_and_and_commute2(i32 %a, i32 %b, i32 %c0) {
2927 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute2(
2928 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
2929 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2930 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
2931 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2932 ; CHECK-NEXT: ret i32 [[AND3]]
2934 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2935 %and1 = and i32 %b, %a
2936 %and2 = and i32 %c, %and1
2937 %not1 = xor i32 %and2, -1
2938 %not2 = xor i32 %a, -1
2939 %or1 = or i32 %not2, %b
2940 %or2 = or i32 %or1, %c
2941 %and3 = and i32 %or2, %not1
2945 define i32 @not_or_or_and_not_and_and_commute3(i32 %a, i32 %b0, i32 %c) {
2946 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute3(
2947 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
2948 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2949 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C:%.*]]
2950 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2951 ; CHECK-NEXT: ret i32 [[AND3]]
2953 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
2954 %and1 = and i32 %b, %a
2955 %and2 = and i32 %and1, %c
2956 %not1 = xor i32 %and2, -1
2957 %not2 = xor i32 %a, -1
2958 %or1 = or i32 %b, %not2
2959 %or2 = or i32 %or1, %c
2960 %and3 = and i32 %or2, %not1
2964 define i32 @not_or_or_and_not_and_and_commute4(i32 %a, i32 %b, i32 %c0) {
2965 ; CHECK-LABEL: @not_or_or_and_not_and_and_commute4(
2966 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
2967 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
2968 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B:%.*]]
2969 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2970 ; CHECK-NEXT: ret i32 [[AND3]]
2972 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
2973 %and1 = and i32 %b, %a
2974 %and2 = and i32 %and1, %c
2975 %not1 = xor i32 %and2, -1
2976 %not2 = xor i32 %a, -1
2977 %or1 = or i32 %not2, %b
2978 %or2 = or i32 %c, %or1
2979 %and3 = and i32 %or2, %not1
2983 define i32 @not_or_or_and_not_and_and_use1(i32 %a, i32 %b, i32 %c) {
2984 ; CHECK-LABEL: @not_or_or_and_not_and_and_use1(
2985 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
2986 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
2987 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B]]
2988 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
2989 ; CHECK-NEXT: call void @use(i32 [[AND1]])
2990 ; CHECK-NEXT: ret i32 [[AND3]]
2992 %and1 = and i32 %b, %a
2993 %and2 = and i32 %and1, %c
2994 %not1 = xor i32 %and2, -1
2995 %not2 = xor i32 %a, -1
2996 %or1 = or i32 %not2, %b
2997 %or2 = or i32 %or1, %c
2998 %and3 = and i32 %or2, %not1
2999 call void @use(i32 %and1)
3003 define i32 @not_or_or_and_not_and_and_use2(i32 %a, i32 %b, i32 %c) {
3004 ; CHECK-LABEL: @not_or_or_and_not_and_and_use2(
3005 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
3006 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
3007 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3008 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]
3009 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3010 ; CHECK-NEXT: call void @use(i32 [[AND2]])
3011 ; CHECK-NEXT: ret i32 [[AND3]]
3013 %and1 = and i32 %b, %a
3014 %and2 = and i32 %and1, %c
3015 %not1 = xor i32 %and2, -1
3016 %not2 = xor i32 %a, -1
3017 %or1 = or i32 %not2, %b
3018 %or2 = or i32 %or1, %c
3019 %and3 = and i32 %or2, %not1
3020 call void @use(i32 %and2)
3024 define i32 @not_or_or_and_not_and_and_use3(i32 %a, i32 %b, i32 %c) {
3025 ; CHECK-LABEL: @not_or_or_and_not_and_and_use3(
3026 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
3027 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
3028 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND2]], -1
3029 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3030 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B]]
3031 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3032 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]
3033 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
3034 ; CHECK-NEXT: ret i32 [[AND3]]
3036 %and1 = and i32 %b, %a
3037 %and2 = and i32 %and1, %c
3038 %not1 = xor i32 %and2, -1
3039 %not2 = xor i32 %a, -1
3040 %or1 = or i32 %not2, %b
3041 %or2 = or i32 %or1, %c
3042 %and3 = and i32 %or2, %not1
3043 call void @use(i32 %not1)
3047 define i32 @not_or_or_and_not_and_and_use4(i32 %a, i32 %b, i32 %c) {
3048 ; CHECK-LABEL: @not_or_or_and_not_and_and_use4(
3049 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3050 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B:%.*]]
3051 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3052 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3053 ; CHECK-NEXT: ret i32 [[AND3]]
3055 %and1 = and i32 %b, %a
3056 %and2 = and i32 %and1, %c
3057 %not1 = xor i32 %and2, -1
3058 %not2 = xor i32 %a, -1
3059 %or1 = or i32 %not2, %b
3060 %or2 = or i32 %or1, %c
3061 %and3 = and i32 %or2, %not1
3062 call void @use(i32 %not2)
3066 define i32 @not_or_or_and_not_and_and_use5(i32 %a, i32 %b, i32 %c) {
3067 ; CHECK-LABEL: @not_or_or_and_not_and_and_use5(
3068 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3069 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B:%.*]]
3070 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C:%.*]], [[B]]
3071 ; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]
3072 ; CHECK-NEXT: call void @use(i32 [[OR1]])
3073 ; CHECK-NEXT: ret i32 [[AND3]]
3075 %and1 = and i32 %b, %a
3076 %and2 = and i32 %and1, %c
3077 %not1 = xor i32 %and2, -1
3078 %not2 = xor i32 %a, -1
3079 %or1 = or i32 %not2, %b
3080 %or2 = or i32 %or1, %c
3081 %and3 = and i32 %or2, %not1
3082 call void @use(i32 %or1)
3086 define i32 @not_or_or_and_not_and_and_use6(i32 %a, i32 %b, i32 %c) {
3087 ; CHECK-LABEL: @not_or_or_and_not_and_and_use6(
3088 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
3089 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
3090 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3091 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B]]
3092 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]
3093 ; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]
3094 ; CHECK-NEXT: call void @use(i32 [[OR2]])
3095 ; CHECK-NEXT: ret i32 [[AND3]]
3097 %and1 = and i32 %b, %a
3098 %and2 = and i32 %and1, %c
3099 %not1 = xor i32 %and2, -1
3100 %not2 = xor i32 %a, -1
3101 %or1 = or i32 %not2, %b
3102 %or2 = or i32 %or1, %c
3103 %and3 = and i32 %or2, %not1
3104 call void @use(i32 %or2)
3108 ; (~a & b & c) | ~(a | b) -> (c | ~b) & ~a
3110 define i32 @not_and_and_or_no_or(i32 %a, i32 %b, i32 %c) {
3111 ; CHECK-LABEL: @not_and_and_or_no_or(
3112 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3113 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3114 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3115 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3116 ; CHECK-NEXT: ret i32 [[OR2]]
3118 %or1 = or i32 %b, %a
3119 %not1 = xor i32 %or1, -1
3120 %not2 = xor i32 %a, -1
3121 %and1 = and i32 %not2, %b
3122 %and2 = and i32 %and1, %c
3123 %or2 = or i32 %and2, %not1
3127 define i32 @not_and_and_or_no_or_commute1_and(i32 %a, i32 %b, i32 %c) {
3128 ; CHECK-LABEL: @not_and_and_or_no_or_commute1_and(
3129 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3130 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3131 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3132 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3133 ; CHECK-NEXT: ret i32 [[OR2]]
3135 %or1 = or i32 %b, %a
3136 %not1 = xor i32 %or1, -1
3137 %not2 = xor i32 %a, -1
3138 %and1 = and i32 %c, %b
3139 %and2 = and i32 %and1, %not2
3140 %or2 = or i32 %and2, %not1
3144 define i32 @not_and_and_or_no_or_commute2_and(i32 %a, i32 %b, i32 %c) {
3145 ; CHECK-LABEL: @not_and_and_or_no_or_commute2_and(
3146 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3147 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3148 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3149 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3150 ; CHECK-NEXT: ret i32 [[OR2]]
3152 %or1 = or i32 %b, %a
3153 %not1 = xor i32 %or1, -1
3154 %not2 = xor i32 %a, -1
3155 %and1 = and i32 %not2, %c
3156 %and2 = and i32 %and1, %b
3157 %or2 = or i32 %and2, %not1
3161 define i32 @not_and_and_or_no_or_commute1(i32 %a, i32 %b, i32 %c) {
3162 ; CHECK-LABEL: @not_and_and_or_no_or_commute1(
3163 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3164 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3165 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3166 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3167 ; CHECK-NEXT: ret i32 [[OR2]]
3169 %or1 = or i32 %a, %b
3170 %not1 = xor i32 %or1, -1
3171 %not2 = xor i32 %a, -1
3172 %and1 = and i32 %not2, %b
3173 %and2 = and i32 %and1, %c
3174 %or2 = or i32 %and2, %not1
3178 define i32 @not_and_and_or_no_or_commute2(i32 %a, i32 %b0, i32 %c) {
3179 ; CHECK-LABEL: @not_and_and_or_no_or_commute2(
3180 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
3181 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3182 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
3183 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3184 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3185 ; CHECK-NEXT: ret i32 [[OR2]]
3187 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3188 %or1 = or i32 %b, %a
3189 %not1 = xor i32 %or1, -1
3190 %not2 = xor i32 %a, -1
3191 %and1 = and i32 %b, %not2
3192 %and2 = and i32 %and1, %c
3193 %or2 = or i32 %and2, %not1
3197 define i32 @not_and_and_or_no_or_commute3(i32 %a, i32 %b, i32 %c0) {
3198 ; CHECK-LABEL: @not_and_and_or_no_or_commute3(
3199 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
3200 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3201 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3202 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]
3203 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3204 ; CHECK-NEXT: ret i32 [[OR2]]
3206 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3207 %or1 = or i32 %b, %a
3208 %not1 = xor i32 %or1, -1
3209 %not2 = xor i32 %a, -1
3210 %and1 = and i32 %not2, %b
3211 %and2 = and i32 %c, %and1
3212 %or2 = or i32 %and2, %not1
3216 define i32 @not_and_and_or_no_or_use1(i32 %a, i32 %b, i32 %c) {
3217 ; CHECK-LABEL: @not_and_and_or_no_or_use1(
3218 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3219 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3220 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3221 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3222 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3223 ; CHECK-NEXT: ret i32 [[OR2]]
3225 %or1 = or i32 %b, %a
3226 %not1 = xor i32 %or1, -1
3227 %not2 = xor i32 %a, -1
3228 %and1 = and i32 %not2, %b
3229 %and2 = and i32 %and1, %c
3230 %or2 = or i32 %and2, %not1
3231 call void @use(i32 %not2)
3235 define i32 @not_and_and_or_no_or_use2(i32 %a, i32 %b, i32 %c) {
3236 ; CHECK-LABEL: @not_and_and_or_no_or_use2(
3237 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3238 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3239 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3240 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3241 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3242 ; CHECK-NEXT: ret i32 [[OR2]]
3244 %or1 = or i32 %b, %a
3245 %not1 = xor i32 %or1, -1
3246 %not2 = xor i32 %a, -1
3247 %and1 = and i32 %b, %c
3248 %and2 = and i32 %and1, %not2
3249 %or2 = or i32 %and2, %not1
3250 call void @use(i32 %not2)
3254 define i32 @not_and_and_or_no_or_use3(i32 %a, i32 %b, i32 %c) {
3255 ; CHECK-LABEL: @not_and_and_or_no_or_use3(
3256 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3257 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3258 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3259 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3260 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3261 ; CHECK-NEXT: ret i32 [[OR2]]
3263 %or1 = or i32 %b, %a
3264 %not1 = xor i32 %or1, -1
3265 %not2 = xor i32 %a, -1
3266 %and1 = and i32 %not2, %c
3267 %and2 = and i32 %and1, %b
3268 %or2 = or i32 %and2, %not1
3269 call void @use(i32 %not2)
3273 define i32 @not_and_and_or_no_or_use4(i32 %a, i32 %b, i32 %c) {
3274 ; CHECK-LABEL: @not_and_and_or_no_or_use4(
3275 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3276 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3277 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3278 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3279 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3280 ; CHECK-NEXT: ret i32 [[OR2]]
3282 %or1 = or i32 %b, %a
3283 %not1 = xor i32 %or1, -1
3284 %not2 = xor i32 %a, -1
3285 %and1 = and i32 %not2, %c
3286 %and2 = and i32 %and1, %b
3287 %or2 = or i32 %and2, %not1
3288 call void @use(i32 %not2)
3292 define i32 @not_and_and_or_no_or_use5(i32 %a, i32 %b, i32 %c) {
3293 ; CHECK-LABEL: @not_and_and_or_no_or_use5(
3294 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
3295 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
3296 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3297 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B]]
3298 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
3299 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3300 ; CHECK-NEXT: call void @use(i32 [[OR1]])
3301 ; CHECK-NEXT: ret i32 [[OR2]]
3303 %or1 = or i32 %b, %a
3304 %not1 = xor i32 %or1, -1
3305 %not2 = xor i32 %a, -1
3306 %and1 = and i32 %not2, %b
3307 %and2 = and i32 %and1, %c
3308 %or2 = or i32 %and2, %not1
3309 call void @use(i32 %or1)
3313 define i32 @not_and_and_or_no_or_use6(i32 %a, i32 %b, i32 %c) {
3314 ; CHECK-LABEL: @not_and_and_or_no_or_use6(
3315 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
3316 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
3317 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3318 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B]]
3319 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
3320 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3321 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
3322 ; CHECK-NEXT: ret i32 [[OR2]]
3324 %or1 = or i32 %b, %a
3325 %not1 = xor i32 %or1, -1
3326 %not2 = xor i32 %a, -1
3327 %and1 = and i32 %not2, %b
3328 %and2 = and i32 %and1, %c
3329 %or2 = or i32 %and2, %not1
3330 call void @use(i32 %not1)
3334 define i32 @not_and_and_or_no_or_use7(i32 %a, i32 %b, i32 %c) {
3335 ; CHECK-LABEL: @not_and_and_or_no_or_use7(
3336 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3337 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B:%.*]]
3338 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
3339 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[C:%.*]]
3340 ; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]
3341 ; CHECK-NEXT: call void @use(i32 [[AND1]])
3342 ; CHECK-NEXT: ret i32 [[OR2]]
3344 %or1 = or i32 %b, %a
3345 %not1 = xor i32 %or1, -1
3346 %not2 = xor i32 %a, -1
3347 %and1 = and i32 %not2, %b
3348 %and2 = and i32 %and1, %c
3349 %or2 = or i32 %and2, %not1
3350 call void @use(i32 %and1)
3354 define i32 @not_and_and_or_no_or_use8(i32 %a, i32 %b, i32 %c) {
3355 ; CHECK-LABEL: @not_and_and_or_no_or_use8(
3356 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
3357 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -1
3358 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3359 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOT2]], [[B]]
3360 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
3361 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]
3362 ; CHECK-NEXT: call void @use(i32 [[AND2]])
3363 ; CHECK-NEXT: ret i32 [[OR2]]
3365 %or1 = or i32 %b, %a
3366 %not1 = xor i32 %or1, -1
3367 %not2 = xor i32 %a, -1
3368 %and1 = and i32 %not2, %b
3369 %and2 = and i32 %and1, %c
3370 %or2 = or i32 %and2, %not1
3371 call void @use(i32 %and2)
3375 ; (~a | b | c) & ~(a & b) -> (c & ~b) | ~a
3377 define i32 @not_or_or_and_no_and(i32 %a, i32 %b, i32 %c) {
3378 ; CHECK-LABEL: @not_or_or_and_no_and(
3379 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3380 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3381 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3382 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3383 ; CHECK-NEXT: ret i32 [[AND2]]
3385 %and1 = and i32 %b, %a
3386 %not1 = xor i32 %and1, -1
3387 %not2 = xor i32 %a, -1
3388 %or1 = or i32 %not2, %b
3389 %or2 = or i32 %or1, %c
3390 %and2 = and i32 %or2, %not1
3394 define i32 @not_or_or_and_no_and_commute1_or(i32 %a, i32 %b, i32 %c) {
3395 ; CHECK-LABEL: @not_or_or_and_no_and_commute1_or(
3396 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3397 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3398 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3399 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3400 ; CHECK-NEXT: ret i32 [[AND2]]
3402 %and1 = and i32 %b, %a
3403 %not1 = xor i32 %and1, -1
3404 %not2 = xor i32 %a, -1
3405 %or1 = or i32 %c, %b
3406 %or2 = or i32 %or1, %not2
3407 %and2 = and i32 %or2, %not1
3411 define i32 @not_or_or_and_no_and_commute2_or(i32 %a, i32 %b, i32 %c) {
3412 ; CHECK-LABEL: @not_or_or_and_no_and_commute2_or(
3413 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3414 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3415 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3416 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3417 ; CHECK-NEXT: ret i32 [[AND2]]
3419 %and1 = and i32 %b, %a
3420 %not1 = xor i32 %and1, -1
3421 %not2 = xor i32 %a, -1
3422 %or1 = or i32 %not2, %c
3423 %or2 = or i32 %or1, %b
3424 %and2 = and i32 %or2, %not1
3428 define i32 @not_or_or_and_no_and_commute1(i32 %a, i32 %b, i32 %c) {
3429 ; CHECK-LABEL: @not_or_or_and_no_and_commute1(
3430 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3431 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3432 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3433 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3434 ; CHECK-NEXT: ret i32 [[AND2]]
3436 %and1 = and i32 %a, %b
3437 %not1 = xor i32 %and1, -1
3438 %not2 = xor i32 %a, -1
3439 %or1 = or i32 %not2, %b
3440 %or2 = or i32 %or1, %c
3441 %and2 = and i32 %or2, %not1
3445 define i32 @not_or_or_and_no_and_commute2(i32 %a, i32 %b0, i32 %c) {
3446 ; CHECK-LABEL: @not_or_or_and_no_and_commute2(
3447 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0:%.*]]
3448 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3449 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
3450 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3451 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3452 ; CHECK-NEXT: ret i32 [[AND2]]
3454 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization
3455 %and1 = and i32 %b, %a
3456 %not1 = xor i32 %and1, -1
3457 %not2 = xor i32 %a, -1
3458 %or1 = or i32 %b, %not2
3459 %or2 = or i32 %or1, %c
3460 %and2 = and i32 %or2, %not1
3464 define i32 @not_or_or_and_no_and_commute3(i32 %a, i32 %b, i32 %c0) {
3465 ; CHECK-LABEL: @not_or_or_and_no_and_commute3(
3466 ; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0:%.*]]
3467 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3468 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3469 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]
3470 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3471 ; CHECK-NEXT: ret i32 [[AND2]]
3473 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization
3474 %and1 = and i32 %b, %a
3475 %not1 = xor i32 %and1, -1
3476 %not2 = xor i32 %a, -1
3477 %or1 = or i32 %not2, %b
3478 %or2 = or i32 %c, %or1
3479 %and2 = and i32 %or2, %not1
3483 define i32 @not_or_or_and_no_and_use1(i32 %a, i32 %b, i32 %c) {
3484 ; CHECK-LABEL: @not_or_or_and_no_and_use1(
3485 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3486 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3487 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3488 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3489 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3490 ; CHECK-NEXT: ret i32 [[AND2]]
3492 %and1 = and i32 %b, %a
3493 %not1 = xor i32 %and1, -1
3494 %not2 = xor i32 %a, -1
3495 %or1 = or i32 %not2, %b
3496 %or2 = or i32 %or1, %c
3497 %and2 = and i32 %or2, %not1
3498 call void @use(i32 %not2)
3502 define i32 @not_or_or_and_no_and_use2(i32 %a, i32 %b, i32 %c) {
3503 ; CHECK-LABEL: @not_or_or_and_no_and_use2(
3504 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3505 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3506 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3507 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3508 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3509 ; CHECK-NEXT: ret i32 [[AND2]]
3511 %and1 = and i32 %b, %a
3512 %not1 = xor i32 %and1, -1
3513 %not2 = xor i32 %a, -1
3514 %or1 = or i32 %b, %c
3515 %or2 = or i32 %or1, %not2
3516 %and2 = and i32 %or2, %not1
3517 call void @use(i32 %not2)
3521 define i32 @not_or_or_and_no_and_use3(i32 %a, i32 %b, i32 %c) {
3522 ; CHECK-LABEL: @not_or_or_and_no_and_use3(
3523 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3524 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3525 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3526 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3527 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3528 ; CHECK-NEXT: ret i32 [[AND2]]
3530 %and1 = and i32 %b, %a
3531 %not1 = xor i32 %and1, -1
3532 %not2 = xor i32 %a, -1
3533 %or1 = or i32 %not2, %c
3534 %or2 = or i32 %or1, %b
3535 %and2 = and i32 %or2, %not1
3536 call void @use(i32 %not2)
3540 define i32 @not_or_or_and_no_and_use4(i32 %a, i32 %b, i32 %c) {
3541 ; CHECK-LABEL: @not_or_or_and_no_and_use4(
3542 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3543 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], -1
3544 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3545 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3546 ; CHECK-NEXT: call void @use(i32 [[NOT2]])
3547 ; CHECK-NEXT: ret i32 [[AND2]]
3549 %and1 = and i32 %b, %a
3550 %not1 = xor i32 %and1, -1
3551 %not2 = xor i32 %a, -1
3552 %or1 = or i32 %not2, %c
3553 %or2 = or i32 %or1, %b
3554 %and2 = and i32 %or2, %not1
3555 call void @use(i32 %not2)
3559 define i32 @not_or_or_and_no_and_use5(i32 %a, i32 %b, i32 %c) {
3560 ; CHECK-LABEL: @not_or_or_and_no_and_use5(
3561 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
3562 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
3563 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3564 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B]]
3565 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
3566 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[OR2]], [[NOT1]]
3567 ; CHECK-NEXT: call void @use(i32 [[AND1]])
3568 ; CHECK-NEXT: ret i32 [[AND2]]
3570 %and1 = and i32 %b, %a
3571 %not1 = xor i32 %and1, -1
3572 %not2 = xor i32 %a, -1
3573 %or1 = or i32 %not2, %b
3574 %or2 = or i32 %or1, %c
3575 %and2 = and i32 %or2, %not1
3576 call void @use(i32 %and1)
3580 define i32 @not_or_or_and_no_and_use6(i32 %a, i32 %b, i32 %c) {
3581 ; CHECK-LABEL: @not_or_or_and_no_and_use6(
3582 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
3583 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
3584 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3585 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B]]
3586 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
3587 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[OR2]], [[NOT1]]
3588 ; CHECK-NEXT: call void @use(i32 [[NOT1]])
3589 ; CHECK-NEXT: ret i32 [[AND2]]
3591 %and1 = and i32 %b, %a
3592 %not1 = xor i32 %and1, -1
3593 %not2 = xor i32 %a, -1
3594 %or1 = or i32 %not2, %b
3595 %or2 = or i32 %or1, %c
3596 %and2 = and i32 %or2, %not1
3597 call void @use(i32 %not1)
3601 define i32 @not_or_or_and_no_and_use7(i32 %a, i32 %b, i32 %c) {
3602 ; CHECK-LABEL: @not_or_or_and_no_and_use7(
3603 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A:%.*]], -1
3604 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B:%.*]]
3605 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1
3606 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[C:%.*]]
3607 ; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]
3608 ; CHECK-NEXT: call void @use(i32 [[OR1]])
3609 ; CHECK-NEXT: ret i32 [[AND2]]
3611 %and1 = and i32 %b, %a
3612 %not1 = xor i32 %and1, -1
3613 %not2 = xor i32 %a, -1
3614 %or1 = or i32 %not2, %b
3615 %or2 = or i32 %or1, %c
3616 %and2 = and i32 %or2, %not1
3617 call void @use(i32 %or1)
3621 define i32 @not_or_or_and_no_and_use8(i32 %a, i32 %b, i32 %c) {
3622 ; CHECK-LABEL: @not_or_or_and_no_and_use8(
3623 ; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B:%.*]], [[A:%.*]]
3624 ; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -1
3625 ; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -1
3626 ; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOT2]], [[B]]
3627 ; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C:%.*]]
3628 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[OR2]], [[NOT1]]
3629 ; CHECK-NEXT: call void @use(i32 [[OR2]])
3630 ; CHECK-NEXT: ret i32 [[AND2]]
3632 %and1 = and i32 %b, %a
3633 %not1 = xor i32 %and1, -1
3634 %not2 = xor i32 %a, -1
3635 %or1 = or i32 %not2, %b
3636 %or2 = or i32 %or1, %c
3637 %and2 = and i32 %or2, %not1
3638 call void @use(i32 %or2)
3642 define i4 @and_orn_xor(i4 %a, i4 %b) {
3643 ; CHECK-LABEL: @and_orn_xor(
3644 ; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[A:%.*]], -1
3645 ; CHECK-NEXT: [[R:%.*]] = and i4 [[TMP1]], [[B:%.*]]
3646 ; CHECK-NEXT: ret i4 [[R]]
3648 %xor = xor i4 %a, %b
3649 %nota = xor i4 %a, -1
3650 %or = or i4 %nota, %b
3651 %r = and i4 %or, %xor
3655 define <2 x i4> @and_orn_xor_commute1(<2 x i4> %a, <2 x i4> %b) {
3656 ; CHECK-LABEL: @and_orn_xor_commute1(
3657 ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[A:%.*]], <i4 -1, i4 -1>
3658 ; CHECK-NEXT: [[R:%.*]] = and <2 x i4> [[TMP1]], [[B:%.*]]
3659 ; CHECK-NEXT: ret <2 x i4> [[R]]
3661 %xor = xor <2 x i4> %a, %b
3662 %nota = xor <2 x i4> %a, <i4 -1, i4 undef>
3663 %or = or <2 x i4> %nota, %b
3664 %r = and <2 x i4> %xor, %or
3668 define i32 @and_orn_xor_commute2(i32 %a, i32 %b) {
3669 ; CHECK-LABEL: @and_orn_xor_commute2(
3670 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
3671 ; CHECK-NEXT: call void @use(i32 [[XOR]])
3672 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1
3673 ; CHECK-NEXT: [[R:%.*]] = and i32 [[TMP1]], [[B]]
3674 ; CHECK-NEXT: ret i32 [[R]]
3676 %xor = xor i32 %b, %a
3677 call void @use(i32 %xor)
3678 %nota = xor i32 %a, -1
3679 %or = or i32 %nota, %b
3680 %r = and i32 %or, %xor
3684 define i32 @and_orn_xor_commute3(i32 %a, i32 %b) {
3685 ; CHECK-LABEL: @and_orn_xor_commute3(
3686 ; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A:%.*]], -1
3687 ; CHECK-NEXT: call void @use(i32 [[NOTA]])
3688 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1
3689 ; CHECK-NEXT: [[R:%.*]] = and i32 [[TMP1]], [[B:%.*]]
3690 ; CHECK-NEXT: ret i32 [[R]]
3692 %xor = xor i32 %b, %a
3693 %nota = xor i32 %a, -1
3694 call void @use(i32 %nota)
3695 %or = or i32 %nota, %b
3696 %r = and i32 %xor, %or
3700 define i32 @and_orn_xor_commute5(i32 %pa, i32 %pb) {
3701 ; CHECK-LABEL: @and_orn_xor_commute5(
3702 ; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA:%.*]], [[PA]]
3703 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB:%.*]], [[PB]]
3704 ; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1
3705 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOTA]]
3706 ; CHECK-NEXT: call void @use(i32 [[OR]])
3707 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1
3708 ; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]
3709 ; CHECK-NEXT: ret i32 [[R]]
3711 %a = mul i32 %pa, %pa
3712 %b = mul i32 %pb, %pb
3713 %xor = xor i32 %a, %b
3714 %nota = xor i32 %a, -1
3715 %or = or i32 %b, %nota
3716 call void @use(i32 %or)
3717 %r = and i32 %or, %xor
3721 define i32 @and_orn_xor_commute6(i32 %pa, i32 %pb) {
3722 ; CHECK-LABEL: @and_orn_xor_commute6(
3723 ; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA:%.*]], [[PA]]
3724 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB:%.*]], [[PB]]
3725 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]
3726 ; CHECK-NEXT: call void @use(i32 [[XOR]])
3727 ; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1
3728 ; CHECK-NEXT: call void @use(i32 [[NOTA]])
3729 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1
3730 ; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]
3731 ; CHECK-NEXT: ret i32 [[R]]
3733 %a = mul i32 %pa, %pa
3734 %b = mul i32 %pb, %pb
3735 %xor = xor i32 %a, %b
3736 call void @use(i32 %xor)
3737 %nota = xor i32 %a, -1
3738 call void @use(i32 %nota)
3739 %or = or i32 %b, %nota
3740 %r = and i32 %xor, %or
3744 define i32 @and_orn_xor_commute7(i32 %pa, i32 %pb) {
3745 ; CHECK-LABEL: @and_orn_xor_commute7(
3746 ; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA:%.*]], [[PA]]
3747 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB:%.*]], [[PB]]
3748 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]
3749 ; CHECK-NEXT: call void @use(i32 [[XOR]])
3750 ; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1
3751 ; CHECK-NEXT: call void @use(i32 [[NOTA]])
3752 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOTA]]
3753 ; CHECK-NEXT: call void @use(i32 [[OR]])
3754 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1
3755 ; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]
3756 ; CHECK-NEXT: ret i32 [[R]]
3758 %a = mul i32 %pa, %pa
3759 %b = mul i32 %pb, %pb
3760 %xor = xor i32 %b, %a
3761 call void @use(i32 %xor)
3762 %nota = xor i32 %a, -1
3763 call void @use(i32 %nota)
3764 %or = or i32 %b, %nota
3765 call void @use(i32 %or)
3766 %r = and i32 %or, %xor
3770 define i32 @and_orn_xor_commute8(i32 %pa, i32 %pb) {
3771 ; CHECK-LABEL: @and_orn_xor_commute8(
3772 ; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA:%.*]], [[PA]]
3773 ; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB:%.*]], [[PB]]
3774 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -1
3775 ; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]
3776 ; CHECK-NEXT: ret i32 [[R]]
3778 %a = mul i32 %pa, %pa
3779 %b = mul i32 %pb, %pb
3780 %xor = xor i32 %b, %a
3781 %nota = xor i32 %a, -1
3782 %or = or i32 %b, %nota
3783 %r = and i32 %xor, %or