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