5122 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i32)5declare void @use_i16(i8)6declare void @use_2xi16(<2 x i16>)7declare void @use_i8(i8)8declare void @use_i1(i1)9 10; a & (a ^ b) --> a & ~b11 12define i32 @and_xor_common_op(i32 %pa, i32 %pb) {13; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op14; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {15; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA]]16; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB]]17; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -118; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]]19; CHECK-NEXT: ret i32 [[R]]20;21 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization22 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization23 %xor = xor i32 %a, %b24 %r = and i32 %a, %xor25 ret i32 %r26}27 28; a & (b ^ a) --> a & ~b29 30define i32 @and_xor_common_op_commute1(i32 %pa, i32 %pb) {31; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute132; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {33; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA]]34; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB]]35; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -136; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]]37; CHECK-NEXT: ret i32 [[R]]38;39 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization40 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization41 %xor = xor i32 %b, %a42 %r = and i32 %a, %xor43 ret i32 %r44}45 46; (b ^ a) & a --> a & ~b47 48define i32 @and_xor_common_op_commute2(i32 %pa, i32 %pb) {49; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute250; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {51; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA]]52; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB]]53; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -154; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]]55; CHECK-NEXT: ret i32 [[R]]56;57 %a = udiv i32 42, %pa ; thwart complexity-based canonicalization58 %b = udiv i32 43, %pb ; thwart complexity-based canonicalization59 %xor = xor i32 %b, %a60 %r = and i32 %xor, %a61 ret i32 %r62}63 64; (a ^ b) & a --> a & ~b65 66define <2 x i32> @and_xor_common_op_commute3(<2 x i32> %pa, <2 x i32> %pb) {67; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_commute368; CHECK-SAME: (<2 x i32> [[PA:%.*]], <2 x i32> [[PB:%.*]]) {69; CHECK-NEXT: [[A:%.*]] = udiv <2 x i32> <i32 42, i32 43>, [[PA]]70; CHECK-NEXT: [[B:%.*]] = udiv <2 x i32> <i32 43, i32 42>, [[PB]]71; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[B]], splat (i32 -1)72; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], [[TMP1]]73; CHECK-NEXT: ret <2 x i32> [[R]]74;75 %a = udiv <2 x i32> <i32 42, i32 43>, %pa ; thwart complexity-based canonicalization76 %b = udiv <2 x i32> <i32 43, i32 42>, %pb ; thwart complexity-based canonicalization77 %xor = xor <2 x i32> %a, %b78 %r = and <2 x i32> %xor, %a79 ret <2 x i32> %r80}81 82; It's ok to match a common constant.83; The xor should be a 'not' op (-1 constant).84 85define <4 x i32> @and_xor_common_op_constant(<4 x i32> %A) {86; CHECK-LABEL: define {{[^@]+}}@and_xor_common_op_constant87; CHECK-SAME: (<4 x i32> [[A:%.*]]) {88; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[A]], splat (i32 -1)89; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[TMP1]], <i32 1, i32 2, i32 3, i32 4>90; CHECK-NEXT: ret <4 x i32> [[TMP2]]91;92 %1 = xor <4 x i32> %A, <i32 1, i32 2, i32 3, i32 4>93 %2 = and <4 x i32> <i32 1, i32 2, i32 3, i32 4>, %194 ret <4 x i32> %295}96 97; a & (a ^ ~b) --> a & b98 99define i32 @and_xor_not_common_op(i32 %a, i32 %b) {100; CHECK-LABEL: define {{[^@]+}}@and_xor_not_common_op101; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {102; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]]103; CHECK-NEXT: ret i32 [[T4]]104;105 %b2 = xor i32 %b, -1106 %t2 = xor i32 %a, %b2107 %t4 = and i32 %t2, %a108 ret i32 %t4109}110 111; a & (a ^ ~b) --> a & b112 113define i32 @and_xor_not_common_op_extrause(i32 %a, i32 %b, ptr %dst) {114; CHECK-LABEL: define {{[^@]+}}@and_xor_not_common_op_extrause115; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], ptr [[DST:%.*]]) {116; CHECK-NEXT: [[B2:%.*]] = xor i32 [[B]], -1117; CHECK-NEXT: store i32 [[B2]], ptr [[DST]], align 4118; CHECK-NEXT: [[T4:%.*]] = and i32 [[B]], [[A]]119; CHECK-NEXT: ret i32 [[T4]]120;121 %b2 = xor i32 %b, -1122 store i32 %b2, ptr %dst123 %t2 = xor i32 %a, %b2124 %t4 = and i32 %t2, %a125 ret i32 %t4126}127 128; a & ~(a ^ b) --> a & b129 130define i32 @and_not_xor_common_op(i32 %a, i32 %b) {131; CHECK-LABEL: define {{[^@]+}}@and_not_xor_common_op132; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {133; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]]134; CHECK-NEXT: ret i32 [[T4]]135;136 %b2 = xor i32 %b, %a137 %t2 = xor i32 %b2, -1138 %t4 = and i32 %t2, %a139 ret i32 %t4140}141 142declare i32 @gen32()143define i32 @and_not_xor_common_op_commutative(i32 %b) {144; CHECK-LABEL: define {{[^@]+}}@and_not_xor_common_op_commutative145; CHECK-SAME: (i32 [[B:%.*]]) {146; CHECK-NEXT: [[A:%.*]] = call i32 @gen32()147; CHECK-NEXT: [[T4:%.*]] = and i32 [[A]], [[B]]148; CHECK-NEXT: ret i32 [[T4]]149;150 %a = call i32 @gen32()151 %b2 = xor i32 %a, %b ; swapped order152 %t2 = xor i32 %b2, -1153 %t4 = and i32 %a, %t2 ; swapped order154 ret i32 %t4155}156 157; rdar://10770603158; (x & y) | (x ^ y) -> x | y159 160define i64 @or(i64 %x, i64 %y) {161; CHECK-LABEL: define {{[^@]+}}@or162; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {163; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[X]]164; CHECK-NEXT: ret i64 [[TMP1]]165;166 %1 = and i64 %y, %x167 %2 = xor i64 %y, %x168 %3 = add i64 %1, %2169 ret i64 %3170}171 172; (x & y) + (x ^ y) -> x | y173 174define i64 @or2(i64 %x, i64 %y) {175; CHECK-LABEL: define {{[^@]+}}@or2176; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {177; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[X]]178; CHECK-NEXT: ret i64 [[TMP1]]179;180 %1 = and i64 %y, %x181 %2 = xor i64 %y, %x182 %3 = or i64 %1, %2183 ret i64 %3184}185 186; ((x & y) ^ z) | y -> (z | y)187 188define i64 @and_xor_or1(i64 %px, i64 %py, i64 %pz) {189; CHECK-LABEL: define {{[^@]+}}@and_xor_or1190; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {191; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]192; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]193; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]]194; CHECK-NEXT: ret i64 [[TMP1]]195;196 %x = udiv i64 42, %px ; thwart complexity-based canonicalization197 %y = udiv i64 42, %py ; thwart complexity-based canonicalization198 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization199 %1 = and i64 %x, %y200 %2 = xor i64 %1, %z201 %3 = or i64 %2, %y202 ret i64 %3203}204 205; ((y & x) ^ z) | y -> (z | y)206 207define i64 @and_xor_or2(i64 %px, i64 %py, i64 %pz) {208; CHECK-LABEL: define {{[^@]+}}@and_xor_or2209; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {210; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]211; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]212; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]]213; CHECK-NEXT: ret i64 [[TMP1]]214;215 %x = udiv i64 42, %px ; thwart complexity-based canonicalization216 %y = udiv i64 42, %py ; thwart complexity-based canonicalization217 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization218 %1 = and i64 %y, %x219 %2 = xor i64 %1, %z220 %3 = or i64 %2, %y221 ret i64 %3222}223 224; (z ^ (x & y)) | y -> (z | y)225 226define i64 @and_xor_or3(i64 %px, i64 %py, i64 %pz) {227; CHECK-LABEL: define {{[^@]+}}@and_xor_or3228; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {229; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]230; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]231; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]]232; CHECK-NEXT: ret i64 [[TMP1]]233;234 %x = udiv i64 42, %px ; thwart complexity-based canonicalization235 %y = udiv i64 42, %py ; thwart complexity-based canonicalization236 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization237 %1 = and i64 %x, %y238 %2 = xor i64 %z, %1239 %3 = or i64 %2, %y240 ret i64 %3241}242 243; (z ^ (y & x)) | y -> (z | y)244 245define i64 @and_xor_or4(i64 %px, i64 %py, i64 %pz) {246; CHECK-LABEL: define {{[^@]+}}@and_xor_or4247; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {248; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]249; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]250; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Z]], [[Y]]251; CHECK-NEXT: ret i64 [[TMP1]]252;253 %x = udiv i64 42, %px ; thwart complexity-based canonicalization254 %y = udiv i64 42, %py ; thwart complexity-based canonicalization255 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization256 %1 = and i64 %y, %x257 %2 = xor i64 %z, %1258 %3 = or i64 %2, %y259 ret i64 %3260}261 262; y | ((x & y) ^ z) -> (y | z)263 264define i64 @and_xor_or5(i64 %px, i64 %py, i64 %pz) {265; CHECK-LABEL: define {{[^@]+}}@and_xor_or5266; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {267; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]268; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]269; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]]270; CHECK-NEXT: ret i64 [[TMP1]]271;272 %x = udiv i64 42, %px ; thwart complexity-based canonicalization273 %y = udiv i64 42, %py ; thwart complexity-based canonicalization274 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization275 %1 = and i64 %x, %y276 %2 = xor i64 %1, %z277 %3 = or i64 %y, %2278 ret i64 %3279}280 281; y | ((y & x) ^ z) -> (y | z)282 283define i64 @and_xor_or6(i64 %px, i64 %py, i64 %pz) {284; CHECK-LABEL: define {{[^@]+}}@and_xor_or6285; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {286; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]287; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]288; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]]289; CHECK-NEXT: ret i64 [[TMP1]]290;291 %x = udiv i64 42, %px ; thwart complexity-based canonicalization292 %y = udiv i64 42, %py ; thwart complexity-based canonicalization293 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization294 %1 = and i64 %y, %x295 %2 = xor i64 %1, %z296 %3 = or i64 %y, %2297 ret i64 %3298}299 300; y | (z ^ (x & y)) -> (y | z)301 302define i64 @and_xor_or7(i64 %px, i64 %py, i64 %pz) {303; CHECK-LABEL: define {{[^@]+}}@and_xor_or7304; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {305; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]306; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]307; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]]308; CHECK-NEXT: ret i64 [[TMP1]]309;310 %x = udiv i64 42, %px ; thwart complexity-based canonicalization311 %y = udiv i64 42, %py ; thwart complexity-based canonicalization312 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization313 %1 = and i64 %x, %y314 %2 = xor i64 %z, %1315 %3 = or i64 %y, %2316 ret i64 %3317}318 319; y | (z ^ (y & x)) -> (y | z)320 321define i64 @and_xor_or8(i64 %px, i64 %py, i64 %pz) {322; CHECK-LABEL: define {{[^@]+}}@and_xor_or8323; CHECK-SAME: (i64 [[PX:%.*]], i64 [[PY:%.*]], i64 [[PZ:%.*]]) {324; CHECK-NEXT: [[Y:%.*]] = udiv i64 42, [[PY]]325; CHECK-NEXT: [[Z:%.*]] = udiv i64 42, [[PZ]]326; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y]], [[Z]]327; CHECK-NEXT: ret i64 [[TMP1]]328;329 %x = udiv i64 42, %px ; thwart complexity-based canonicalization330 %y = udiv i64 42, %py ; thwart complexity-based canonicalization331 %z = udiv i64 42, %pz ; thwart complexity-based canonicalization332 %1 = and i64 %y, %x333 %2 = xor i64 %z, %1334 %3 = or i64 %y, %2335 ret i64 %3336}337 338; w | (z ^ (y & x))339 340define i64 @and_xor_or_negative(i64 %x, i64 %y, i64 %z, i64 %w) {341; CHECK-LABEL: define {{[^@]+}}@and_xor_or_negative342; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]], i64 [[W:%.*]]) {343; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[Y]], [[X]]344; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[Z]], [[TMP1]]345; CHECK-NEXT: [[TMP3:%.*]] = or i64 [[W]], [[TMP2]]346; CHECK-NEXT: ret i64 [[TMP3]]347;348 %1 = and i64 %y, %x349 %2 = xor i64 %z, %1350 %3 = or i64 %w, %2351 ret i64 %3352}353 354; PR37098 - https://bugs.llvm.org/show_bug.cgi?id=37098355; Reassociate bitwise logic to eliminate a shift.356; There are 4 commuted * 3 shift ops * 3 logic ops = 36 potential variations of this fold.357; Mix the commutation options to provide coverage using less tests.358 359define i8 @and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {360; CHECK-LABEL: define {{[^@]+}}@and_shl361; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {362; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], [[Y]]363; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]]364; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP2]], [[Z]]365; CHECK-NEXT: ret i8 [[R]]366;367 %sx = shl i8 %x, %shamt368 %sy = shl i8 %y, %shamt369 %a = and i8 %sx, %z370 %r = and i8 %sy, %a371 ret i8 %r372}373 374define i8 @or_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {375; CHECK-LABEL: define {{[^@]+}}@or_shl376; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {377; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]]378; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]]379; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]]380; CHECK-NEXT: ret i8 [[R]]381;382 %sx = shl i8 %x, %shamt383 %sy = shl i8 %y, %shamt384 %a = or i8 %sx, %z385 %r = or i8 %a, %sy386 ret i8 %r387}388 389define i8 @xor_shl(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {390; CHECK-LABEL: define {{[^@]+}}@xor_shl391; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {392; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]]393; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], [[Y]]394; CHECK-NEXT: [[TMP2:%.*]] = shl i8 [[TMP1]], [[SHAMT]]395; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], [[Z]]396; CHECK-NEXT: ret i8 [[R]]397;398 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization399 %sx = shl i8 %x, %shamt400 %sy = shl i8 %y, %shamt401 %a = xor i8 %z, %sx402 %r = xor i8 %a, %sy403 ret i8 %r404}405 406define i8 @and_lshr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {407; CHECK-LABEL: define {{[^@]+}}@and_lshr408; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {409; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]]410; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], [[Y]]411; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]412; CHECK-NEXT: [[R:%.*]] = and i8 [[TMP2]], [[Z]]413; CHECK-NEXT: ret i8 [[R]]414;415 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization416 %sx = lshr i8 %x, %shamt417 %sy = lshr i8 %y, %shamt418 %a = and i8 %z, %sx419 %r = and i8 %sy, %a420 ret i8 %r421}422 423define i8 @or_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {424; CHECK-LABEL: define {{[^@]+}}@or_lshr425; 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]]430;431 %sx = lshr i8 %x, %shamt432 %sy = lshr i8 %y, %shamt433 %a = or i8 %sx, %z434 %r = or i8 %sy, %a435 ret i8 %r436}437 438define i8 @or_lshr_commuted1(i8 %x, i8 %y, i8 %z, i8 %shamt) {439; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted1440; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {441; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]]442; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]443; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]]444; CHECK-NEXT: ret i8 [[R]]445;446 %sx = lshr i8 %x, %shamt447 %sy = lshr i8 %y, %shamt448 %a = or i8 %z, %sx449 %r = or i8 %sy, %a450 ret i8 %r451}452 453define i8 @or_lshr_commuted2(i8 %x, i8 %y, i8 %z, i8 %shamt) {454; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted2455; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {456; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]]457; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]458; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]]459; CHECK-NEXT: ret i8 [[R]]460;461 %sx = lshr i8 %x, %shamt462 %sy = lshr i8 %y, %shamt463 %a = or i8 %z, %sx464 %r = or i8 %a, %sy465 ret i8 %r466}467 468define i8 @or_lshr_commuted3(i8 %x, i8 %y, i8 %z, i8 %shamt) {469; CHECK-LABEL: define {{[^@]+}}@or_lshr_commuted3470; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {471; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[X]], [[Y]]472; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]473; CHECK-NEXT: [[R:%.*]] = or i8 [[TMP2]], [[Z]]474; CHECK-NEXT: ret i8 [[R]]475;476 %sx = lshr i8 %x, %shamt477 %sy = lshr i8 %y, %shamt478 %a = or i8 %sx, %z479 %r = or i8 %a, %sy480 ret i8 %r481}482 483define i8 @xor_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) {484; CHECK-LABEL: define {{[^@]+}}@xor_lshr485; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {486; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], [[Y]]487; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]488; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], [[Z]]489; CHECK-NEXT: ret i8 [[R]]490;491 %sx = lshr i8 %x, %shamt492 %sy = lshr i8 %y, %shamt493 %a = xor i8 %sx, %z494 %r = xor i8 %a, %sy495 ret i8 %r496}497 498define i8 @and_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {499; CHECK-LABEL: define {{[^@]+}}@and_ashr500; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {501; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]]502; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]]503; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]]504; CHECK-NEXT: [[A:%.*]] = and i8 [[Z]], [[SX]]505; CHECK-NEXT: [[R:%.*]] = and i8 [[A]], [[SY]]506; CHECK-NEXT: ret i8 [[R]]507;508 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization509 %sx = ashr i8 %x, %shamt510 %sy = ashr i8 %y, %shamt511 %a = and i8 %z, %sx512 %r = and i8 %a, %sy513 ret i8 %r514}515 516define i8 @or_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) {517; CHECK-LABEL: define {{[^@]+}}@or_ashr518; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[ZARG:%.*]], i8 [[SHAMT:%.*]]) {519; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG]]520; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X]], [[SHAMT]]521; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y]], [[SHAMT]]522; CHECK-NEXT: [[A:%.*]] = or i8 [[Z]], [[SX]]523; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]]524; CHECK-NEXT: ret i8 [[R]]525;526 %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization527 %sx = ashr i8 %x, %shamt528 %sy = ashr i8 %y, %shamt529 %a = or i8 %z, %sx530 %r = or i8 %sy, %a531 ret i8 %r532}533 534define <2 x i8> @xor_ashr(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z, <2 x i8> %shamt) {535; CHECK-LABEL: define {{[^@]+}}@xor_ashr536; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]], <2 x i8> [[SHAMT:%.*]]) {537; CHECK-NEXT: [[SX:%.*]] = ashr <2 x i8> [[X]], [[SHAMT]]538; CHECK-NEXT: [[SY:%.*]] = ashr <2 x i8> [[Y]], [[SHAMT]]539; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> [[SX]], [[Z]]540; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[A]], [[SY]]541; CHECK-NEXT: ret <2 x i8> [[R]]542;543 %sx = ashr <2 x i8> %x, %shamt544 %sy = ashr <2 x i8> %y, %shamt545 %a = xor <2 x i8> %sx, %z546 %r = xor <2 x i8> %a, %sy547 ret <2 x i8> %r548}549 550; Negative test - different logic ops551 552define i8 @or_and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {553; CHECK-LABEL: define {{[^@]+}}@or_and_shl554; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {555; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X]], [[SHAMT]]556; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]557; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z]]558; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]]559; CHECK-NEXT: ret i8 [[R]]560;561 %sx = shl i8 %x, %shamt562 %sy = shl i8 %y, %shamt563 %a = or i8 %sx, %z564 %r = and i8 %sy, %a565 ret i8 %r566}567 568; Negative test - different shift ops569 570define i8 @or_lshr_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) {571; CHECK-LABEL: define {{[^@]+}}@or_lshr_shl572; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {573; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]574; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y]], [[SHAMT]]575; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z]]576; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[SY]]577; CHECK-NEXT: ret i8 [[R]]578;579 %sx = lshr i8 %x, %shamt580 %sy = shl i8 %y, %shamt581 %a = or i8 %sx, %z582 %r = or i8 %a, %sy583 ret i8 %r584}585 586; Negative test - different shift amounts587 588define i8 @or_lshr_shamt2(i8 %x, i8 %y, i8 %z, i8 %shamt) {589; CHECK-LABEL: define {{[^@]+}}@or_lshr_shamt2590; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {591; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X]], 5592; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y]], [[SHAMT]]593; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z]]594; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]]595; CHECK-NEXT: ret i8 [[R]]596;597 %sx = lshr i8 %x, 5598 %sy = lshr i8 %y, %shamt599 %a = or i8 %sx, %z600 %r = or i8 %sy, %a601 ret i8 %r602}603 604; Negative test - multi-use605 606define i8 @xor_lshr_multiuse(i8 %x, i8 %y, i8 %z, i8 %shamt) {607; CHECK-LABEL: define {{[^@]+}}@xor_lshr_multiuse608; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[SHAMT:%.*]]) {609; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X]], [[SHAMT]]610; CHECK-NEXT: [[A:%.*]] = xor i8 [[SX]], [[Z]]611; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], [[Y]]612; CHECK-NEXT: [[TMP2:%.*]] = lshr i8 [[TMP1]], [[SHAMT]]613; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP2]], [[Z]]614; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[A]], [[R]]615; CHECK-NEXT: ret i8 [[R2]]616;617 %sx = lshr i8 %x, %shamt618 %sy = lshr i8 %y, %shamt619 %a = xor i8 %sx, %z620 %r = xor i8 %a, %sy621 %r2 = sdiv i8 %a, %r622 ret i8 %r2623}624 625; Reassociate chains of extend(X) | (extend(Y) | Z).626; Check that logical op is performed on a smaller type and then extended.627 628define i64 @sext_or_chain(i64 %a, i16 %b, i16 %c) {629; CHECK-LABEL: define {{[^@]+}}@sext_or_chain630; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {631; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64632; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64633; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]]634; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]635; CHECK-NEXT: ret i64 [[OR2]]636;637 %conv = sext i16 %b to i64638 %conv2 = sext i16 %c to i64639 %or = or i64 %a, %conv640 %or2 = or i64 %or, %conv2641 ret i64 %or2642}643 644define i64 @zext_or_chain(i64 %a, i16 %b, i16 %c) {645; CHECK-LABEL: define {{[^@]+}}@zext_or_chain646; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {647; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B]] to i64648; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C]] to i64649; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]]650; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]651; CHECK-NEXT: ret i64 [[OR2]]652;653 %conv = zext i16 %b to i64654 %conv2 = zext i16 %c to i64655 %or = or i64 %a, %conv656 %or2 = or i64 %or, %conv2657 ret i64 %or2658}659 660define i64 @sext_and_chain(i64 %a, i16 %b, i16 %c) {661; CHECK-LABEL: define {{[^@]+}}@sext_and_chain662; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {663; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64664; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64665; CHECK-NEXT: [[AND:%.*]] = and i64 [[A]], [[CONV]]666; CHECK-NEXT: [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]667; CHECK-NEXT: ret i64 [[AND2]]668;669 %conv = sext i16 %b to i64670 %conv2 = sext i16 %c to i64671 %and = and i64 %a, %conv672 %and2 = and i64 %and, %conv2673 ret i64 %and2674}675 676define i64 @zext_and_chain(i64 %a, i16 %b, i16 %c) {677; CHECK-LABEL: define {{[^@]+}}@zext_and_chain678; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {679; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B]] to i64680; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C]] to i64681; CHECK-NEXT: [[AND:%.*]] = and i64 [[A]], [[CONV]]682; CHECK-NEXT: [[AND2:%.*]] = and i64 [[AND]], [[CONV2]]683; CHECK-NEXT: ret i64 [[AND2]]684;685 %conv = zext i16 %b to i64686 %conv2 = zext i16 %c to i64687 %and = and i64 %a, %conv688 %and2 = and i64 %and, %conv2689 ret i64 %and2690}691 692define i64 @sext_xor_chain(i64 %a, i16 %b, i16 %c) {693; CHECK-LABEL: define {{[^@]+}}@sext_xor_chain694; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {695; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64696; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64697; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A]], [[CONV]]698; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]699; CHECK-NEXT: ret i64 [[XOR2]]700;701 %conv = sext i16 %b to i64702 %conv2 = sext i16 %c to i64703 %xor = xor i64 %a, %conv704 %xor2 = xor i64 %xor, %conv2705 ret i64 %xor2706}707 708define i64 @zext_xor_chain(i64 %a, i16 %b, i16 %c) {709; CHECK-LABEL: define {{[^@]+}}@zext_xor_chain710; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]]) {711; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[B]] to i64712; CHECK-NEXT: [[CONV2:%.*]] = zext i16 [[C]] to i64713; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A]], [[CONV]]714; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[XOR]], [[CONV2]]715; CHECK-NEXT: ret i64 [[XOR2]]716;717 %conv = zext i16 %b to i64718 %conv2 = zext i16 %c to i64719 %xor = xor i64 %a, %conv720 %xor2 = xor i64 %xor, %conv2721 ret i64 %xor2722}723 724; Negative test with more uses.725define i64 @sext_or_chain_two_uses1(i64 %a, i16 %b, i16 %c, i64 %d) {726; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses1727; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) {728; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64729; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64730; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]]731; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]732; CHECK-NEXT: [[USE:%.*]] = udiv i64 [[OR]], [[D]]733; CHECK-NEXT: [[RETVAL:%.*]] = udiv i64 [[OR2]], [[USE]]734; CHECK-NEXT: ret i64 [[RETVAL]]735;736 %conv = sext i16 %b to i64737 %conv2 = sext i16 %c to i64738 ; %or has two uses739 %or = or i64 %a, %conv740 %or2 = or i64 %or, %conv2741 %use = udiv i64 %or, %d742 %retval = udiv i64 %or2, %use743 ret i64 %retval744}745define i64 @sext_or_chain_two_uses2(i64 %a, i16 %b, i16 %c, i64 %d) {746; CHECK-LABEL: define {{[^@]+}}@sext_or_chain_two_uses2747; CHECK-SAME: (i64 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i64 [[D:%.*]]) {748; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[B]] to i64749; CHECK-NEXT: [[CONV2:%.*]] = sext i16 [[C]] to i64750; CHECK-NEXT: [[OR:%.*]] = or i64 [[A]], [[CONV]]751; CHECK-NEXT: [[OR2:%.*]] = or i64 [[OR]], [[CONV2]]752; CHECK-NEXT: [[USE1:%.*]] = udiv i64 [[OR2]], [[D]]753; CHECK-NEXT: [[USE2:%.*]] = udiv i64 [[OR2]], [[USE1]]754; CHECK-NEXT: ret i64 [[USE2]]755;756 %conv = sext i16 %b to i64757 %conv2 = sext i16 %c to i64758 %or = or i64 %a, %conv759 ; %or2 has two uses760 %or2 = or i64 %or, %conv2761 %use1 = udiv i64 %or2, %d762 %use2 = udiv i64 %or2, %use1763 ret i64 %use2764}765 766; (a & ~b) & ~c --> a & ~(b | c)767 768define i32 @not_and_and_not(i32 %a0, i32 %b, i32 %c) {769; CHECK-LABEL: define {{[^@]+}}@not_and_and_not770; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {771; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]772; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C]]773; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1774; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]]775; CHECK-NEXT: ret i32 [[AND2]]776;777 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization778 %not1 = xor i32 %b, -1779 %not2 = xor i32 %c, -1780 %and1 = and i32 %a, %not1781 %and2 = and i32 %and1, %not2782 ret i32 %and2783}784 785define <4 x i64> @not_and_and_not_4i64(<4 x i64> %a0, <4 x i64> %b, <4 x i64> %c) {786; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_4i64787; CHECK-SAME: (<4 x i64> [[A0:%.*]], <4 x i64> [[B:%.*]], <4 x i64> [[C:%.*]]) {788; CHECK-NEXT: [[A:%.*]] = sdiv <4 x i64> splat (i64 42), [[A0]]789; CHECK-NEXT: [[TMP1:%.*]] = or <4 x i64> [[B]], [[C]]790; CHECK-NEXT: [[TMP2:%.*]] = xor <4 x i64> [[TMP1]], splat (i64 -1)791; CHECK-NEXT: [[AND2:%.*]] = and <4 x i64> [[A]], [[TMP2]]792; CHECK-NEXT: ret <4 x i64> [[AND2]]793;794 %a = sdiv <4 x i64> <i64 42, i64 42, i64 42, i64 42>, %a0 ; thwart complexity-based canonicalization795 %not1 = xor <4 x i64> %b, <i64 -1, i64 -1, i64 -1, i64 -1>796 %not2 = xor <4 x i64> %c, <i64 -1, i64 -1, i64 -1, i64 -1>797 %and1 = and <4 x i64> %a, %not1798 %and2 = and <4 x i64> %and1, %not2799 ret <4 x i64> %and2800}801 802; (~b & a) & ~c --> a & ~(b | c)803 804define i32 @not_and_and_not_commute1(i32 %a, i32 %b, i32 %c) {805; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute1806; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {807; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C]]808; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1809; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]]810; CHECK-NEXT: ret i32 [[AND2]]811;812 %not1 = xor i32 %b, -1813 %not2 = xor i32 %c, -1814 %and1 = and i32 %not1, %a815 %and2 = and i32 %and1, %not2816 ret i32 %and2817}818 819; ~c & (a & ~b) --> a & ~(b | c)820 821define i32 @not_and_and_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {822; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_commute2_extra_not_use823; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {824; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]825; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1826; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B]], [[C]]827; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1828; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[TMP2]]829; CHECK-NEXT: call void @use(i32 [[NOT2]])830; CHECK-NEXT: ret i32 [[AND2]]831;832 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization833 %not1 = xor i32 %b, -1834 %not2 = xor i32 %c, -1835 %and1 = and i32 %a, %not1836 %and2 = and i32 %not2, %and1837 call void @use(i32 %not2)838 ret i32 %and2839}840 841define i32 @not_and_and_not_extra_and1_use(i32 %a0, i32 %b, i32 %c) {842; CHECK-LABEL: define {{[^@]+}}@not_and_and_not_extra_and1_use843; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {844; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]845; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[B]], -1846; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1847; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]]848; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[NOT2]]849; CHECK-NEXT: call void @use(i32 [[AND1]])850; CHECK-NEXT: ret i32 [[AND2]]851;852 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization853 %not1 = xor i32 %b, -1854 %not2 = xor i32 %c, -1855 %and1 = and i32 %a, %not1856 %and2 = and i32 %and1, %not2857 call void @use(i32 %and1)858 ret i32 %and2859}860 861; (a | ~b) | ~c --> a | ~(b & c)862 863define i32 @not_or_or_not(i32 %a0, i32 %b, i32 %c) {864; CHECK-LABEL: define {{[^@]+}}@not_or_or_not865; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {866; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]867; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C]]868; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1869; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]]870; CHECK-NEXT: ret i32 [[OR2]]871;872 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization873 %not1 = xor i32 %b, -1874 %not2 = xor i32 %c, -1875 %or1 = or i32 %a, %not1876 %or2 = or i32 %or1, %not2877 ret i32 %or2878}879 880define <2 x i6> @not_or_or_not_2i6(<2 x i6> %a0, <2 x i6> %b, <2 x i6> %c) {881; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_2i6882; CHECK-SAME: (<2 x i6> [[A0:%.*]], <2 x i6> [[B:%.*]], <2 x i6> [[C:%.*]]) {883; CHECK-NEXT: [[A:%.*]] = sdiv <2 x i6> splat (i6 3), [[A0]]884; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i6> [[B]], [[C]]885; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i6> [[TMP1]], splat (i6 -1)886; CHECK-NEXT: [[OR2:%.*]] = or <2 x i6> [[A]], [[TMP2]]887; CHECK-NEXT: ret <2 x i6> [[OR2]]888;889 %a = sdiv <2 x i6> <i6 3, i6 3>, %a0 ; thwart complexity-based canonicalization890 %not1 = xor <2 x i6> %b, <i6 -1, i6 -1>891 %not2 = xor <2 x i6> %c, <i6 -1, i6 poison>892 %or1 = or <2 x i6> %a, %not1893 %or2 = or <2 x i6> %or1, %not2894 ret <2 x i6> %or2895}896 897; (~b | a) | ~c --> a | ~(b & c)898 899define i32 @not_or_or_not_commute1(i32 %a, i32 %b, i32 %c) {900; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute1901; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {902; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C]]903; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1904; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]]905; CHECK-NEXT: ret i32 [[OR2]]906;907 %not1 = xor i32 %b, -1908 %not2 = xor i32 %c, -1909 %or1 = or i32 %not1, %a910 %or2 = or i32 %or1, %not2911 ret i32 %or2912}913 914; ~c | (a | ~b) --> a | ~(b & c)915 916define i32 @not_or_or_not_commute2_extra_not_use(i32 %a0, i32 %b, i32 %c) {917; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_commute2_extra_not_use918; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {919; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]920; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1921; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[B]], [[C]]922; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1923; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[TMP2]]924; CHECK-NEXT: call void @use(i32 [[NOT2]])925; CHECK-NEXT: ret i32 [[OR2]]926;927 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization928 %not1 = xor i32 %b, -1929 %not2 = xor i32 %c, -1930 %or1 = or i32 %a, %not1931 %or2 = or i32 %not2, %or1932 call void @use(i32 %not2)933 ret i32 %or2934}935 936define i32 @not_or_or_not_extra_or1_use(i32 %a0, i32 %b, i32 %c) {937; CHECK-LABEL: define {{[^@]+}}@not_or_or_not_extra_or1_use938; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {939; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]940; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[B]], -1941; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[C]], -1942; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]943; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[NOT2]]944; CHECK-NEXT: call void @use(i32 [[OR1]])945; CHECK-NEXT: ret i32 [[OR2]]946;947 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization948 %not1 = xor i32 %b, -1949 %not2 = xor i32 %c, -1950 %or1 = or i32 %a, %not1951 %or2 = or i32 %or1, %not2952 call void @use(i32 %or1)953 ret i32 %or2954}955 956; (c & ~(a | b)) | (b & ~(a | c)) --> ~a & (b ^ c)957 958define i32 @or_not_and(i32 %a, i32 %b, i32 %c) {959; CHECK-LABEL: define {{[^@]+}}@or_not_and960; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {961; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]962; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1963; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]964; CHECK-NEXT: ret i32 [[OR3]]965;966 %or1 = or i32 %a, %b967 %not1 = xor i32 %or1, -1968 %and1 = and i32 %not1, %c969 %or2 = or i32 %a, %c970 %not2 = xor i32 %or2, -1971 %and2 = and i32 %not2, %b972 %or3 = or i32 %and1, %and2973 ret i32 %or3974}975 976define i32 @or_not_and_commute1(i32 %a, i32 %b0, i32 %c) {977; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute1978; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {979; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]980; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]981; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -1982; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]983; CHECK-NEXT: ret i32 [[OR3]]984;985 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization986 %or1 = or i32 %a, %b987 %not1 = xor i32 %or1, -1988 %and1 = and i32 %not1, %c989 %or2 = or i32 %a, %c990 %not2 = xor i32 %or2, -1991 %and2 = and i32 %b, %not2992 %or3 = or i32 %and1, %and2993 ret i32 %or3994}995 996define i32 @or_not_and_commute2(i32 %a, i32 %b0, i32 %c) {997; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute2998; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {999; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1000; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]1001; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11002; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1003; CHECK-NEXT: ret i32 [[OR3]]1004;1005 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1006 %or1 = or i32 %a, %b1007 %not1 = xor i32 %or1, -11008 %and1 = and i32 %not1, %c1009 %or2 = or i32 %a, %c1010 %not2 = xor i32 %or2, -11011 %and2 = and i32 %b, %not21012 %or3 = or i32 %and2, %and11013 ret i32 %or31014}1015 1016define i32 @or_not_and_commute3(i32 %a, i32 %b, i32 %c) {1017; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute31018; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1019; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1020; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11021; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1022; CHECK-NEXT: ret i32 [[OR3]]1023;1024 %or1 = or i32 %b, %a1025 %not1 = xor i32 %or1, -11026 %and1 = and i32 %not1, %c1027 %or2 = or i32 %c, %a1028 %not2 = xor i32 %or2, -11029 %and2 = and i32 %not2, %b1030 %or3 = or i32 %and1, %and21031 ret i32 %or31032}1033 1034define i32 @or_not_and_commute4(i32 %a, i32 %b, i32 %c0) {1035; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute41036; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {1037; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]1038; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1039; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11040; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1041; CHECK-NEXT: ret i32 [[OR3]]1042;1043 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization1044 %or1 = or i32 %a, %b1045 %not1 = xor i32 %or1, -11046 %and1 = and i32 %c, %not11047 %or2 = or i32 %a, %c1048 %not2 = xor i32 %or2, -11049 %and2 = and i32 %not2, %b1050 %or3 = or i32 %and1, %and21051 ret i32 %or31052}1053 1054define i32 @or_not_and_commute5(i32 %a0, i32 %b, i32 %c0) {1055; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute51056; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {1057; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]1058; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]1059; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1060; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11061; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1062; CHECK-NEXT: ret i32 [[OR3]]1063;1064 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization1065 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization1066 %or1 = or i32 %a, %b1067 %not1 = xor i32 %or1, -11068 %and1 = and i32 %c, %not11069 %or2 = or i32 %a, %c1070 %not2 = xor i32 %or2, -11071 %and2 = and i32 %not2, %b1072 %or3 = or i32 %and1, %and21073 ret i32 %or31074}1075 1076define i32 @or_not_and_commute6(i32 %a, i32 %b, i32 %c) {1077; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute61078; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1079; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1080; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11081; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1082; CHECK-NEXT: ret i32 [[OR3]]1083;1084 %or1 = or i32 %a, %b1085 %not1 = xor i32 %or1, -11086 %and1 = and i32 %not1, %c1087 %or2 = or i32 %c, %a1088 %not2 = xor i32 %or2, -11089 %and2 = and i32 %not2, %b1090 %or3 = or i32 %and1, %and21091 ret i32 %or31092}1093 1094define i32 @or_not_and_commute7(i32 %a, i32 %b, i32 %c) {1095; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute71096; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1097; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1098; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11099; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1100; CHECK-NEXT: ret i32 [[OR3]]1101;1102 %or1 = or i32 %b, %a1103 %not1 = xor i32 %or1, -11104 %and1 = and i32 %not1, %c1105 %or2 = or i32 %a, %c1106 %not2 = xor i32 %or2, -11107 %and2 = and i32 %not2, %b1108 %or3 = or i32 %and1, %and21109 ret i32 %or31110}1111 1112define i32 @or_not_and_commute8(i32 %a0, i32 %b0, i32 %c) {1113; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute81114; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {1115; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]1116; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1117; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1118; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11119; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1120; CHECK-NEXT: ret i32 [[OR3]]1121;1122 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization1123 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1124 %or1 = or i32 %a, %b1125 %not1 = xor i32 %or1, -11126 %and1 = and i32 %not1, %c1127 %or2 = or i32 %c, %a1128 %not2 = xor i32 %or2, -11129 %and2 = and i32 %b, %not21130 %or3 = or i32 %and1, %and21131 ret i32 %or31132}1133 1134define i32 @or_not_and_commute9(i32 %a0, i32 %b0, i32 %c0) {1135; CHECK-LABEL: define {{[^@]+}}@or_not_and_commute91136; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) {1137; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]1138; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1139; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]1140; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1141; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11142; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1143; CHECK-NEXT: ret i32 [[OR3]]1144;1145 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization1146 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1147 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization1148 %or1 = or i32 %a, %b1149 %not1 = xor i32 %or1, -11150 %and1 = and i32 %not1, %c1151 %or2 = or i32 %a, %c1152 %not2 = xor i32 %or2, -11153 %and2 = and i32 %b, %not21154 %or3 = or i32 %and1, %and21155 ret i32 %or31156}1157 1158define i32 @or_not_and_extra_not_use1(i32 %a, i32 %b, i32 %c) {1159; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use11160; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1161; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1162; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11163; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1164; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11165; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1166; CHECK-NEXT: call void @use(i32 [[NOT1]])1167; CHECK-NEXT: ret i32 [[OR3]]1168;1169 %or1 = or i32 %a, %b1170 %not1 = xor i32 %or1, -11171 %and1 = and i32 %not1, %c1172 %or2 = or i32 %a, %c1173 %not2 = xor i32 %or2, -11174 %and2 = and i32 %not2, %b1175 %or3 = or i32 %and1, %and21176 call void @use(i32 %not1)1177 ret i32 %or31178}1179 1180define i32 @or_not_and_extra_not_use2(i32 %a, i32 %b, i32 %c) {1181; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_not_use21182; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1183; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1184; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11185; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]]1186; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1187; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11188; CHECK-NEXT: [[AND2:%.*]] = and i32 [[B]], [[NOT2]]1189; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]1190; CHECK-NEXT: call void @use(i32 [[NOT2]])1191; CHECK-NEXT: ret i32 [[OR3]]1192;1193 %or1 = or i32 %a, %b1194 %not1 = xor i32 %or1, -11195 %and1 = and i32 %not1, %c1196 %or2 = or i32 %a, %c1197 %not2 = xor i32 %or2, -11198 %and2 = and i32 %not2, %b1199 %or3 = or i32 %and1, %and21200 call void @use(i32 %not2)1201 ret i32 %or31202}1203 1204define i32 @or_not_and_extra_and_use1(i32 %a, i32 %b, i32 %c) {1205; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use11206; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1207; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1208; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11209; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]]1210; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1211; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11212; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1213; CHECK-NEXT: call void @use(i32 [[AND1]])1214; CHECK-NEXT: ret i32 [[OR3]]1215;1216 %or1 = or i32 %a, %b1217 %not1 = xor i32 %or1, -11218 %and1 = and i32 %not1, %c1219 %or2 = or i32 %a, %c1220 %not2 = xor i32 %or2, -11221 %and2 = and i32 %not2, %b1222 %or3 = or i32 %and1, %and21223 call void @use(i32 %and1)1224 ret i32 %or31225}1226 1227define i32 @or_not_and_extra_and_use2(i32 %a, i32 %b, i32 %c) {1228; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_and_use21229; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1230; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1231; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11232; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]]1233; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1234; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11235; CHECK-NEXT: [[AND2:%.*]] = and i32 [[B]], [[NOT2]]1236; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]1237; CHECK-NEXT: call void @use(i32 [[AND2]])1238; CHECK-NEXT: ret i32 [[OR3]]1239;1240 %or1 = or i32 %a, %b1241 %not1 = xor i32 %or1, -11242 %and1 = and i32 %not1, %c1243 %or2 = or i32 %a, %c1244 %not2 = xor i32 %or2, -11245 %and2 = and i32 %not2, %b1246 %or3 = or i32 %and1, %and21247 call void @use(i32 %and2)1248 ret i32 %or31249}1250 1251define i32 @or_not_and_extra_or_use1(i32 %a, i32 %b, i32 %c) {1252; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use11253; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1254; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1255; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1256; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11257; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1258; CHECK-NEXT: call void @use(i32 [[OR1]])1259; CHECK-NEXT: ret i32 [[OR3]]1260;1261 %or1 = or i32 %a, %b1262 %not1 = xor i32 %or1, -11263 %and1 = and i32 %not1, %c1264 %or2 = or i32 %a, %c1265 %not2 = xor i32 %or2, -11266 %and2 = and i32 %not2, %b1267 %or3 = or i32 %and1, %and21268 call void @use(i32 %or1)1269 ret i32 %or31270}1271 1272define i32 @or_not_and_extra_or_use2(i32 %a, i32 %b, i32 %c) {1273; CHECK-LABEL: define {{[^@]+}}@or_not_and_extra_or_use21274; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1275; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1276; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1277; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[A]], -11278; CHECK-NEXT: [[OR3:%.*]] = and i32 [[TMP1]], [[TMP2]]1279; CHECK-NEXT: call void @use(i32 [[OR2]])1280; CHECK-NEXT: ret i32 [[OR3]]1281;1282 %or1 = or i32 %a, %b1283 %not1 = xor i32 %or1, -11284 %and1 = and i32 %not1, %c1285 %or2 = or i32 %a, %c1286 %not2 = xor i32 %or2, -11287 %and2 = and i32 %not2, %b1288 %or3 = or i32 %and1, %and21289 call void @use(i32 %or2)1290 ret i32 %or31291}1292 1293define i32 @or_not_and_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {1294; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_c1295; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {1296; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1297; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11298; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]]1299; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[D]]1300; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11301; CHECK-NEXT: [[AND2:%.*]] = and i32 [[B]], [[NOT2]]1302; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]1303; CHECK-NEXT: ret i32 [[OR3]]1304;1305 %or1 = or i32 %a, %b1306 %not1 = xor i32 %or1, -11307 %and1 = and i32 %not1, %c1308 %or2 = or i32 %a, %d1309 %not2 = xor i32 %or2, -11310 %and2 = and i32 %not2, %b1311 %or3 = or i32 %and1, %and21312 ret i32 %or31313}1314 1315define i32 @or_not_and_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {1316; CHECK-LABEL: define {{[^@]+}}@or_not_and_wrong_b1317; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {1318; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[B]]1319; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11320; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[NOT1]]1321; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1322; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11323; CHECK-NEXT: [[AND2:%.*]] = and i32 [[D]], [[NOT2]]1324; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[AND2]]1325; CHECK-NEXT: ret i32 [[OR3]]1326;1327 %or1 = or i32 %a, %b1328 %not1 = xor i32 %or1, -11329 %and1 = and i32 %not1, %c1330 %or2 = or i32 %a, %c1331 %not2 = xor i32 %or2, -11332 %and2 = and i32 %not2, %d1333 %or3 = or i32 %and1, %and21334 ret i32 %or31335}1336 1337; (c | ~(a & b)) & (b | ~(a & c)) --> ~(a & (b ^ c))1338 1339define i32 @and_not_or(i32 %a, i32 %b, i32 %c) {1340; CHECK-LABEL: define {{[^@]+}}@and_not_or1341; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1342; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1343; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1344; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11345; CHECK-NEXT: ret i32 [[AND3]]1346;1347 %and1 = and i32 %a, %b1348 %not1 = xor i32 %and1, -11349 %or1 = or i32 %not1, %c1350 %and2 = and i32 %a, %c1351 %not2 = xor i32 %and2, -11352 %or2 = or i32 %not2, %b1353 %and3 = and i32 %or1, %or21354 ret i32 %and31355}1356 1357define i32 @and_not_or_commute1(i32 %a, i32 %b0, i32 %c) {1358; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute11359; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {1360; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1361; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1362; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1363; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11364; CHECK-NEXT: ret i32 [[AND3]]1365;1366 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1367 %and1 = and i32 %a, %b1368 %not1 = xor i32 %and1, -11369 %or1 = or i32 %not1, %c1370 %and2 = and i32 %a, %c1371 %not2 = xor i32 %and2, -11372 %or2 = or i32 %b, %not21373 %and3 = and i32 %or1, %or21374 ret i32 %and31375}1376 1377define i32 @and_not_or_commute2(i32 %a, i32 %b0, i32 %c) {1378; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute21379; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {1380; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1381; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]1382; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1383; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11384; CHECK-NEXT: ret i32 [[AND3]]1385;1386 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1387 %and1 = and i32 %a, %b1388 %not1 = xor i32 %and1, -11389 %or1 = or i32 %not1, %c1390 %and2 = and i32 %a, %c1391 %not2 = xor i32 %and2, -11392 %or2 = or i32 %b, %not21393 %and3 = and i32 %or2, %or11394 ret i32 %and31395}1396 1397define i32 @and_not_or_commute3(i32 %a, i32 %b, i32 %c) {1398; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute31399; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1400; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1401; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1402; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11403; CHECK-NEXT: ret i32 [[AND3]]1404;1405 %and1 = and i32 %b, %a1406 %not1 = xor i32 %and1, -11407 %or1 = or i32 %not1, %c1408 %and2 = and i32 %c, %a1409 %not2 = xor i32 %and2, -11410 %or2 = or i32 %not2, %b1411 %and3 = and i32 %or1, %or21412 ret i32 %and31413}1414 1415define i32 @and_not_or_commute4(i32 %a, i32 %b, i32 %c0) {1416; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute41417; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {1418; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]1419; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1420; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1421; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11422; CHECK-NEXT: ret i32 [[AND3]]1423;1424 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization1425 %and1 = and i32 %a, %b1426 %not1 = xor i32 %and1, -11427 %or1 = or i32 %c, %not11428 %and2 = and i32 %a, %c1429 %not2 = xor i32 %and2, -11430 %or2 = or i32 %not2, %b1431 %and3 = and i32 %or1, %or21432 ret i32 %and31433}1434 1435define i32 @and_not_or_commute5(i32 %a0, i32 %b, i32 %c0) {1436; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute51437; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {1438; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]1439; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]1440; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1441; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1442; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11443; CHECK-NEXT: ret i32 [[AND3]]1444;1445 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization1446 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization1447 %and1 = and i32 %a, %b1448 %not1 = xor i32 %and1, -11449 %or1 = or i32 %c, %not11450 %and2 = and i32 %a, %c1451 %not2 = xor i32 %and2, -11452 %or2 = or i32 %not2, %b1453 %and3 = and i32 %or1, %or21454 ret i32 %and31455}1456 1457define i32 @and_not_or_commute6(i32 %a, i32 %b, i32 %c) {1458; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute61459; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1460; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1461; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1462; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11463; CHECK-NEXT: ret i32 [[AND3]]1464;1465 %and1 = and i32 %a, %b1466 %not1 = xor i32 %and1, -11467 %or1 = or i32 %not1, %c1468 %and2 = and i32 %c, %a1469 %not2 = xor i32 %and2, -11470 %or2 = or i32 %not2, %b1471 %and3 = and i32 %or1, %or21472 ret i32 %and31473}1474 1475define i32 @and_not_or_commute7(i32 %a, i32 %b, i32 %c) {1476; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute71477; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1478; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1479; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1480; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11481; CHECK-NEXT: ret i32 [[AND3]]1482;1483 %and1 = and i32 %b, %a1484 %not1 = xor i32 %and1, -11485 %or1 = or i32 %not1, %c1486 %and2 = and i32 %a, %c1487 %not2 = xor i32 %and2, -11488 %or2 = or i32 %not2, %b1489 %and3 = and i32 %or1, %or21490 ret i32 %and31491}1492 1493define i32 @and_not_or_commute8(i32 %a0, i32 %b0, i32 %c) {1494; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute81495; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {1496; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]1497; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1498; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1499; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1500; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11501; CHECK-NEXT: ret i32 [[AND3]]1502;1503 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization1504 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1505 %and1 = and i32 %a, %b1506 %not1 = xor i32 %and1, -11507 %or1 = or i32 %not1, %c1508 %and2 = and i32 %c, %a1509 %not2 = xor i32 %and2, -11510 %or2 = or i32 %b, %not21511 %and3 = and i32 %or1, %or21512 ret i32 %and31513}1514 1515define i32 @and_not_or_commute9(i32 %a0, i32 %b0, i32 %c0) {1516; CHECK-LABEL: define {{[^@]+}}@and_not_or_commute91517; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B0:%.*]], i32 [[C0:%.*]]) {1518; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]1519; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1520; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]1521; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1522; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1523; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11524; CHECK-NEXT: ret i32 [[AND3]]1525;1526 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization1527 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1528 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization1529 %and1 = and i32 %a, %b1530 %not1 = xor i32 %and1, -11531 %or1 = or i32 %not1, %c1532 %and2 = and i32 %a, %c1533 %not2 = xor i32 %and2, -11534 %or2 = or i32 %b, %not21535 %and3 = and i32 %or1, %or21536 ret i32 %and31537}1538 1539define i32 @and_not_or_extra_not_use1(i32 %a, i32 %b, i32 %c) {1540; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use11541; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1542; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1543; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -11544; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1545; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1546; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11547; CHECK-NEXT: call void @use(i32 [[NOT1]])1548; CHECK-NEXT: ret i32 [[AND3]]1549;1550 %and1 = and i32 %a, %b1551 %not1 = xor i32 %and1, -11552 %or1 = or i32 %not1, %c1553 %and2 = and i32 %a, %c1554 %not2 = xor i32 %and2, -11555 %or2 = or i32 %not2, %b1556 %and3 = and i32 %or1, %or21557 call void @use(i32 %not1)1558 ret i32 %and31559}1560 1561define i32 @and_not_or_extra_not_use2(i32 %a, i32 %b, i32 %c) {1562; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_not_use21563; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1564; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1565; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -11566; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]]1567; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]1568; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -11569; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOT2]]1570; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]1571; CHECK-NEXT: call void @use(i32 [[NOT2]])1572; CHECK-NEXT: ret i32 [[AND3]]1573;1574 %and1 = and i32 %a, %b1575 %not1 = xor i32 %and1, -11576 %or1 = or i32 %not1, %c1577 %and2 = and i32 %a, %c1578 %not2 = xor i32 %and2, -11579 %or2 = or i32 %not2, %b1580 %and3 = and i32 %or1, %or21581 call void @use(i32 %not2)1582 ret i32 %and31583}1584 1585define i32 @and_not_or_extra_and_use1(i32 %a, i32 %b, i32 %c) {1586; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use11587; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1588; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1589; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -11590; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]]1591; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1592; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1593; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11594; CHECK-NEXT: call void @use(i32 [[OR1]])1595; CHECK-NEXT: ret i32 [[AND3]]1596;1597 %and1 = and i32 %a, %b1598 %not1 = xor i32 %and1, -11599 %or1 = or i32 %not1, %c1600 %and2 = and i32 %a, %c1601 %not2 = xor i32 %and2, -11602 %or2 = or i32 %not2, %b1603 %and3 = and i32 %or1, %or21604 call void @use(i32 %or1)1605 ret i32 %and31606}1607 1608define i32 @and_not_or_extra_and_use2(i32 %a, i32 %b, i32 %c) {1609; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_and_use21610; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1611; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1612; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -11613; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]]1614; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]1615; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -11616; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOT2]]1617; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]1618; CHECK-NEXT: call void @use(i32 [[OR2]])1619; CHECK-NEXT: ret i32 [[AND3]]1620;1621 %and1 = and i32 %a, %b1622 %not1 = xor i32 %and1, -11623 %or1 = or i32 %not1, %c1624 %and2 = and i32 %a, %c1625 %not2 = xor i32 %and2, -11626 %or2 = or i32 %not2, %b1627 %and3 = and i32 %or1, %or21628 call void @use(i32 %or2)1629 ret i32 %and31630}1631 1632define i32 @and_not_or_extra_or_use1(i32 %a, i32 %b, i32 %c) {1633; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use11634; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1635; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1636; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1637; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1638; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11639; CHECK-NEXT: call void @use(i32 [[AND1]])1640; CHECK-NEXT: ret i32 [[AND3]]1641;1642 %and1 = and i32 %a, %b1643 %not1 = xor i32 %and1, -11644 %or1 = or i32 %not1, %c1645 %and2 = and i32 %a, %c1646 %not2 = xor i32 %and2, -11647 %or2 = or i32 %not2, %b1648 %and3 = and i32 %or1, %or21649 call void @use(i32 %and1)1650 ret i32 %and31651}1652 1653define i32 @and_not_or_extra_or_use2(i32 %a, i32 %b, i32 %c) {1654; CHECK-LABEL: define {{[^@]+}}@and_not_or_extra_or_use21655; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1656; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]1657; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]1658; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]1659; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -11660; CHECK-NEXT: call void @use(i32 [[AND2]])1661; CHECK-NEXT: ret i32 [[AND3]]1662;1663 %and1 = and i32 %a, %b1664 %not1 = xor i32 %and1, -11665 %or1 = or i32 %not1, %c1666 %and2 = and i32 %a, %c1667 %not2 = xor i32 %and2, -11668 %or2 = or i32 %not2, %b1669 %and3 = and i32 %or1, %or21670 call void @use(i32 %and2)1671 ret i32 %and31672}1673 1674define i32 @and_not_or_wrong_c(i32 %a, i32 %b, i32 %c, i32 %d) {1675; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_c1676; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {1677; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1678; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -11679; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]]1680; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[D]]1681; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -11682; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOT2]]1683; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]1684; CHECK-NEXT: ret i32 [[AND3]]1685;1686 %and1 = and i32 %a, %b1687 %not1 = xor i32 %and1, -11688 %or1 = or i32 %not1, %c1689 %and2 = and i32 %a, %d1690 %not2 = xor i32 %and2, -11691 %or2 = or i32 %not2, %b1692 %and3 = and i32 %or1, %or21693 ret i32 %and31694}1695 1696define i32 @and_not_or_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {1697; CHECK-LABEL: define {{[^@]+}}@and_not_or_wrong_b1698; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {1699; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[B]]1700; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -11701; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[NOT1]]1702; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]1703; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -11704; CHECK-NEXT: [[OR2:%.*]] = or i32 [[D]], [[NOT2]]1705; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR1]], [[OR2]]1706; CHECK-NEXT: ret i32 [[AND3]]1707;1708 %and1 = and i32 %a, %b1709 %not1 = xor i32 %and1, -11710 %or1 = or i32 %not1, %c1711 %and2 = and i32 %a, %c1712 %not2 = xor i32 %and2, -11713 %or2 = or i32 %not2, %d1714 %and3 = and i32 %or1, %or21715 ret i32 %and31716}1717 1718; (b & ~(a | c)) | ~(a | b) --> ~((b & c) | a)1719 1720define i32 @or_and_not_not(i32 %a, i32 %b, i32 %c) {1721; CHECK-LABEL: define {{[^@]+}}@or_and_not_not1722; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1723; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1724; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1725; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11726; CHECK-NEXT: ret i32 [[OR3]]1727;1728 %or1 = or i32 %b, %a1729 %not1 = xor i32 %or1, -11730 %or2 = or i32 %a, %c1731 %not2 = xor i32 %or2, -11732 %and = and i32 %not2, %b1733 %or3 = or i32 %and, %not11734 ret i32 %or31735}1736 1737define i32 @or_and_not_not_commute1(i32 %a, i32 %b0, i32 %c) {1738; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute11739; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {1740; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1741; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1742; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1743; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11744; CHECK-NEXT: ret i32 [[OR3]]1745;1746 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1747 %or1 = or i32 %b, %a1748 %not1 = xor i32 %or1, -11749 %or2 = or i32 %a, %c1750 %not2 = xor i32 %or2, -11751 %and = and i32 %b, %not21752 %or3 = or i32 %and, %not11753 ret i32 %or31754}1755 1756define i32 @or_and_not_not_commute2(i32 %a, i32 %b, i32 %c) {1757; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute21758; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1759; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1760; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1761; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11762; CHECK-NEXT: ret i32 [[OR3]]1763;1764 %or1 = or i32 %b, %a1765 %not1 = xor i32 %or1, -11766 %or2 = or i32 %a, %c1767 %not2 = xor i32 %or2, -11768 %and = and i32 %not2, %b1769 %or3 = or i32 %and, %not11770 ret i32 %or31771}1772 1773define i32 @or_and_not_not_commute3(i32 %a, i32 %b, i32 %c) {1774; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute31775; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1776; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1777; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1778; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11779; CHECK-NEXT: ret i32 [[OR3]]1780;1781 %or1 = or i32 %b, %a1782 %not1 = xor i32 %or1, -11783 %or2 = or i32 %c, %a1784 %not2 = xor i32 %or2, -11785 %and = and i32 %not2, %b1786 %or3 = or i32 %and, %not11787 ret i32 %or31788}1789 1790define i32 @or_and_not_not_commute4(i32 %a, i32 %b, i32 %c) {1791; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute41792; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1793; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1794; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1795; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11796; CHECK-NEXT: ret i32 [[OR3]]1797;1798 %or1 = or i32 %a, %b1799 %not1 = xor i32 %or1, -11800 %or2 = or i32 %a, %c1801 %not2 = xor i32 %or2, -11802 %and = and i32 %not2, %b1803 %or3 = or i32 %and, %not11804 ret i32 %or31805}1806 1807define i32 @or_and_not_not_commute5(i32 %a, i32 %b, i32 %c) {1808; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute51809; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1810; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1811; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1812; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11813; CHECK-NEXT: ret i32 [[OR3]]1814;1815 %or1 = or i32 %b, %a1816 %not1 = xor i32 %or1, -11817 %or2 = or i32 %a, %c1818 %not2 = xor i32 %or2, -11819 %and = and i32 %not2, %b1820 %or3 = or i32 %not1, %and1821 ret i32 %or31822}1823 1824define i32 @or_and_not_not_commute6(i32 %a, i32 %b0, i32 %c) {1825; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute61826; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {1827; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]1828; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1829; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1830; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11831; CHECK-NEXT: ret i32 [[OR3]]1832;1833 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization1834 %or1 = or i32 %b, %a1835 %not1 = xor i32 %or1, -11836 %or2 = or i32 %c, %a1837 %not2 = xor i32 %or2, -11838 %and = and i32 %b, %not21839 %or3 = or i32 %and, %not11840 ret i32 %or31841}1842 1843define i32 @or_and_not_not_commute7(i32 %a, i32 %b, i32 %c) {1844; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_commute71845; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1846; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1847; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1848; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11849; CHECK-NEXT: ret i32 [[OR3]]1850;1851 %or1 = or i32 %a, %b1852 %not1 = xor i32 %or1, -11853 %or2 = or i32 %c, %a1854 %not2 = xor i32 %or2, -11855 %and = and i32 %not2, %b1856 %or3 = or i32 %and, %not11857 ret i32 %or31858}1859 1860define i32 @or_and_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {1861; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use11862; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1863; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]1864; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11865; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1866; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11867; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]]1868; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]1869; CHECK-NEXT: call void @use(i32 [[NOT1]])1870; CHECK-NEXT: ret i32 [[OR3]]1871;1872 %or1 = or i32 %b, %a1873 %not1 = xor i32 %or1, -11874 %or2 = or i32 %a, %c1875 %not2 = xor i32 %or2, -11876 %and = and i32 %not2, %b1877 %or3 = or i32 %and, %not11878 call void @use(i32 %not1)1879 ret i32 %or31880}1881 1882define i32 @or_and_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {1883; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_not_use21884; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1885; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1886; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11887; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1888; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1889; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11890; CHECK-NEXT: call void @use(i32 [[NOT2]])1891; CHECK-NEXT: ret i32 [[OR3]]1892;1893 %or1 = or i32 %b, %a1894 %not1 = xor i32 %or1, -11895 %or2 = or i32 %a, %c1896 %not2 = xor i32 %or2, -11897 %and = and i32 %not2, %b1898 %or3 = or i32 %and, %not11899 call void @use(i32 %not2)1900 ret i32 %or31901}1902 1903define i32 @or_and_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {1904; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_and_use1905; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1906; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1907; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11908; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]]1909; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1910; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1911; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11912; CHECK-NEXT: call void @use(i32 [[AND]])1913; CHECK-NEXT: ret i32 [[OR3]]1914;1915 %or1 = or i32 %b, %a1916 %not1 = xor i32 %or1, -11917 %or2 = or i32 %a, %c1918 %not2 = xor i32 %or2, -11919 %and = and i32 %not2, %b1920 %or3 = or i32 %and, %not11921 call void @use(i32 %and)1922 ret i32 %or31923}1924 1925define i32 @or_and_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {1926; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use11927; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1928; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]1929; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11930; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1931; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11932; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]]1933; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]1934; CHECK-NEXT: call void @use(i32 [[OR1]])1935; CHECK-NEXT: ret i32 [[OR3]]1936;1937 %or1 = or i32 %b, %a1938 %not1 = xor i32 %or1, -11939 %or2 = or i32 %a, %c1940 %not2 = xor i32 %or2, -11941 %and = and i32 %not2, %b1942 %or3 = or i32 %and, %not11943 call void @use(i32 %or1)1944 ret i32 %or31945}1946 1947define i32 @or_and_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {1948; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_extra_or_use21949; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1950; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1951; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[B]]1952; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]1953; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -11954; CHECK-NEXT: call void @use(i32 [[OR2]])1955; CHECK-NEXT: ret i32 [[OR3]]1956;1957 %or1 = or i32 %b, %a1958 %not1 = xor i32 %or1, -11959 %or2 = or i32 %a, %c1960 %not2 = xor i32 %or2, -11961 %and = and i32 %not2, %b1962 %or3 = or i32 %and, %not11963 call void @use(i32 %or2)1964 ret i32 %or31965}1966 1967; Check the use limit. It can be adjusted in the future in terms of1968; LHS and RHS uses distribution to be more flexible.1969define i32 @or_and_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {1970; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_2_extra_uses1971; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {1972; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]1973; CHECK-NEXT: call void @use(i32 [[OR1]])1974; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11975; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1976; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -11977; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]]1978; CHECK-NEXT: call void @use(i32 [[AND]])1979; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]1980; CHECK-NEXT: ret i32 [[OR3]]1981;1982 %or1 = or i32 %b, %a1983 call void @use(i32 %or1)1984 %not1 = xor i32 %or1, -11985 %or2 = or i32 %a, %c1986 %not2 = xor i32 %or2, -11987 %and = and i32 %not2, %b1988 call void @use(i32 %and)1989 %or3 = or i32 %not1, %and1990 ret i32 %or31991}1992 1993define i32 @or_and_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {1994; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_a1995; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {1996; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[D]]1997; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -11998; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]1999; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -12000; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]]2001; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]2002; CHECK-NEXT: ret i32 [[OR3]]2003;2004 %or1 = or i32 %b, %d2005 %not1 = xor i32 %or1, -12006 %or2 = or i32 %a, %c2007 %not2 = xor i32 %or2, -12008 %and = and i32 %not2, %b2009 %or3 = or i32 %and, %not12010 ret i32 %or32011}2012 2013define i32 @or_and_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {2014; CHECK-LABEL: define {{[^@]+}}@or_and_not_not_wrong_b2015; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {2016; CHECK-NEXT: [[OR1:%.*]] = or i32 [[D]], [[A]]2017; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -12018; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[C]]2019; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -12020; CHECK-NEXT: [[AND:%.*]] = and i32 [[B]], [[NOT2]]2021; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND]], [[NOT1]]2022; CHECK-NEXT: ret i32 [[OR3]]2023;2024 %or1 = or i32 %d, %a2025 %not1 = xor i32 %or1, -12026 %or2 = or i32 %a, %c2027 %not2 = xor i32 %or2, -12028 %and = and i32 %not2, %b2029 %or3 = or i32 %and, %not12030 ret i32 %or32031}2032 2033; (b | ~(a & c)) & ~(a & b) --> ~((b | c) & a)2034 2035define i32 @and_or_not_not(i32 %a, i32 %b, i32 %c) {2036; CHECK-LABEL: define {{[^@]+}}@and_or_not_not2037; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2038; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2039; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2040; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12041; CHECK-NEXT: ret i32 [[AND3]]2042;2043 %and1 = and i32 %b, %a2044 %not1 = xor i32 %and1, -12045 %and2 = and i32 %a, %c2046 %not2 = xor i32 %and2, -12047 %or = or i32 %not2, %b2048 %and3 = and i32 %or, %not12049 ret i32 %and32050}2051 2052define i32 @and_or_not_not_commute1(i32 %a, i32 %b0, i32 %c) {2053; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute12054; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {2055; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]2056; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2057; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2058; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12059; CHECK-NEXT: ret i32 [[AND3]]2060;2061 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization2062 %and1 = and i32 %b, %a2063 %not1 = xor i32 %and1, -12064 %and2 = and i32 %a, %c2065 %not2 = xor i32 %and2, -12066 %or = or i32 %b, %not22067 %and3 = and i32 %or, %not12068 ret i32 %and32069}2070 2071define i32 @and_or_not_not_commute2(i32 %a, i32 %b, i32 %c) {2072; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute22073; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2074; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2075; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2076; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12077; CHECK-NEXT: ret i32 [[AND3]]2078;2079 %and1 = and i32 %b, %a2080 %not1 = xor i32 %and1, -12081 %and2 = and i32 %a, %c2082 %not2 = xor i32 %and2, -12083 %or = or i32 %not2, %b2084 %and3 = and i32 %or, %not12085 ret i32 %and32086}2087 2088define i32 @and_or_not_not_commute3(i32 %a, i32 %b, i32 %c) {2089; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute32090; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2091; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2092; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2093; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12094; CHECK-NEXT: ret i32 [[AND3]]2095;2096 %and1 = and i32 %b, %a2097 %not1 = xor i32 %and1, -12098 %and2 = and i32 %c, %a2099 %not2 = xor i32 %and2, -12100 %or = or i32 %not2, %b2101 %and3 = and i32 %or, %not12102 ret i32 %and32103}2104 2105define i32 @and_or_not_not_commute4(i32 %a, i32 %b, i32 %c) {2106; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute42107; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2108; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2109; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2110; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12111; CHECK-NEXT: ret i32 [[AND3]]2112;2113 %and1 = and i32 %a, %b2114 %not1 = xor i32 %and1, -12115 %and2 = and i32 %a, %c2116 %not2 = xor i32 %and2, -12117 %or = or i32 %not2, %b2118 %and3 = and i32 %or, %not12119 ret i32 %and32120}2121 2122define i32 @and_or_not_not_commute5(i32 %a, i32 %b, i32 %c) {2123; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute52124; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2125; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2126; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2127; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12128; CHECK-NEXT: ret i32 [[AND3]]2129;2130 %and1 = and i32 %b, %a2131 %not1 = xor i32 %and1, -12132 %and2 = and i32 %a, %c2133 %not2 = xor i32 %and2, -12134 %or = or i32 %not2, %b2135 %and3 = and i32 %not1, %or2136 ret i32 %and32137}2138 2139define i32 @and_or_not_not_commute6(i32 %a, i32 %b0, i32 %c) {2140; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute62141; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {2142; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]2143; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2144; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2145; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12146; CHECK-NEXT: ret i32 [[AND3]]2147;2148 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization2149 %and1 = and i32 %b, %a2150 %not1 = xor i32 %and1, -12151 %and2 = and i32 %c, %a2152 %not2 = xor i32 %and2, -12153 %or = or i32 %b, %not22154 %and3 = and i32 %or, %not12155 ret i32 %and32156}2157 2158define i32 @and_or_not_not_commute7(i32 %a, i32 %b, i32 %c) {2159; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_commute72160; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2161; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2162; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2163; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12164; CHECK-NEXT: ret i32 [[AND3]]2165;2166 %and1 = and i32 %a, %b2167 %not1 = xor i32 %and1, -12168 %and2 = and i32 %c, %a2169 %not2 = xor i32 %and2, -12170 %or = or i32 %not2, %b2171 %and3 = and i32 %or, %not12172 ret i32 %and32173}2174 2175define i32 @and_or_not_not_extra_not_use1(i32 %a, i32 %b, i32 %c) {2176; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use12177; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2178; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]2179; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12180; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2181; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12182; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]]2183; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]2184; CHECK-NEXT: call void @use(i32 [[NOT1]])2185; CHECK-NEXT: ret i32 [[AND3]]2186;2187 %and1 = and i32 %b, %a2188 %not1 = xor i32 %and1, -12189 %and2 = and i32 %a, %c2190 %not2 = xor i32 %and2, -12191 %or = or i32 %not2, %b2192 %and3 = and i32 %or, %not12193 call void @use(i32 %not1)2194 ret i32 %and32195}2196 2197define i32 @and_or_not_not_extra_not_use2(i32 %a, i32 %b, i32 %c) {2198; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_not_use22199; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2200; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2201; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12202; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2203; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2204; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12205; CHECK-NEXT: call void @use(i32 [[NOT2]])2206; CHECK-NEXT: ret i32 [[AND3]]2207;2208 %and1 = and i32 %b, %a2209 %not1 = xor i32 %and1, -12210 %and2 = and i32 %a, %c2211 %not2 = xor i32 %and2, -12212 %or = or i32 %not2, %b2213 %and3 = and i32 %or, %not12214 call void @use(i32 %not2)2215 ret i32 %and32216}2217 2218define i32 @and_or_not_not_extra_and_use(i32 %a, i32 %b, i32 %c) {2219; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_and_use2220; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2221; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2222; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12223; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]]2224; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2225; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2226; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12227; CHECK-NEXT: call void @use(i32 [[OR]])2228; CHECK-NEXT: ret i32 [[AND3]]2229;2230 %and1 = and i32 %b, %a2231 %not1 = xor i32 %and1, -12232 %and2 = and i32 %a, %c2233 %not2 = xor i32 %and2, -12234 %or = or i32 %not2, %b2235 %and3 = and i32 %or, %not12236 call void @use(i32 %or)2237 ret i32 %and32238}2239 2240define i32 @and_or_not_not_extra_or_use1(i32 %a, i32 %b, i32 %c) {2241; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use12242; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2243; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]2244; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2245; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12246; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]]2247; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]2248; CHECK-NEXT: call void @use(i32 [[AND1]])2249; CHECK-NEXT: ret i32 [[AND3]]2250;2251 %and1 = and i32 %b, %a2252 %not1 = xor i32 %and1, -12253 %and2 = and i32 %a, %c2254 %not2 = xor i32 %and2, -12255 %or = or i32 %not2, %b2256 %and3 = and i32 %or, %not12257 call void @use(i32 %and1)2258 ret i32 %and32259}2260 2261define i32 @and_or_not_not_extra_or_use2(i32 %a, i32 %b, i32 %c) {2262; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_extra_or_use22263; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2264; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2265; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[B]]2266; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[A]]2267; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[TMP2]], -12268; CHECK-NEXT: call void @use(i32 [[AND2]])2269; CHECK-NEXT: ret i32 [[AND3]]2270;2271 %and1 = and i32 %b, %a2272 %not1 = xor i32 %and1, -12273 %and2 = and i32 %a, %c2274 %not2 = xor i32 %and2, -12275 %or = or i32 %not2, %b2276 %and3 = and i32 %or, %not12277 call void @use(i32 %and2)2278 ret i32 %and32279}2280 2281define i32 @and_or_not_not_2_extra_uses(i32 %a, i32 %b, i32 %c) {2282; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_2_extra_uses2283; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2284; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]2285; CHECK-NEXT: call void @use(i32 [[AND1]])2286; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2287; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12288; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]]2289; CHECK-NEXT: call void @use(i32 [[OR]])2290; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]2291; CHECK-NEXT: ret i32 [[AND3]]2292;2293 %and1 = and i32 %b, %a2294 call void @use(i32 %and1)2295 %not1 = xor i32 %and1, -12296 %and2 = and i32 %a, %c2297 %not2 = xor i32 %and2, -12298 %or = or i32 %not2, %b2299 call void @use(i32 %or)2300 %and3 = and i32 %not1, %or2301 ret i32 %and32302}2303 2304define i32 @and_or_not_not_wrong_a(i32 %a, i32 %b, i32 %c, i32 %d) {2305; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_a2306; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {2307; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[D]]2308; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2309; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12310; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]]2311; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND1]], [[OR]]2312; CHECK-NEXT: ret i32 [[AND3]]2313;2314 %and1 = and i32 %b, %d2315 %not1 = xor i32 %and1, -12316 %and2 = and i32 %a, %c2317 %not2 = xor i32 %and2, -12318 %or = or i32 %not2, %b2319 %and3 = and i32 %or, %not12320 ret i32 %and32321}2322 2323define i32 @and_or_not_not_wrong_b(i32 %a, i32 %b, i32 %c, i32 %d) {2324; CHECK-LABEL: define {{[^@]+}}@and_or_not_not_wrong_b2325; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {2326; CHECK-NEXT: [[AND1:%.*]] = and i32 [[D]], [[A]]2327; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12328; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[C]]2329; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12330; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOT2]]2331; CHECK-NEXT: [[AND3:%.*]] = and i32 [[OR]], [[NOT1]]2332; CHECK-NEXT: ret i32 [[AND3]]2333;2334 %and1 = and i32 %d, %a2335 %not1 = xor i32 %and1, -12336 %and2 = and i32 %a, %c2337 %not2 = xor i32 %and2, -12338 %or = or i32 %not2, %b2339 %and3 = and i32 %or, %not12340 ret i32 %and32341}2342 2343; (a & ~(b | c)) | ~(a | (b ^ c)) --> (~a & b & c) | ~(b | c)2344 2345define i32 @and_not_or_or_not_or_xor(i32 %a, i32 %b, i32 %c) {2346; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor2347; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2348; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2349; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2350; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2351; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2352; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12353; CHECK-NEXT: ret i32 [[OR3]]2354;2355 %or1 = or i32 %b, %c2356 %not1 = xor i32 %or1, -12357 %and1 = and i32 %not1, %a2358 %xor1 = xor i32 %b, %c2359 %or2 = or i32 %xor1, %a2360 %not2 = xor i32 %or2, -12361 %or3 = or i32 %and1, %not22362 ret i32 %or32363}2364 2365define i32 @and_not_or_or_not_or_xor_commute1(i32 %a, i32 %b, i32 %c) {2366; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute12367; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2368; CHECK-NEXT: [[OR1:%.*]] = or i32 [[C]], [[B]]2369; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2370; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2371; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2372; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12373; CHECK-NEXT: ret i32 [[OR3]]2374;2375 %or1 = or i32 %c, %b2376 %not1 = xor i32 %or1, -12377 %and1 = and i32 %not1, %a2378 %xor1 = xor i32 %b, %c2379 %or2 = or i32 %xor1, %a2380 %not2 = xor i32 %or2, -12381 %or3 = or i32 %and1, %not22382 ret i32 %or32383}2384 2385define i32 @and_not_or_or_not_or_xor_commute2(i32 %a0, i32 %b, i32 %c) {2386; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute22387; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2388; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]2389; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2390; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2391; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2392; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2393; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12394; CHECK-NEXT: ret i32 [[OR3]]2395;2396 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization2397 %or1 = or i32 %b, %c2398 %not1 = xor i32 %or1, -12399 %and1 = and i32 %a, %not12400 %xor1 = xor i32 %b, %c2401 %or2 = or i32 %xor1, %a2402 %not2 = xor i32 %or2, -12403 %or3 = or i32 %and1, %not22404 ret i32 %or32405}2406 2407define i32 @and_not_or_or_not_or_xor_commute3(i32 %a, i32 %b, i32 %c) {2408; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute32409; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2410; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2411; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[C]], [[B]]2412; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2413; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2414; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12415; CHECK-NEXT: ret i32 [[OR3]]2416;2417 %or1 = or i32 %b, %c2418 %not1 = xor i32 %or1, -12419 %and1 = and i32 %not1, %a2420 %xor1 = xor i32 %c, %b2421 %or2 = or i32 %xor1, %a2422 %not2 = xor i32 %or2, -12423 %or3 = or i32 %and1, %not22424 ret i32 %or32425}2426 2427define i32 @and_not_or_or_not_or_xor_commute4(i32 %a0, i32 %b, i32 %c) {2428; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute42429; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2430; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]2431; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2432; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2433; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[XOR1]]2434; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2435; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12436; CHECK-NEXT: ret i32 [[OR3]]2437;2438 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization2439 %or1 = or i32 %b, %c2440 %not1 = xor i32 %or1, -12441 %and1 = and i32 %a, %not12442 %xor1 = xor i32 %b, %c2443 %or2 = or i32 %a, %xor12444 %not2 = xor i32 %or2, -12445 %or3 = or i32 %and1, %not22446 ret i32 %or32447}2448 2449define i32 @and_not_or_or_not_or_xor_commute5(i32 %a, i32 %b, i32 %c) {2450; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_commute52451; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2452; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2453; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2454; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2455; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2456; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12457; CHECK-NEXT: ret i32 [[OR3]]2458;2459 %or1 = or i32 %b, %c2460 %not1 = xor i32 %or1, -12461 %and1 = and i32 %not1, %a2462 %xor1 = xor i32 %b, %c2463 %or2 = or i32 %xor1, %a2464 %not2 = xor i32 %or2, -12465 %or3 = or i32 %not2, %and12466 ret i32 %or32467}2468 2469define i32 @and_not_or_or_not_or_xor_use1(i32 %a, i32 %b, i32 %c) {2470; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use12471; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2472; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2473; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2474; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2475; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2476; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12477; CHECK-NEXT: call void @use(i32 [[OR1]])2478; CHECK-NEXT: ret i32 [[OR3]]2479;2480 %or1 = or i32 %b, %c2481 %not1 = xor i32 %or1, -12482 %and1 = and i32 %not1, %a2483 %xor1 = xor i32 %b, %c2484 %or2 = or i32 %xor1, %a2485 %not2 = xor i32 %or2, -12486 %or3 = or i32 %and1, %not22487 call void @use(i32 %or1)2488 ret i32 %or32489}2490 2491define i32 @and_not_or_or_not_or_xor_use2(i32 %a, i32 %b, i32 %c) {2492; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use22493; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2494; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2495; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -12496; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2497; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2498; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2499; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12500; CHECK-NEXT: call void @use(i32 [[NOT1]])2501; CHECK-NEXT: ret i32 [[OR3]]2502;2503 %or1 = or i32 %b, %c2504 %not1 = xor i32 %or1, -12505 %and1 = and i32 %not1, %a2506 %xor1 = xor i32 %b, %c2507 %or2 = or i32 %xor1, %a2508 %not2 = xor i32 %or2, -12509 %or3 = or i32 %and1, %not22510 call void @use(i32 %not1)2511 ret i32 %or32512}2513 2514define i32 @and_not_or_or_not_or_xor_use3(i32 %a, i32 %b, i32 %c) {2515; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use32516; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2517; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2518; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -12519; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]]2520; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2521; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2522; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -12523; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]2524; CHECK-NEXT: call void @use(i32 [[AND1]])2525; CHECK-NEXT: ret i32 [[OR3]]2526;2527 %or1 = or i32 %b, %c2528 %not1 = xor i32 %or1, -12529 %and1 = and i32 %not1, %a2530 %xor1 = xor i32 %b, %c2531 %or2 = or i32 %xor1, %a2532 %not2 = xor i32 %or2, -12533 %or3 = or i32 %and1, %not22534 call void @use(i32 %and1)2535 ret i32 %or32536}2537 2538define i32 @and_not_or_or_not_or_xor_use4(i32 %a, i32 %b, i32 %c) {2539; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use42540; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2541; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2542; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2543; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2544; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2545; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12546; CHECK-NEXT: call void @use(i32 [[XOR1]])2547; CHECK-NEXT: ret i32 [[OR3]]2548;2549 %or1 = or i32 %b, %c2550 %not1 = xor i32 %or1, -12551 %and1 = and i32 %not1, %a2552 %xor1 = xor i32 %b, %c2553 %or2 = or i32 %xor1, %a2554 %not2 = xor i32 %or2, -12555 %or3 = or i32 %and1, %not22556 call void @use(i32 %xor1)2557 ret i32 %or32558}2559 2560define i32 @and_not_or_or_not_or_xor_use5(i32 %a, i32 %b, i32 %c) {2561; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use52562; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2563; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2564; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2565; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2566; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[OR1]], [[OR2]]2567; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP1]], -12568; CHECK-NEXT: call void @use(i32 [[OR2]])2569; CHECK-NEXT: ret i32 [[OR3]]2570;2571 %or1 = or i32 %b, %c2572 %not1 = xor i32 %or1, -12573 %and1 = and i32 %not1, %a2574 %xor1 = xor i32 %b, %c2575 %or2 = or i32 %xor1, %a2576 %not2 = xor i32 %or2, -12577 %or3 = or i32 %and1, %not22578 call void @use(i32 %or2)2579 ret i32 %or32580}2581 2582define i32 @and_not_or_or_not_or_xor_use6(i32 %a, i32 %b, i32 %c) {2583; CHECK-LABEL: define {{[^@]+}}@and_not_or_or_not_or_xor_use62584; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2585; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[C]]2586; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -12587; CHECK-NEXT: [[AND1:%.*]] = and i32 [[A]], [[NOT1]]2588; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2589; CHECK-NEXT: [[OR2:%.*]] = or i32 [[XOR1]], [[A]]2590; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[OR2]], -12591; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND1]], [[NOT2]]2592; CHECK-NEXT: call void @use(i32 [[NOT2]])2593; CHECK-NEXT: ret i32 [[OR3]]2594;2595 %or1 = or i32 %b, %c2596 %not1 = xor i32 %or1, -12597 %and1 = and i32 %not1, %a2598 %xor1 = xor i32 %b, %c2599 %or2 = or i32 %xor1, %a2600 %not2 = xor i32 %or2, -12601 %or3 = or i32 %and1, %not22602 call void @use(i32 %not2)2603 ret i32 %or32604}2605 2606; (a | ~(b & c)) & ~(a & (b ^ c)) --> ~(a | b) | (a ^ b ^ c)2607; This pattern is not handled because the result is more undefined than a source.2608; It is invalid as is, but feezing %a and %b will make it valid.2609 2610define i32 @or_not_and_and_not_and_xor(i32 %a, i32 %b, i32 %c) {2611; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor2612; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2613; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2614; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12615; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2616; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2617; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2618; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2619; CHECK-NEXT: ret i32 [[AND3]]2620;2621 %and1 = and i32 %b, %c2622 %not1 = xor i32 %and1, -12623 %or1 = or i32 %not1, %a2624 %xor1 = xor i32 %b, %c2625 %and2 = and i32 %xor1, %a2626 %not2 = xor i32 %and2, -12627 %and3 = and i32 %or1, %not22628 ret i32 %and32629}2630 2631define i32 @or_not_and_and_not_and_xor_commute1(i32 %a, i32 %b, i32 %c) {2632; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute12633; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2634; CHECK-NEXT: [[AND1:%.*]] = and i32 [[C]], [[B]]2635; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12636; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2637; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2638; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2639; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2640; CHECK-NEXT: ret i32 [[AND3]]2641;2642 %and1 = and i32 %c, %b2643 %not1 = xor i32 %and1, -12644 %or1 = or i32 %not1, %a2645 %xor1 = xor i32 %b, %c2646 %and2 = and i32 %xor1, %a2647 %not2 = xor i32 %and2, -12648 %and3 = and i32 %or1, %not22649 ret i32 %and32650}2651 2652define i32 @or_not_and_and_not_and_xor_commute2(i32 %a0, i32 %b, i32 %c) {2653; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute22654; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2655; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]2656; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2657; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12658; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2659; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2660; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2661; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2662; CHECK-NEXT: ret i32 [[AND3]]2663;2664 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization2665 %and1 = and i32 %b, %c2666 %not1 = xor i32 %and1, -12667 %or1 = or i32 %a, %not12668 %xor1 = xor i32 %b, %c2669 %and2 = and i32 %xor1, %a2670 %not2 = xor i32 %and2, -12671 %and3 = and i32 %or1, %not22672 ret i32 %and32673}2674 2675define i32 @or_not_and_and_not_and_xor_commute3(i32 %a, i32 %b, i32 %c) {2676; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute32677; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2678; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2679; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12680; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2681; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[C]], [[B]]2682; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2683; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2684; CHECK-NEXT: ret i32 [[AND3]]2685;2686 %and1 = and i32 %b, %c2687 %not1 = xor i32 %and1, -12688 %or1 = or i32 %not1, %a2689 %xor1 = xor i32 %c, %b2690 %and2 = and i32 %xor1, %a2691 %not2 = xor i32 %and2, -12692 %and3 = and i32 %or1, %not22693 ret i32 %and32694}2695 2696define i32 @or_not_and_and_not_and_xor_commute4(i32 %a0, i32 %b, i32 %c) {2697; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute42698; CHECK-SAME: (i32 [[A0:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2699; CHECK-NEXT: [[A:%.*]] = sdiv i32 42, [[A0]]2700; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2701; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12702; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2703; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2704; CHECK-NEXT: [[AND2:%.*]] = and i32 [[A]], [[XOR1]]2705; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2706; CHECK-NEXT: ret i32 [[AND3]]2707;2708 %a = sdiv i32 42, %a0 ; thwart complexity-based canonicalization2709 %and1 = and i32 %b, %c2710 %not1 = xor i32 %and1, -12711 %or1 = or i32 %a, %not12712 %xor1 = xor i32 %b, %c2713 %and2 = and i32 %a, %xor12714 %not2 = xor i32 %and2, -12715 %and3 = and i32 %or1, %not22716 ret i32 %and32717}2718 2719define i32 @or_not_and_and_not_and_xor_commute5(i32 %a, i32 %b, i32 %c) {2720; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_commute52721; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2722; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2723; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12724; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2725; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2726; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2727; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2728; CHECK-NEXT: ret i32 [[AND3]]2729;2730 %and1 = and i32 %b, %c2731 %not1 = xor i32 %and1, -12732 %or1 = or i32 %not1, %a2733 %xor1 = xor i32 %b, %c2734 %and2 = and i32 %xor1, %a2735 %not2 = xor i32 %and2, -12736 %and3 = and i32 %not2, %or12737 ret i32 %and32738}2739 2740define i32 @or_not_and_and_not_and_xor_use1(i32 %a, i32 %b, i32 %c) {2741; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use12742; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2743; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2744; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12745; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2746; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2747; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2748; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2749; CHECK-NEXT: call void @use(i32 [[AND1]])2750; CHECK-NEXT: ret i32 [[AND3]]2751;2752 %and1 = and i32 %b, %c2753 %not1 = xor i32 %and1, -12754 %or1 = or i32 %not1, %a2755 %xor1 = xor i32 %b, %c2756 %and2 = and i32 %xor1, %a2757 %not2 = xor i32 %and2, -12758 %and3 = and i32 %or1, %not22759 call void @use(i32 %and1)2760 ret i32 %and32761}2762 2763define i32 @or_not_and_and_not_and_xor_use2(i32 %a, i32 %b, i32 %c) {2764; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use22765; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2766; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2767; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12768; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2769; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2770; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2771; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2772; CHECK-NEXT: call void @use(i32 [[NOT1]])2773; CHECK-NEXT: ret i32 [[AND3]]2774;2775 %and1 = and i32 %b, %c2776 %not1 = xor i32 %and1, -12777 %or1 = or i32 %not1, %a2778 %xor1 = xor i32 %b, %c2779 %and2 = and i32 %xor1, %a2780 %not2 = xor i32 %and2, -12781 %and3 = and i32 %or1, %not22782 call void @use(i32 %not1)2783 ret i32 %and32784}2785 2786define i32 @or_not_and_and_not_and_xor_use3(i32 %a, i32 %b, i32 %c) {2787; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use32788; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2789; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2790; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12791; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2792; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2793; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2794; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2795; CHECK-NEXT: call void @use(i32 [[OR1]])2796; CHECK-NEXT: ret i32 [[AND3]]2797;2798 %and1 = and i32 %b, %c2799 %not1 = xor i32 %and1, -12800 %or1 = or i32 %not1, %a2801 %xor1 = xor i32 %b, %c2802 %and2 = and i32 %xor1, %a2803 %not2 = xor i32 %and2, -12804 %and3 = and i32 %or1, %not22805 call void @use(i32 %or1)2806 ret i32 %and32807}2808 2809define i32 @or_not_and_and_not_and_xor_use4(i32 %a, i32 %b, i32 %c) {2810; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use42811; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2812; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2813; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12814; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2815; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2816; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2817; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2818; CHECK-NEXT: call void @use(i32 [[XOR1]])2819; CHECK-NEXT: ret i32 [[AND3]]2820;2821 %and1 = and i32 %b, %c2822 %not1 = xor i32 %and1, -12823 %or1 = or i32 %not1, %a2824 %xor1 = xor i32 %b, %c2825 %and2 = and i32 %xor1, %a2826 %not2 = xor i32 %and2, -12827 %and3 = and i32 %or1, %not22828 call void @use(i32 %xor1)2829 ret i32 %and32830}2831 2832define i32 @or_not_and_and_not_and_xor_use5(i32 %a, i32 %b, i32 %c) {2833; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use52834; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2835; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2836; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12837; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2838; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2839; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2840; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2841; CHECK-NEXT: call void @use(i32 [[AND2]])2842; CHECK-NEXT: ret i32 [[AND3]]2843;2844 %and1 = and i32 %b, %c2845 %not1 = xor i32 %and1, -12846 %or1 = or i32 %not1, %a2847 %xor1 = xor i32 %b, %c2848 %and2 = and i32 %xor1, %a2849 %not2 = xor i32 %and2, -12850 %and3 = and i32 %or1, %not22851 call void @use(i32 %and2)2852 ret i32 %and32853}2854 2855define i32 @or_not_and_and_not_and_xor_use6(i32 %a, i32 %b, i32 %c) {2856; CHECK-LABEL: define {{[^@]+}}@or_not_and_and_not_and_xor_use62857; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2858; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[C]]2859; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -12860; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOT1]]2861; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B]], [[C]]2862; CHECK-NEXT: [[AND2:%.*]] = and i32 [[XOR1]], [[A]]2863; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[AND2]], -12864; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR1]]2865; CHECK-NEXT: call void @use(i32 [[NOT2]])2866; CHECK-NEXT: ret i32 [[AND3]]2867;2868 %and1 = and i32 %b, %c2869 %not1 = xor i32 %and1, -12870 %or1 = or i32 %not1, %a2871 %xor1 = xor i32 %b, %c2872 %and2 = and i32 %xor1, %a2873 %not2 = xor i32 %and2, -12874 %and3 = and i32 %or1, %not22875 call void @use(i32 %not2)2876 ret i32 %and32877}2878 2879; (~a & b & c) | ~(a | b | c) -> ~(a | (b ^ c))2880 2881define i32 @not_and_and_or_not_or_or(i32 %a, i32 %b, i32 %c) {2882; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or2883; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2884; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]2885; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2886; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12887; CHECK-NEXT: ret i32 [[OR3]]2888;2889 %or1 = or i32 %b, %a2890 %or2 = or i32 %or1, %c2891 %not1 = xor i32 %or2, -12892 %not2 = xor i32 %a, -12893 %and1 = and i32 %not2, %b2894 %and2 = and i32 %and1, %c2895 %or3 = or i32 %and2, %not12896 ret i32 %or32897}2898 2899define i32 @not_and_and_or_not_or_or_commute1_or(i32 %a, i32 %b, i32 %c) {2900; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_or2901; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2902; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]2903; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2904; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12905; CHECK-NEXT: ret i32 [[OR3]]2906;2907 %or1 = or i32 %c, %a2908 %or2 = or i32 %or1, %b2909 %not1 = xor i32 %or2, -12910 %not2 = xor i32 %a, -12911 %and1 = and i32 %not2, %b2912 %and2 = and i32 %and1, %c2913 %or3 = or i32 %and2, %not12914 ret i32 %or32915}2916 2917define i32 @not_and_and_or_not_or_or_commute2_or(i32 %a, i32 %b, i32 %c) {2918; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_or2919; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2920; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]2921; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2922; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12923; CHECK-NEXT: ret i32 [[OR3]]2924;2925 %or1 = or i32 %b, %c2926 %or2 = or i32 %or1, %a2927 %not1 = xor i32 %or2, -12928 %not2 = xor i32 %a, -12929 %and1 = and i32 %not2, %b2930 %and2 = and i32 %and1, %c2931 %or3 = or i32 %and2, %not12932 ret i32 %or32933}2934 2935define i32 @not_and_and_or_not_or_or_commute1_and(i32 %a, i32 %b, i32 %c) {2936; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute1_and2937; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2938; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]2939; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2940; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12941; CHECK-NEXT: ret i32 [[OR3]]2942;2943 %or1 = or i32 %b, %a2944 %or2 = or i32 %or1, %c2945 %not1 = xor i32 %or2, -12946 %not2 = xor i32 %a, -12947 %and1 = and i32 %not2, %c2948 %and2 = and i32 %and1, %b2949 %or3 = or i32 %and2, %not12950 ret i32 %or32951}2952 2953define i32 @not_and_and_or_not_or_or_commute2_and(i32 %a, i32 %b, i32 %c) {2954; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute2_and2955; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2956; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]2957; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2958; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12959; CHECK-NEXT: ret i32 [[OR3]]2960;2961 %or1 = or i32 %b, %a2962 %or2 = or i32 %or1, %c2963 %not1 = xor i32 %or2, -12964 %not2 = xor i32 %a, -12965 %and1 = and i32 %b, %c2966 %and2 = and i32 %and1, %not22967 %or3 = or i32 %and2, %not12968 ret i32 %or32969}2970 2971define i32 @not_and_and_or_not_or_or_commute1(i32 %a, i32 %b, i32 %c) {2972; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute12973; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {2974; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]2975; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2976; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12977; CHECK-NEXT: ret i32 [[OR3]]2978;2979 %or1 = or i32 %a, %b2980 %or2 = or i32 %or1, %c2981 %not1 = xor i32 %or2, -12982 %not2 = xor i32 %a, -12983 %and1 = and i32 %not2, %b2984 %and2 = and i32 %and1, %c2985 %or3 = or i32 %and2, %not12986 ret i32 %or32987}2988 2989define i32 @not_and_and_or_not_or_or_commute2(i32 %a, i32 %b, i32 %c0) {2990; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute22991; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {2992; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]2993; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]2994; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]2995; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -12996; CHECK-NEXT: ret i32 [[OR3]]2997;2998 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization2999 %or1 = or i32 %b, %a3000 %or2 = or i32 %c, %or13001 %not1 = xor i32 %or2, -13002 %not2 = xor i32 %a, -13003 %and1 = and i32 %not2, %b3004 %and2 = and i32 %and1, %c3005 %or3 = or i32 %and2, %not13006 ret i32 %or33007}3008 3009define i32 @not_and_and_or_not_or_or_commute3(i32 %a, i32 %b0, i32 %c) {3010; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute33011; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {3012; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]3013; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3014; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]3015; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -13016; CHECK-NEXT: ret i32 [[OR3]]3017;3018 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization3019 %or1 = or i32 %b, %a3020 %or2 = or i32 %or1, %c3021 %not1 = xor i32 %or2, -13022 %not2 = xor i32 %a, -13023 %and1 = and i32 %b, %not23024 %and2 = and i32 %and1, %c3025 %or3 = or i32 %and2, %not13026 ret i32 %or33027}3028 3029define i32 @not_and_and_or_not_or_or_commute4(i32 %a, i32 %b, i32 %c0) {3030; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_commute43031; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {3032; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]3033; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3034; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]3035; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -13036; CHECK-NEXT: ret i32 [[OR3]]3037;3038 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization3039 %or1 = or i32 %b, %a3040 %or2 = or i32 %or1, %c3041 %not1 = xor i32 %or2, -13042 %not2 = xor i32 %a, -13043 %and1 = and i32 %not2, %b3044 %and2 = and i32 %c, %and13045 %or3 = or i32 %and2, %not13046 ret i32 %or33047}3048 3049define i32 @not_and_and_or_not_or_or_use1(i32 %a, i32 %b, i32 %c) {3050; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use13051; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3052; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3053; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3054; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]3055; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -13056; CHECK-NEXT: call void @use(i32 [[OR1]])3057; CHECK-NEXT: ret i32 [[OR3]]3058;3059 %or1 = or i32 %b, %a3060 %or2 = or i32 %or1, %c3061 %not1 = xor i32 %or2, -13062 %not2 = xor i32 %a, -13063 %and1 = and i32 %not2, %b3064 %and2 = and i32 %and1, %c3065 %or3 = or i32 %and2, %not13066 call void @use(i32 %or1)3067 ret i32 %or33068}3069 3070define i32 @not_and_and_or_not_or_or_use2(i32 %a, i32 %b, i32 %c) {3071; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use23072; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3073; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3074; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]3075; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3076; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]3077; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -13078; CHECK-NEXT: call void @use(i32 [[OR2]])3079; CHECK-NEXT: ret i32 [[OR3]]3080;3081 %or1 = or i32 %b, %a3082 %or2 = or i32 %or1, %c3083 %not1 = xor i32 %or2, -13084 %not2 = xor i32 %a, -13085 %and1 = and i32 %not2, %b3086 %and2 = and i32 %and1, %c3087 %or3 = or i32 %and2, %not13088 call void @use(i32 %or2)3089 ret i32 %or33090}3091 3092define i32 @not_and_and_or_not_or_or_use3(i32 %a, i32 %b, i32 %c) {3093; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use33094; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3095; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3096; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]3097; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -13098; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13099; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]]3100; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]3101; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]3102; CHECK-NEXT: call void @use(i32 [[NOT1]])3103; CHECK-NEXT: ret i32 [[OR3]]3104;3105 %or1 = or i32 %b, %a3106 %or2 = or i32 %or1, %c3107 %not1 = xor i32 %or2, -13108 %not2 = xor i32 %a, -13109 %and1 = and i32 %not2, %b3110 %and2 = and i32 %and1, %c3111 %or3 = or i32 %and2, %not13112 call void @use(i32 %not1)3113 ret i32 %or33114}3115 3116define i32 @not_and_and_or_not_or_or_use4(i32 %a, i32 %b, i32 %c) {3117; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use43118; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3119; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13120; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3121; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]3122; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -13123; CHECK-NEXT: call void @use(i32 [[NOT2]])3124; CHECK-NEXT: ret i32 [[OR3]]3125;3126 %or1 = or i32 %b, %a3127 %or2 = or i32 %or1, %c3128 %not1 = xor i32 %or2, -13129 %not2 = xor i32 %a, -13130 %and1 = and i32 %not2, %b3131 %and2 = and i32 %and1, %c3132 %or3 = or i32 %and2, %not13133 call void @use(i32 %not2)3134 ret i32 %or33135}3136 3137define i32 @not_and_and_or_not_or_or_use5(i32 %a, i32 %b, i32 %c) {3138; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use53139; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3140; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13141; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]]3142; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3143; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[A]]3144; CHECK-NEXT: [[OR3:%.*]] = xor i32 [[TMP2]], -13145; CHECK-NEXT: call void @use(i32 [[AND1]])3146; CHECK-NEXT: ret i32 [[OR3]]3147;3148 %or1 = or i32 %b, %a3149 %or2 = or i32 %or1, %c3150 %not1 = xor i32 %or2, -13151 %not2 = xor i32 %a, -13152 %and1 = and i32 %not2, %b3153 %and2 = and i32 %and1, %c3154 %or3 = or i32 %and2, %not13155 call void @use(i32 %and1)3156 ret i32 %or33157}3158 3159define i32 @not_and_and_or_not_or_or_use6(i32 %a, i32 %b, i32 %c) {3160; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_not_or_or_use63161; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3162; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3163; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]3164; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR2]], -13165; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13166; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]]3167; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]3168; CHECK-NEXT: [[OR3:%.*]] = or i32 [[AND2]], [[NOT1]]3169; CHECK-NEXT: call void @use(i32 [[AND2]])3170; CHECK-NEXT: ret i32 [[OR3]]3171;3172 %or1 = or i32 %b, %a3173 %or2 = or i32 %or1, %c3174 %not1 = xor i32 %or2, -13175 %not2 = xor i32 %a, -13176 %and1 = and i32 %not2, %b3177 %and2 = and i32 %and1, %c3178 %or3 = or i32 %and2, %not13179 call void @use(i32 %and2)3180 ret i32 %or33181}3182 3183; (~a | b | c) & ~(a & b & c) -> ~a | (b ^ c)3184 3185define i32 @not_or_or_and_not_and_and(i32 %a, i32 %b, i32 %c) {3186; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and3187; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3188; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13189; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3190; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3191; CHECK-NEXT: ret i32 [[AND3]]3192;3193 %and1 = and i32 %b, %a3194 %and2 = and i32 %and1, %c3195 %not1 = xor i32 %and2, -13196 %not2 = xor i32 %a, -13197 %or1 = or i32 %not2, %b3198 %or2 = or i32 %or1, %c3199 %and3 = and i32 %or2, %not13200 ret i32 %and33201}3202 3203define i32 @not_or_or_and_not_and_and_commute1_and(i32 %a, i32 %b, i32 %c) {3204; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_and3205; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3206; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13207; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3208; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3209; CHECK-NEXT: ret i32 [[AND3]]3210;3211 %and1 = and i32 %c, %a3212 %and2 = and i32 %and1, %b3213 %not1 = xor i32 %and2, -13214 %not2 = xor i32 %a, -13215 %or1 = or i32 %not2, %b3216 %or2 = or i32 %or1, %c3217 %and3 = and i32 %or2, %not13218 ret i32 %and33219}3220 3221define i32 @not_or_or_and_not_and_and_commute2_and(i32 %a, i32 %b, i32 %c) {3222; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_and3223; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3224; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13225; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3226; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3227; CHECK-NEXT: ret i32 [[AND3]]3228;3229 %and1 = and i32 %b, %c3230 %and2 = and i32 %and1, %a3231 %not1 = xor i32 %and2, -13232 %not2 = xor i32 %a, -13233 %or1 = or i32 %not2, %b3234 %or2 = or i32 %or1, %c3235 %and3 = and i32 %or2, %not13236 ret i32 %and33237}3238 3239define i32 @not_or_or_and_not_and_and_commute1_or(i32 %a, i32 %b, i32 %c) {3240; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute1_or3241; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3242; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13243; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]3244; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3245; CHECK-NEXT: ret i32 [[AND3]]3246;3247 %and1 = and i32 %b, %a3248 %and2 = and i32 %and1, %c3249 %not1 = xor i32 %and2, -13250 %not2 = xor i32 %a, -13251 %or1 = or i32 %not2, %c3252 %or2 = or i32 %or1, %b3253 %and3 = and i32 %or2, %not13254 ret i32 %and33255}3256 3257define i32 @not_or_or_and_not_and_and_commute2_or(i32 %a, i32 %b, i32 %c) {3258; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute2_or3259; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3260; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13261; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[C]]3262; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3263; CHECK-NEXT: ret i32 [[AND3]]3264;3265 %and1 = and i32 %b, %a3266 %and2 = and i32 %and1, %c3267 %not1 = xor i32 %and2, -13268 %not2 = xor i32 %a, -13269 %or1 = or i32 %b, %c3270 %or2 = or i32 %or1, %not23271 %and3 = and i32 %or2, %not13272 ret i32 %and33273}3274 3275define i32 @not_or_or_and_not_and_and_commute1(i32 %a, i32 %b, i32 %c) {3276; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute13277; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3278; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13279; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3280; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3281; CHECK-NEXT: ret i32 [[AND3]]3282;3283 %and1 = and i32 %a, %b3284 %and2 = and i32 %and1, %c3285 %not1 = xor i32 %and2, -13286 %not2 = xor i32 %a, -13287 %or1 = or i32 %not2, %b3288 %or2 = or i32 %or1, %c3289 %and3 = and i32 %or2, %not13290 ret i32 %and33291}3292 3293define i32 @not_or_or_and_not_and_and_commute2(i32 %a, i32 %b, i32 %c0) {3294; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute23295; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {3296; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]3297; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13298; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3299; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3300; CHECK-NEXT: ret i32 [[AND3]]3301;3302 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization3303 %and1 = and i32 %b, %a3304 %and2 = and i32 %c, %and13305 %not1 = xor i32 %and2, -13306 %not2 = xor i32 %a, -13307 %or1 = or i32 %not2, %b3308 %or2 = or i32 %or1, %c3309 %and3 = and i32 %or2, %not13310 ret i32 %and33311}3312 3313define i32 @not_or_or_and_not_and_and_commute3(i32 %a, i32 %b0, i32 %c) {3314; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute33315; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {3316; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]3317; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13318; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3319; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3320; CHECK-NEXT: ret i32 [[AND3]]3321;3322 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization3323 %and1 = and i32 %b, %a3324 %and2 = and i32 %and1, %c3325 %not1 = xor i32 %and2, -13326 %not2 = xor i32 %a, -13327 %or1 = or i32 %b, %not23328 %or2 = or i32 %or1, %c3329 %and3 = and i32 %or2, %not13330 ret i32 %and33331}3332 3333define i32 @not_or_or_and_not_and_and_commute4(i32 %a, i32 %b, i32 %c0) {3334; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_commute43335; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {3336; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]3337; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13338; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3339; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3340; CHECK-NEXT: ret i32 [[AND3]]3341;3342 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization3343 %and1 = and i32 %b, %a3344 %and2 = and i32 %and1, %c3345 %not1 = xor i32 %and2, -13346 %not2 = xor i32 %a, -13347 %or1 = or i32 %not2, %b3348 %or2 = or i32 %c, %or13349 %and3 = and i32 %or2, %not13350 ret i32 %and33351}3352 3353define i32 @not_or_or_and_not_and_and_use1(i32 %a, i32 %b, i32 %c) {3354; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use13355; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3356; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]3357; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13358; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3359; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3360; CHECK-NEXT: call void @use(i32 [[AND1]])3361; CHECK-NEXT: ret i32 [[AND3]]3362;3363 %and1 = and i32 %b, %a3364 %and2 = and i32 %and1, %c3365 %not1 = xor i32 %and2, -13366 %not2 = xor i32 %a, -13367 %or1 = or i32 %not2, %b3368 %or2 = or i32 %or1, %c3369 %and3 = and i32 %or2, %not13370 call void @use(i32 %and1)3371 ret i32 %and33372}3373 3374define i32 @not_or_or_and_not_and_and_use2(i32 %a, i32 %b, i32 %c) {3375; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use23376; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3377; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]3378; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]3379; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13380; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3381; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3382; CHECK-NEXT: call void @use(i32 [[AND2]])3383; CHECK-NEXT: ret i32 [[AND3]]3384;3385 %and1 = and i32 %b, %a3386 %and2 = and i32 %and1, %c3387 %not1 = xor i32 %and2, -13388 %not2 = xor i32 %a, -13389 %or1 = or i32 %not2, %b3390 %or2 = or i32 %or1, %c3391 %and3 = and i32 %or2, %not13392 call void @use(i32 %and2)3393 ret i32 %and33394}3395 3396define i32 @not_or_or_and_not_and_and_use3(i32 %a, i32 %b, i32 %c) {3397; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use33398; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3399; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]3400; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]3401; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND2]], -13402; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13403; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]]3404; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]3405; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]3406; CHECK-NEXT: call void @use(i32 [[NOT1]])3407; CHECK-NEXT: ret i32 [[AND3]]3408;3409 %and1 = and i32 %b, %a3410 %and2 = and i32 %and1, %c3411 %not1 = xor i32 %and2, -13412 %not2 = xor i32 %a, -13413 %or1 = or i32 %not2, %b3414 %or2 = or i32 %or1, %c3415 %and3 = and i32 %or2, %not13416 call void @use(i32 %not1)3417 ret i32 %and33418}3419 3420define i32 @not_or_or_and_not_and_and_use4(i32 %a, i32 %b, i32 %c) {3421; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use43422; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3423; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13424; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3425; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3426; CHECK-NEXT: call void @use(i32 [[NOT2]])3427; CHECK-NEXT: ret i32 [[AND3]]3428;3429 %and1 = and i32 %b, %a3430 %and2 = and i32 %and1, %c3431 %not1 = xor i32 %and2, -13432 %not2 = xor i32 %a, -13433 %or1 = or i32 %not2, %b3434 %or2 = or i32 %or1, %c3435 %and3 = and i32 %or2, %not13436 call void @use(i32 %not2)3437 ret i32 %and33438}3439 3440define i32 @not_or_or_and_not_and_and_use5(i32 %a, i32 %b, i32 %c) {3441; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use53442; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3443; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13444; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]]3445; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[C]], [[B]]3446; CHECK-NEXT: [[AND3:%.*]] = or i32 [[TMP1]], [[NOT2]]3447; CHECK-NEXT: call void @use(i32 [[OR1]])3448; CHECK-NEXT: ret i32 [[AND3]]3449;3450 %and1 = and i32 %b, %a3451 %and2 = and i32 %and1, %c3452 %not1 = xor i32 %and2, -13453 %not2 = xor i32 %a, -13454 %or1 = or i32 %not2, %b3455 %or2 = or i32 %or1, %c3456 %and3 = and i32 %or2, %not13457 call void @use(i32 %or1)3458 ret i32 %and33459}3460 3461define i32 @not_or_or_and_not_and_and_use6(i32 %a, i32 %b, i32 %c) {3462; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_not_and_and_use63463; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3464; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]3465; CHECK-NEXT: [[AND2:%.*]] = and i32 [[AND1]], [[C]]3466; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13467; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]]3468; CHECK-NEXT: [[OR2:%.*]] = or i32 [[OR1]], [[C]]3469; CHECK-NEXT: [[AND3:%.*]] = xor i32 [[AND2]], [[OR2]]3470; CHECK-NEXT: call void @use(i32 [[OR2]])3471; CHECK-NEXT: ret i32 [[AND3]]3472;3473 %and1 = and i32 %b, %a3474 %and2 = and i32 %and1, %c3475 %not1 = xor i32 %and2, -13476 %not2 = xor i32 %a, -13477 %or1 = or i32 %not2, %b3478 %or2 = or i32 %or1, %c3479 %and3 = and i32 %or2, %not13480 call void @use(i32 %or2)3481 ret i32 %and33482}3483 3484; (~a & b & c) | ~(a | b) -> (c | ~b) & ~a3485 3486define i32 @not_and_and_or_no_or(i32 %a, i32 %b, i32 %c) {3487; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or3488; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3489; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13490; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13491; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3492; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3493; CHECK-NEXT: ret i32 [[OR2]]3494;3495 %or1 = or i32 %b, %a3496 %not1 = xor i32 %or1, -13497 %not2 = xor i32 %a, -13498 %and1 = and i32 %not2, %b3499 %and2 = and i32 %and1, %c3500 %or2 = or i32 %and2, %not13501 ret i32 %or23502}3503 3504define i32 @not_and_and_or_no_or_commute1_and(i32 %a, i32 %b, i32 %c) {3505; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute1_and3506; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3507; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13508; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13509; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3510; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3511; CHECK-NEXT: ret i32 [[OR2]]3512;3513 %or1 = or i32 %b, %a3514 %not1 = xor i32 %or1, -13515 %not2 = xor i32 %a, -13516 %and1 = and i32 %c, %b3517 %and2 = and i32 %and1, %not23518 %or2 = or i32 %and2, %not13519 ret i32 %or23520}3521 3522define i32 @not_and_and_or_no_or_commute2_and(i32 %a, i32 %b, i32 %c) {3523; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute2_and3524; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3525; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13526; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13527; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3528; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3529; CHECK-NEXT: ret i32 [[OR2]]3530;3531 %or1 = or i32 %b, %a3532 %not1 = xor i32 %or1, -13533 %not2 = xor i32 %a, -13534 %and1 = and i32 %not2, %c3535 %and2 = and i32 %and1, %b3536 %or2 = or i32 %and2, %not13537 ret i32 %or23538}3539 3540define i32 @not_and_and_or_no_or_commute1(i32 %a, i32 %b, i32 %c) {3541; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute13542; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3543; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13544; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13545; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3546; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3547; CHECK-NEXT: ret i32 [[OR2]]3548;3549 %or1 = or i32 %a, %b3550 %not1 = xor i32 %or1, -13551 %not2 = xor i32 %a, -13552 %and1 = and i32 %not2, %b3553 %and2 = and i32 %and1, %c3554 %or2 = or i32 %and2, %not13555 ret i32 %or23556}3557 3558define i32 @not_and_and_or_no_or_commute2(i32 %a, i32 %b0, i32 %c) {3559; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute23560; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {3561; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]3562; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13563; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13564; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3565; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3566; CHECK-NEXT: ret i32 [[OR2]]3567;3568 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization3569 %or1 = or i32 %b, %a3570 %not1 = xor i32 %or1, -13571 %not2 = xor i32 %a, -13572 %and1 = and i32 %b, %not23573 %and2 = and i32 %and1, %c3574 %or2 = or i32 %and2, %not13575 ret i32 %or23576}3577 3578define i32 @not_and_and_or_no_or_commute3(i32 %a, i32 %b, i32 %c0) {3579; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_commute33580; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {3581; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]3582; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13583; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13584; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3585; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3586; CHECK-NEXT: ret i32 [[OR2]]3587;3588 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization3589 %or1 = or i32 %b, %a3590 %not1 = xor i32 %or1, -13591 %not2 = xor i32 %a, -13592 %and1 = and i32 %not2, %b3593 %and2 = and i32 %c, %and13594 %or2 = or i32 %and2, %not13595 ret i32 %or23596}3597 3598define i32 @not_and_and_or_no_or_use1(i32 %a, i32 %b, i32 %c) {3599; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use13600; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3601; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13602; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13603; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3604; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3605; CHECK-NEXT: call void @use(i32 [[NOT2]])3606; CHECK-NEXT: ret i32 [[OR2]]3607;3608 %or1 = or i32 %b, %a3609 %not1 = xor i32 %or1, -13610 %not2 = xor i32 %a, -13611 %and1 = and i32 %not2, %b3612 %and2 = and i32 %and1, %c3613 %or2 = or i32 %and2, %not13614 call void @use(i32 %not2)3615 ret i32 %or23616}3617 3618define i32 @not_and_and_or_no_or_use2(i32 %a, i32 %b, i32 %c) {3619; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use23620; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3621; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13622; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13623; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3624; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3625; CHECK-NEXT: call void @use(i32 [[NOT2]])3626; CHECK-NEXT: ret i32 [[OR2]]3627;3628 %or1 = or i32 %b, %a3629 %not1 = xor i32 %or1, -13630 %not2 = xor i32 %a, -13631 %and1 = and i32 %b, %c3632 %and2 = and i32 %and1, %not23633 %or2 = or i32 %and2, %not13634 call void @use(i32 %not2)3635 ret i32 %or23636}3637 3638define i32 @not_and_and_or_no_or_use3(i32 %a, i32 %b, i32 %c) {3639; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use33640; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3641; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13642; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13643; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3644; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3645; CHECK-NEXT: call void @use(i32 [[NOT2]])3646; CHECK-NEXT: ret i32 [[OR2]]3647;3648 %or1 = or i32 %b, %a3649 %not1 = xor i32 %or1, -13650 %not2 = xor i32 %a, -13651 %and1 = and i32 %not2, %c3652 %and2 = and i32 %and1, %b3653 %or2 = or i32 %and2, %not13654 call void @use(i32 %not2)3655 ret i32 %or23656}3657 3658define i32 @not_and_and_or_no_or_use4(i32 %a, i32 %b, i32 %c) {3659; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use43660; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3661; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13662; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13663; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3664; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3665; CHECK-NEXT: call void @use(i32 [[NOT2]])3666; CHECK-NEXT: ret i32 [[OR2]]3667;3668 %or1 = or i32 %b, %a3669 %not1 = xor i32 %or1, -13670 %not2 = xor i32 %a, -13671 %and1 = and i32 %not2, %c3672 %and2 = and i32 %and1, %b3673 %or2 = or i32 %and2, %not13674 call void @use(i32 %not2)3675 ret i32 %or23676}3677 3678define i32 @not_and_and_or_no_or_use5(i32 %a, i32 %b, i32 %c) {3679; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use53680; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3681; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3682; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -13683; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13684; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]3685; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP1]], [[B]]3686; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]3687; CHECK-NEXT: call void @use(i32 [[OR1]])3688; CHECK-NEXT: ret i32 [[OR2]]3689;3690 %or1 = or i32 %b, %a3691 %not1 = xor i32 %or1, -13692 %not2 = xor i32 %a, -13693 %and1 = and i32 %not2, %b3694 %and2 = and i32 %and1, %c3695 %or2 = or i32 %and2, %not13696 call void @use(i32 %or1)3697 ret i32 %or23698}3699 3700define i32 @not_and_and_or_no_or_use6(i32 %a, i32 %b, i32 %c) {3701; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use63702; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3703; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3704; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -13705; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13706; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]3707; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP1]], [[B]]3708; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]3709; CHECK-NEXT: call void @use(i32 [[NOT1]])3710; CHECK-NEXT: ret i32 [[OR2]]3711;3712 %or1 = or i32 %b, %a3713 %not1 = xor i32 %or1, -13714 %not2 = xor i32 %a, -13715 %and1 = and i32 %not2, %b3716 %and2 = and i32 %and1, %c3717 %or2 = or i32 %and2, %not13718 call void @use(i32 %not1)3719 ret i32 %or23720}3721 3722define i32 @not_and_and_or_no_or_use7(i32 %a, i32 %b, i32 %c) {3723; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use73724; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3725; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13726; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[NOT2]]3727; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13728; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C]], [[TMP1]]3729; CHECK-NEXT: [[OR2:%.*]] = and i32 [[TMP2]], [[NOT2]]3730; CHECK-NEXT: call void @use(i32 [[AND1]])3731; CHECK-NEXT: ret i32 [[OR2]]3732;3733 %or1 = or i32 %b, %a3734 %not1 = xor i32 %or1, -13735 %not2 = xor i32 %a, -13736 %and1 = and i32 %not2, %b3737 %and2 = and i32 %and1, %c3738 %or2 = or i32 %and2, %not13739 call void @use(i32 %and1)3740 ret i32 %or23741}3742 3743define i32 @not_and_and_or_no_or_use8(i32 %a, i32 %b, i32 %c) {3744; CHECK-LABEL: define {{[^@]+}}@not_and_and_or_no_or_use83745; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3746; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[A]]3747; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[OR1]], -13748; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13749; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[C]], [[NOT2]]3750; CHECK-NEXT: [[AND2:%.*]] = and i32 [[TMP1]], [[B]]3751; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND2]], [[NOT1]]3752; CHECK-NEXT: call void @use(i32 [[AND2]])3753; CHECK-NEXT: ret i32 [[OR2]]3754;3755 %or1 = or i32 %b, %a3756 %not1 = xor i32 %or1, -13757 %not2 = xor i32 %a, -13758 %and1 = and i32 %not2, %b3759 %and2 = and i32 %and1, %c3760 %or2 = or i32 %and2, %not13761 call void @use(i32 %and2)3762 ret i32 %or23763}3764 3765; (~a | b | c) & ~(a & b) -> (c & ~b) | ~a3766 3767define i32 @not_or_or_and_no_and(i32 %a, i32 %b, i32 %c) {3768; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and3769; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3770; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13771; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13772; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3773; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3774; CHECK-NEXT: ret i32 [[AND2]]3775;3776 %and1 = and i32 %b, %a3777 %not1 = xor i32 %and1, -13778 %not2 = xor i32 %a, -13779 %or1 = or i32 %not2, %b3780 %or2 = or i32 %or1, %c3781 %and2 = and i32 %or2, %not13782 ret i32 %and23783}3784 3785define i32 @not_or_or_and_no_and_commute1_or(i32 %a, i32 %b, i32 %c) {3786; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute1_or3787; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3788; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13789; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13790; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3791; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3792; CHECK-NEXT: ret i32 [[AND2]]3793;3794 %and1 = and i32 %b, %a3795 %not1 = xor i32 %and1, -13796 %not2 = xor i32 %a, -13797 %or1 = or i32 %c, %b3798 %or2 = or i32 %or1, %not23799 %and2 = and i32 %or2, %not13800 ret i32 %and23801}3802 3803define i32 @not_or_or_and_no_and_commute2_or(i32 %a, i32 %b, i32 %c) {3804; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute2_or3805; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3806; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13807; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13808; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3809; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3810; CHECK-NEXT: ret i32 [[AND2]]3811;3812 %and1 = and i32 %b, %a3813 %not1 = xor i32 %and1, -13814 %not2 = xor i32 %a, -13815 %or1 = or i32 %not2, %c3816 %or2 = or i32 %or1, %b3817 %and2 = and i32 %or2, %not13818 ret i32 %and23819}3820 3821define i32 @not_or_or_and_no_and_commute1(i32 %a, i32 %b, i32 %c) {3822; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute13823; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3824; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13825; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13826; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3827; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3828; CHECK-NEXT: ret i32 [[AND2]]3829;3830 %and1 = and i32 %a, %b3831 %not1 = xor i32 %and1, -13832 %not2 = xor i32 %a, -13833 %or1 = or i32 %not2, %b3834 %or2 = or i32 %or1, %c3835 %and2 = and i32 %or2, %not13836 ret i32 %and23837}3838 3839define i32 @not_or_or_and_no_and_commute2(i32 %a, i32 %b0, i32 %c) {3840; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute23841; CHECK-SAME: (i32 [[A:%.*]], i32 [[B0:%.*]], i32 [[C:%.*]]) {3842; CHECK-NEXT: [[B:%.*]] = sdiv i32 42, [[B0]]3843; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13844; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13845; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3846; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3847; CHECK-NEXT: ret i32 [[AND2]]3848;3849 %b = sdiv i32 42, %b0 ; thwart complexity-based canonicalization3850 %and1 = and i32 %b, %a3851 %not1 = xor i32 %and1, -13852 %not2 = xor i32 %a, -13853 %or1 = or i32 %b, %not23854 %or2 = or i32 %or1, %c3855 %and2 = and i32 %or2, %not13856 ret i32 %and23857}3858 3859define i32 @not_or_or_and_no_and_commute3(i32 %a, i32 %b, i32 %c0) {3860; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_commute33861; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C0:%.*]]) {3862; CHECK-NEXT: [[C:%.*]] = sdiv i32 42, [[C0]]3863; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13864; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13865; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3866; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3867; CHECK-NEXT: ret i32 [[AND2]]3868;3869 %c = sdiv i32 42, %c0 ; thwart complexity-based canonicalization3870 %and1 = and i32 %b, %a3871 %not1 = xor i32 %and1, -13872 %not2 = xor i32 %a, -13873 %or1 = or i32 %not2, %b3874 %or2 = or i32 %c, %or13875 %and2 = and i32 %or2, %not13876 ret i32 %and23877}3878 3879define i32 @not_or_or_and_no_and_use1(i32 %a, i32 %b, i32 %c) {3880; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use13881; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3882; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13883; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13884; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3885; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3886; CHECK-NEXT: call void @use(i32 [[NOT2]])3887; CHECK-NEXT: ret i32 [[AND2]]3888;3889 %and1 = and i32 %b, %a3890 %not1 = xor i32 %and1, -13891 %not2 = xor i32 %a, -13892 %or1 = or i32 %not2, %b3893 %or2 = or i32 %or1, %c3894 %and2 = and i32 %or2, %not13895 call void @use(i32 %not2)3896 ret i32 %and23897}3898 3899define i32 @not_or_or_and_no_and_use2(i32 %a, i32 %b, i32 %c) {3900; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use23901; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3902; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13903; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13904; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3905; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3906; CHECK-NEXT: call void @use(i32 [[NOT2]])3907; CHECK-NEXT: ret i32 [[AND2]]3908;3909 %and1 = and i32 %b, %a3910 %not1 = xor i32 %and1, -13911 %not2 = xor i32 %a, -13912 %or1 = or i32 %b, %c3913 %or2 = or i32 %or1, %not23914 %and2 = and i32 %or2, %not13915 call void @use(i32 %not2)3916 ret i32 %and23917}3918 3919define i32 @not_or_or_and_no_and_use3(i32 %a, i32 %b, i32 %c) {3920; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use33921; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3922; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13923; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13924; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3925; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3926; CHECK-NEXT: call void @use(i32 [[NOT2]])3927; CHECK-NEXT: ret i32 [[AND2]]3928;3929 %and1 = and i32 %b, %a3930 %not1 = xor i32 %and1, -13931 %not2 = xor i32 %a, -13932 %or1 = or i32 %not2, %c3933 %or2 = or i32 %or1, %b3934 %and2 = and i32 %or2, %not13935 call void @use(i32 %not2)3936 ret i32 %and23937}3938 3939define i32 @not_or_or_and_no_and_use4(i32 %a, i32 %b, i32 %c) {3940; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use43941; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3942; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13943; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -13944; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]3945; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]3946; CHECK-NEXT: call void @use(i32 [[NOT2]])3947; CHECK-NEXT: ret i32 [[AND2]]3948;3949 %and1 = and i32 %b, %a3950 %not1 = xor i32 %and1, -13951 %not2 = xor i32 %a, -13952 %or1 = or i32 %not2, %c3953 %or2 = or i32 %or1, %b3954 %and2 = and i32 %or2, %not13955 call void @use(i32 %not2)3956 ret i32 %and23957}3958 3959define i32 @not_or_or_and_no_and_use5(i32 %a, i32 %b, i32 %c) {3960; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use53961; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3962; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]3963; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13964; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]3965; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP1]], [[B]]3966; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]3967; CHECK-NEXT: call void @use(i32 [[AND1]])3968; CHECK-NEXT: ret i32 [[AND2]]3969;3970 %and1 = and i32 %b, %a3971 %not1 = xor i32 %and1, -13972 %not2 = xor i32 %a, -13973 %or1 = or i32 %not2, %b3974 %or2 = or i32 %or1, %c3975 %and2 = and i32 %or2, %not13976 call void @use(i32 %and1)3977 ret i32 %and23978}3979 3980define i32 @not_or_or_and_no_and_use6(i32 %a, i32 %b, i32 %c) {3981; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use63982; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {3983; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]3984; CHECK-NEXT: [[NOT1:%.*]] = xor i32 [[AND1]], -13985; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -13986; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]3987; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP1]], [[B]]3988; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]3989; CHECK-NEXT: call void @use(i32 [[NOT1]])3990; CHECK-NEXT: ret i32 [[AND2]]3991;3992 %and1 = and i32 %b, %a3993 %not1 = xor i32 %and1, -13994 %not2 = xor i32 %a, -13995 %or1 = or i32 %not2, %b3996 %or2 = or i32 %or1, %c3997 %and2 = and i32 %or2, %not13998 call void @use(i32 %not1)3999 ret i32 %and24000}4001 4002define i32 @not_or_or_and_no_and_use7(i32 %a, i32 %b, i32 %c) {4003; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use74004; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {4005; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -14006; CHECK-NEXT: [[OR1:%.*]] = or i32 [[B]], [[NOT2]]4007; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -14008; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C]], [[TMP1]]4009; CHECK-NEXT: [[AND2:%.*]] = or i32 [[TMP2]], [[NOT2]]4010; CHECK-NEXT: call void @use(i32 [[OR1]])4011; CHECK-NEXT: ret i32 [[AND2]]4012;4013 %and1 = and i32 %b, %a4014 %not1 = xor i32 %and1, -14015 %not2 = xor i32 %a, -14016 %or1 = or i32 %not2, %b4017 %or2 = or i32 %or1, %c4018 %and2 = and i32 %or2, %not14019 call void @use(i32 %or1)4020 ret i32 %and24021}4022 4023define i32 @not_or_or_and_no_and_use8(i32 %a, i32 %b, i32 %c) {4024; CHECK-LABEL: define {{[^@]+}}@not_or_or_and_no_and_use84025; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {4026; CHECK-NEXT: [[AND1:%.*]] = and i32 [[B]], [[A]]4027; CHECK-NEXT: [[NOT2:%.*]] = xor i32 [[A]], -14028; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[C]], [[NOT2]]4029; CHECK-NEXT: [[OR2:%.*]] = or i32 [[TMP1]], [[B]]4030; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[AND1]], [[OR2]]4031; CHECK-NEXT: call void @use(i32 [[OR2]])4032; CHECK-NEXT: ret i32 [[AND2]]4033;4034 %and1 = and i32 %b, %a4035 %not1 = xor i32 %and1, -14036 %not2 = xor i32 %a, -14037 %or1 = or i32 %not2, %b4038 %or2 = or i32 %or1, %c4039 %and2 = and i32 %or2, %not14040 call void @use(i32 %or2)4041 ret i32 %and24042}4043 4044define i4 @and_orn_xor(i4 %a, i4 %b) {4045; CHECK-LABEL: define {{[^@]+}}@and_orn_xor4046; CHECK-SAME: (i4 [[A:%.*]], i4 [[B:%.*]]) {4047; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[A]], -14048; CHECK-NEXT: [[R:%.*]] = and i4 [[B]], [[TMP1]]4049; CHECK-NEXT: ret i4 [[R]]4050;4051 %xor = xor i4 %a, %b4052 %nota = xor i4 %a, -14053 %or = or i4 %nota, %b4054 %r = and i4 %or, %xor4055 ret i4 %r4056}4057 4058define <2 x i4> @and_orn_xor_commute1(<2 x i4> %a, <2 x i4> %b) {4059; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute14060; CHECK-SAME: (<2 x i4> [[A:%.*]], <2 x i4> [[B:%.*]]) {4061; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[A]], splat (i4 -1)4062; CHECK-NEXT: [[R:%.*]] = and <2 x i4> [[B]], [[TMP1]]4063; CHECK-NEXT: ret <2 x i4> [[R]]4064;4065 %xor = xor <2 x i4> %a, %b4066 %nota = xor <2 x i4> %a, <i4 -1, i4 poison>4067 %or = or <2 x i4> %nota, %b4068 %r = and <2 x i4> %xor, %or4069 ret <2 x i4> %r4070}4071 4072define i32 @and_orn_xor_commute2(i32 %a, i32 %b) {4073; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute24074; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {4075; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]4076; CHECK-NEXT: call void @use(i32 [[XOR]])4077; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -14078; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]4079; CHECK-NEXT: ret i32 [[R]]4080;4081 %xor = xor i32 %b, %a4082 call void @use(i32 %xor)4083 %nota = xor i32 %a, -14084 %or = or i32 %nota, %b4085 %r = and i32 %or, %xor4086 ret i32 %r4087}4088 4089define i32 @and_orn_xor_commute3(i32 %a, i32 %b) {4090; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute34091; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {4092; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -14093; CHECK-NEXT: call void @use(i32 [[NOTA]])4094; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -14095; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]4096; CHECK-NEXT: ret i32 [[R]]4097;4098 %xor = xor i32 %b, %a4099 %nota = xor i32 %a, -14100 call void @use(i32 %nota)4101 %or = or i32 %nota, %b4102 %r = and i32 %xor, %or4103 ret i32 %r4104}4105 4106define i32 @and_orn_xor_commute5(i32 %pa, i32 %pb) {4107; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute54108; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {4109; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]]4110; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]]4111; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -14112; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOTA]]4113; CHECK-NEXT: call void @use(i32 [[OR]])4114; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -14115; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]4116; CHECK-NEXT: ret i32 [[R]]4117;4118 %a = mul i32 %pa, %pa4119 %b = mul i32 %pb, %pb4120 %xor = xor i32 %a, %b4121 %nota = xor i32 %a, -14122 %or = or i32 %b, %nota4123 call void @use(i32 %or)4124 %r = and i32 %or, %xor4125 ret i32 %r4126}4127 4128define i32 @and_orn_xor_commute6(i32 %pa, i32 %pb) {4129; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute64130; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {4131; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]]4132; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]]4133; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]4134; CHECK-NEXT: call void @use(i32 [[XOR]])4135; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -14136; CHECK-NEXT: call void @use(i32 [[NOTA]])4137; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -14138; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]4139; CHECK-NEXT: ret i32 [[R]]4140;4141 %a = mul i32 %pa, %pa4142 %b = mul i32 %pb, %pb4143 %xor = xor i32 %a, %b4144 call void @use(i32 %xor)4145 %nota = xor i32 %a, -14146 call void @use(i32 %nota)4147 %or = or i32 %b, %nota4148 %r = and i32 %xor, %or4149 ret i32 %r4150}4151 4152define i32 @and_orn_xor_commute7(i32 %pa, i32 %pb) {4153; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute74154; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {4155; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]]4156; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]]4157; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]4158; CHECK-NEXT: call void @use(i32 [[XOR]])4159; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -14160; CHECK-NEXT: call void @use(i32 [[NOTA]])4161; CHECK-NEXT: [[OR:%.*]] = or i32 [[B]], [[NOTA]]4162; CHECK-NEXT: call void @use(i32 [[OR]])4163; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -14164; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]4165; CHECK-NEXT: ret i32 [[R]]4166;4167 %a = mul i32 %pa, %pa4168 %b = mul i32 %pb, %pb4169 %xor = xor i32 %b, %a4170 call void @use(i32 %xor)4171 %nota = xor i32 %a, -14172 call void @use(i32 %nota)4173 %or = or i32 %b, %nota4174 call void @use(i32 %or)4175 %r = and i32 %or, %xor4176 ret i32 %r4177}4178 4179define i32 @and_orn_xor_commute8(i32 %pa, i32 %pb) {4180; CHECK-LABEL: define {{[^@]+}}@and_orn_xor_commute84181; CHECK-SAME: (i32 [[PA:%.*]], i32 [[PB:%.*]]) {4182; CHECK-NEXT: [[A:%.*]] = mul i32 [[PA]], [[PA]]4183; CHECK-NEXT: [[B:%.*]] = mul i32 [[PB]], [[PB]]4184; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], -14185; CHECK-NEXT: [[R:%.*]] = and i32 [[B]], [[TMP1]]4186; CHECK-NEXT: ret i32 [[R]]4187;4188 %a = mul i32 %pa, %pa4189 %b = mul i32 %pb, %pb4190 %xor = xor i32 %b, %a4191 %nota = xor i32 %a, -14192 %or = or i32 %b, %nota4193 %r = and i32 %xor, %or4194 ret i32 %r4195}4196 4197define i32 @zext_zext_and_uses(i8 %x, i8 %y) {4198; CHECK-LABEL: define {{[^@]+}}@zext_zext_and_uses4199; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4200; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i324201; CHECK-NEXT: call void @use(i32 [[ZX]])4202; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y]] to i324203; CHECK-NEXT: call void @use(i32 [[ZY]])4204; CHECK-NEXT: [[R:%.*]] = and i32 [[ZX]], [[ZY]]4205; CHECK-NEXT: ret i32 [[R]]4206;4207 %zx = zext i8 %x to i324208 call void @use(i32 %zx)4209 %zy = zext i8 %y to i324210 call void @use(i32 %zy)4211 %r = and i32 %zx, %zy4212 ret i32 %r4213}4214 4215define i32 @sext_sext_or_uses(i8 %x, i8 %y) {4216; CHECK-LABEL: define {{[^@]+}}@sext_sext_or_uses4217; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4218; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i324219; CHECK-NEXT: call void @use(i32 [[SX]])4220; CHECK-NEXT: [[SY:%.*]] = sext i8 [[Y]] to i324221; CHECK-NEXT: call void @use(i32 [[SY]])4222; CHECK-NEXT: [[R:%.*]] = or i32 [[SX]], [[SY]]4223; CHECK-NEXT: ret i32 [[R]]4224;4225 %sx = sext i8 %x to i324226 call void @use(i32 %sx)4227 %sy = sext i8 %y to i324228 call void @use(i32 %sy)4229 %r = or i32 %sx, %sy4230 ret i32 %r4231}4232 4233define i32 @trunc_trunc_xor_uses(i65 %x, i65 %y) {4234; CHECK-LABEL: define {{[^@]+}}@trunc_trunc_xor_uses4235; CHECK-SAME: (i65 [[X:%.*]], i65 [[Y:%.*]]) {4236; CHECK-NEXT: [[SX:%.*]] = trunc i65 [[X]] to i324237; CHECK-NEXT: call void @use(i32 [[SX]])4238; CHECK-NEXT: [[SY:%.*]] = trunc i65 [[Y]] to i324239; CHECK-NEXT: call void @use(i32 [[SY]])4240; CHECK-NEXT: [[R:%.*]] = xor i32 [[SX]], [[SY]]4241; CHECK-NEXT: ret i32 [[R]]4242;4243 %sx = trunc i65 %x to i324244 call void @use(i32 %sx)4245 %sy = trunc i65 %y to i324246 call void @use(i32 %sy)4247 %r = xor i32 %sx, %sy4248 ret i32 %r4249}4250 4251define i16 @and_zext_zext(i8 %x, i4 %y) {4252; CHECK-LABEL: define {{[^@]+}}@and_zext_zext4253; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4254; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i84255; CHECK-NEXT: [[R1:%.*]] = and i8 [[X]], [[TMP1]]4256; CHECK-NEXT: [[R:%.*]] = zext nneg i8 [[R1]] to i164257; CHECK-NEXT: ret i16 [[R]]4258;4259 %zx = zext i8 %x to i164260 %zy = zext i4 %y to i164261 %r = and i16 %zx, %zy4262 ret i16 %r4263}4264 4265define i16 @and_zext_zext_2(i8 %x, i8 %y) {4266; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_24267; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4268; CHECK-NEXT: [[R1:%.*]] = and i8 [[X]], [[Y]]4269; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164270; CHECK-NEXT: ret i16 [[R]]4271;4272 %zx = zext i8 %x to i164273 %zy = zext i8 %y to i164274 %r = and i16 %zx, %zy4275 ret i16 %r4276}4277 4278define i16 @and_zext_zext_2_use1(i8 %x, i8 %y) {4279; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_2_use14280; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4281; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i164282; CHECK-NEXT: call void @use_i16(i16 [[ZX]])4283; CHECK-NEXT: [[R1:%.*]] = and i8 [[X]], [[Y]]4284; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164285; CHECK-NEXT: ret i16 [[R]]4286;4287 %zx = zext i8 %x to i164288 call void @use_i16(i16 %zx)4289 %zy = zext i8 %y to i164290 %r = and i16 %zx, %zy4291 ret i16 %r4292}4293 4294define i16 @or_zext_zext(i8 %x, i4 %y) {4295; CHECK-LABEL: define {{[^@]+}}@or_zext_zext4296; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4297; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i84298; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[TMP1]]4299; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164300; CHECK-NEXT: ret i16 [[R]]4301;4302 %zx = zext i8 %x to i164303 %zy = zext i4 %y to i164304 %r = or i16 %zy, %zx4305 ret i16 %r4306}4307 4308define i16 @or_zext_zext_2(i8 %x, i8 %y) {4309; CHECK-LABEL: define {{[^@]+}}@or_zext_zext_24310; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4311; CHECK-NEXT: [[R1:%.*]] = or i8 [[Y]], [[X]]4312; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164313; CHECK-NEXT: ret i16 [[R]]4314;4315 %zx = zext i8 %x to i164316 %zy = zext i8 %y to i164317 %r = or i16 %zy, %zx4318 ret i16 %r4319}4320 4321define i16 @or_zext_zext_2_use1(i8 %x, i8 %y) {4322; CHECK-LABEL: define {{[^@]+}}@or_zext_zext_2_use14323; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4324; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i164325; CHECK-NEXT: call void @use_i16(i16 [[ZX]])4326; CHECK-NEXT: [[R1:%.*]] = or i8 [[Y]], [[X]]4327; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164328; CHECK-NEXT: ret i16 [[R]]4329;4330 %zx = zext i8 %x to i164331 call void @use_i16(i16 %zx)4332 %zy = zext i8 %y to i164333 %r = or i16 %zy, %zx4334 ret i16 %r4335}4336 4337define i16 @or_disjoint_zext_zext(i8 %x, i4 %y) {4338; CHECK-LABEL: define {{[^@]+}}@or_disjoint_zext_zext4339; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4340; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i84341; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[X]], [[TMP1]]4342; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164343; CHECK-NEXT: ret i16 [[R]]4344;4345 %zx = zext i8 %x to i164346 %zy = zext i4 %y to i164347 %r = or disjoint i16 %zy, %zx4348 ret i16 %r4349}4350 4351define i16 @or_disjoint_zext_zext_2(i8 %x, i8 %y) {4352; CHECK-LABEL: define {{[^@]+}}@or_disjoint_zext_zext_24353; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4354; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[Y]], [[X]]4355; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i164356; CHECK-NEXT: ret i16 [[R]]4357;4358 %zx = zext i8 %x to i164359 %zy = zext i8 %y to i164360 %r = or disjoint i16 %zy, %zx4361 ret i16 %r4362}4363 4364define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) {4365; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext4366; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) {4367; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i4> [[Y]] to <2 x i8>4368; CHECK-NEXT: [[R1:%.*]] = xor <2 x i8> [[X]], [[TMP1]]4369; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>4370; CHECK-NEXT: ret <2 x i16> [[R]]4371;4372 %zx = zext <2 x i8> %x to <2 x i16>4373 %zy = zext <2 x i4> %y to <2 x i16>4374 %r = xor <2 x i16> %zx, %zy4375 ret <2 x i16> %r4376}4377 4378define <2 x i16> @xor_zext_zext_2(<2 x i8> %x, <2 x i8> %y) {4379; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext_24380; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {4381; CHECK-NEXT: [[R1:%.*]] = xor <2 x i8> [[X]], [[Y]]4382; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>4383; CHECK-NEXT: ret <2 x i16> [[R]]4384;4385 %zx = zext <2 x i8> %x to <2 x i16>4386 %zy = zext <2 x i8> %y to <2 x i16>4387 %r = xor <2 x i16> %zx, %zy4388 ret <2 x i16> %r4389}4390 4391define <2 x i16> @xor_zext_zext_2_use1(<2 x i8> %x, <2 x i8> %y) {4392; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext_2_use14393; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {4394; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i8> [[X]] to <2 x i16>4395; CHECK-NEXT: call void @use_2xi16(<2 x i16> [[ZX]])4396; CHECK-NEXT: [[R1:%.*]] = xor <2 x i8> [[X]], [[Y]]4397; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>4398; CHECK-NEXT: ret <2 x i16> [[R]]4399;4400 %zx = zext <2 x i8> %x to <2 x i16>4401 call void @use_2xi16(<2 x i16> %zx)4402 %zy = zext <2 x i8> %y to <2 x i16>4403 %r = xor <2 x i16> %zx, %zy4404 ret <2 x i16> %r4405}4406 4407define i16 @and_sext_sext(i8 %x, i4 %y) {4408; CHECK-LABEL: define {{[^@]+}}@and_sext_sext4409; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4410; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i84411; CHECK-NEXT: [[R1:%.*]] = and i8 [[X]], [[TMP1]]4412; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164413; CHECK-NEXT: ret i16 [[R]]4414;4415 %sx = sext i8 %x to i164416 %sy = sext i4 %y to i164417 %r = and i16 %sy, %sx4418 ret i16 %r4419}4420 4421define i16 @and_sext_sext_2(i8 %x, i8 %y) {4422; CHECK-LABEL: define {{[^@]+}}@and_sext_sext_24423; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4424; CHECK-NEXT: [[R1:%.*]] = and i8 [[Y]], [[X]]4425; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164426; CHECK-NEXT: ret i16 [[R]]4427;4428 %sx = sext i8 %x to i164429 %sy = sext i8 %y to i164430 %r = and i16 %sy, %sx4431 ret i16 %r4432}4433 4434define i16 @and_sext_sext_2_use1(i8 %x, i8 %y) {4435; CHECK-LABEL: define {{[^@]+}}@and_sext_sext_2_use14436; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4437; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i164438; CHECK-NEXT: call void @use_i16(i16 [[SX]])4439; CHECK-NEXT: [[R1:%.*]] = and i8 [[Y]], [[X]]4440; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164441; CHECK-NEXT: ret i16 [[R]]4442;4443 %sx = sext i8 %x to i164444 call void @use_i16(i16 %sx)4445 %sy = sext i8 %y to i164446 %r = and i16 %sy, %sx4447 ret i16 %r4448}4449 4450define i16 @or_sext_sext(i8 %x, i4 %y) {4451; CHECK-LABEL: define {{[^@]+}}@or_sext_sext4452; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4453; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i84454; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[TMP1]]4455; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164456; CHECK-NEXT: ret i16 [[R]]4457;4458 %sx = sext i8 %x to i164459 %sy = sext i4 %y to i164460 %r = or i16 %sx, %sy4461 ret i16 %r4462}4463 4464define i16 @or_sext_sext_2(i8 %x, i8 %y) {4465; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_24466; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4467; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[Y]]4468; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164469; CHECK-NEXT: ret i16 [[R]]4470;4471 %sx = sext i8 %x to i164472 %sy = sext i8 %y to i164473 %r = or i16 %sx, %sy4474 ret i16 %r4475}4476 4477define i16 @or_sext_sext_2_use1(i8 %x, i8 %y) {4478; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_2_use14479; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4480; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i164481; CHECK-NEXT: call void @use_i16(i16 [[SX]])4482; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[Y]]4483; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164484; CHECK-NEXT: ret i16 [[R]]4485;4486 %sx = sext i8 %x to i164487 call void @use_i16(i16 %sx)4488 %sy = sext i8 %y to i164489 %r = or i16 %sx, %sy4490 ret i16 %r4491}4492 4493define i16 @or_disjoint_sext_sext(i8 %x, i4 %y) {4494; CHECK-LABEL: define {{[^@]+}}@or_disjoint_sext_sext4495; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4496; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i84497; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[X]], [[TMP1]]4498; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164499; CHECK-NEXT: ret i16 [[R]]4500;4501 %sx = sext i8 %x to i164502 %sy = sext i4 %y to i164503 %r = or disjoint i16 %sx, %sy4504 ret i16 %r4505}4506 4507define i16 @or_disjoint_sext_sext_2(i8 %x, i8 %y) {4508; CHECK-LABEL: define {{[^@]+}}@or_disjoint_sext_sext_24509; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4510; CHECK-NEXT: [[R1:%.*]] = or disjoint i8 [[X]], [[Y]]4511; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164512; CHECK-NEXT: ret i16 [[R]]4513;4514 %sx = sext i8 %x to i164515 %sy = sext i8 %y to i164516 %r = or disjoint i16 %sx, %sy4517 ret i16 %r4518}4519 4520define i16 @xor_sext_sext(i8 %x, i4 %y) {4521; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext4522; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4523; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i84524; CHECK-NEXT: [[R1:%.*]] = xor i8 [[X]], [[TMP1]]4525; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164526; CHECK-NEXT: ret i16 [[R]]4527;4528 %sx = sext i8 %x to i164529 %sy = sext i4 %y to i164530 %r = xor i16 %sx, %sy4531 ret i16 %r4532}4533 4534define i16 @xor_sext_sext_2(i8 %x, i8 %y) {4535; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext_24536; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4537; CHECK-NEXT: [[R1:%.*]] = xor i8 [[X]], [[Y]]4538; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164539; CHECK-NEXT: ret i16 [[R]]4540;4541 %sx = sext i8 %x to i164542 %sy = sext i8 %y to i164543 %r = xor i16 %sx, %sy4544 ret i16 %r4545}4546 4547define i16 @xor_sext_sext_2_use1(i8 %x, i8 %y) {4548; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext_2_use14549; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4550; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i164551; CHECK-NEXT: call void @use_i16(i16 [[SX]])4552; CHECK-NEXT: [[R1:%.*]] = xor i8 [[X]], [[Y]]4553; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i164554; CHECK-NEXT: ret i16 [[R]]4555;4556 %sx = sext i8 %x to i164557 call void @use_i16(i16 %sx)4558 %sy = sext i8 %y to i164559 %r = xor i16 %sx, %sy4560 ret i16 %r4561}4562 4563; negative test - mismatched casts4564 4565define i16 @and_zext_sext(i8 %x, i4 %y) {4566; CHECK-LABEL: define {{[^@]+}}@and_zext_sext4567; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4568; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i164569; CHECK-NEXT: [[SY:%.*]] = sext i4 [[Y]] to i164570; CHECK-NEXT: [[R:%.*]] = and i16 [[ZX]], [[SY]]4571; CHECK-NEXT: ret i16 [[R]]4572;4573 %zx = zext i8 %x to i164574 %sy = sext i4 %y to i164575 %r = and i16 %zx, %sy4576 ret i16 %r4577}4578 4579; negative test - don't create an extra instruction4580 4581define i32 @and_zext_zext_use1(i8 %x, i4 %y) {4582; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use14583; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4584; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i324585; CHECK-NEXT: call void @use(i32 [[ZX]])4586; CHECK-NEXT: [[ZY:%.*]] = zext i4 [[Y]] to i324587; CHECK-NEXT: [[R:%.*]] = and i32 [[ZX]], [[ZY]]4588; CHECK-NEXT: ret i32 [[R]]4589;4590 %zx = zext i8 %x to i324591 call void @use(i32 %zx)4592 %zy = zext i4 %y to i324593 %r = and i32 %zx, %zy4594 ret i32 %r4595}4596 4597define i32 @and_zext_zext_use2(i8 %x, i8 %y) {4598; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use24599; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4600; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i324601; CHECK-NEXT: call void @use(i32 [[ZX]])4602; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y]] to i324603; CHECK-NEXT: call void @use(i32 [[ZY]])4604; CHECK-NEXT: [[R:%.*]] = and i32 [[ZX]], [[ZY]]4605; CHECK-NEXT: ret i32 [[R]]4606;4607 %zx = zext i8 %x to i324608 call void @use(i32 %zx)4609 %zy = zext i8 %y to i324610 call void @use(i32 %zy)4611 %r = and i32 %zx, %zy4612 ret i32 %r4613}4614 4615; negative test - don't create an extra instruction4616 4617define i32 @or_sext_sext_use1(i8 %x, i4 %y) {4618; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use14619; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {4620; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i324621; CHECK-NEXT: [[SY:%.*]] = sext i4 [[Y]] to i324622; CHECK-NEXT: call void @use(i32 [[SY]])4623; CHECK-NEXT: [[R:%.*]] = or i32 [[SX]], [[SY]]4624; CHECK-NEXT: ret i32 [[R]]4625;4626 %sx = sext i8 %x to i324627 %sy = sext i4 %y to i324628 call void @use(i32 %sy)4629 %r = or i32 %sx, %sy4630 ret i32 %r4631}4632 4633define i32 @or_sext_sext_use2(i8 %x, i8 %y) {4634; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use24635; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {4636; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i324637; CHECK-NEXT: call void @use(i32 [[SX]])4638; CHECK-NEXT: [[SY:%.*]] = sext i8 [[Y]] to i324639; CHECK-NEXT: call void @use(i32 [[SY]])4640; CHECK-NEXT: [[R:%.*]] = or i32 [[SX]], [[SY]]4641; CHECK-NEXT: ret i32 [[R]]4642;4643 %sx = sext i8 %x to i324644 call void @use(i32 %sx)4645 %sy = sext i8 %y to i324646 call void @use(i32 %sy)4647 %r = or i32 %sx, %sy4648 ret i32 %r4649}4650 4651define i1 @PR56294(i8 %x) {4652; CHECK-LABEL: define {{[^@]+}}@PR562944653; CHECK-SAME: (i8 [[X:%.*]]) {4654; CHECK-NEXT: ret i1 false4655;4656 %t2 = icmp eq i8 %x, 24657 %t3 = and i8 %x, 14658 %t4 = zext i1 %t2 to i324659 %t5 = zext i8 %t3 to i324660 %t6 = and i32 %t4, %t54661 %t7 = icmp ne i32 %t6, 04662 ret i1 %t74663}4664 4665define i32 @canonicalize_logic_first_or0(i32 %x) {4666; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or04667; CHECK-SAME: (i32 [[X:%.*]]) {4668; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 154669; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], 1124670; CHECK-NEXT: ret i32 [[R]]4671;4672 %a = add i32 %x, 112 ; 011100004673 %r = or i32 %a, 15 ; 000011114674 ret i32 %r4675}4676 4677define i32 @canonicalize_logic_first_or0_nsw(i32 %x) {4678; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nsw4679; CHECK-SAME: (i32 [[X:%.*]]) {4680; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 154681; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 1124682; CHECK-NEXT: ret i32 [[R]]4683;4684 %a = add nsw i32 %x, 112 ; 011100004685 %r = or i32 %a, 15 ; 000011114686 ret i32 %r4687}4688 4689define i32 @canonicalize_logic_first_or0_nswnuw(i32 %x) {4690; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nswnuw4691; CHECK-SAME: (i32 [[X:%.*]]) {4692; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 154693; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1124694; CHECK-NEXT: ret i32 [[R]]4695;4696 %a = add nsw nuw i32 %x, 112 ; 011100004697 %r = or i32 %a, 15 ; 000011114698 ret i32 %r4699}4700 4701define <2 x i32> @canonicalize_logic_first_or_vector0(<2 x i32> %x) {4702; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector04703; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4704; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)4705; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 112)4706; CHECK-NEXT: ret <2 x i32> [[R]]4707;4708 %a = add <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>4709 %r = or <2 x i32> <i32 15, i32 15>, %a ; <0x0000000F, 0x0000000F>4710 ret <2 x i32> %r4711}4712 4713define <2 x i32> @canonicalize_logic_first_or_vector0_nsw(<2 x i32> %x) {4714; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nsw4715; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4716; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)4717; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 112)4718; CHECK-NEXT: ret <2 x i32> [[R]]4719;4720 %a = add nsw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>4721 %r = or <2 x i32> <i32 15, i32 15>, %a ; <0x0000000F, 0x0000000F>4722 ret <2 x i32> %r4723}4724 4725define <2 x i32> @canonicalize_logic_first_or_vector0_nswnuw(<2 x i32> %x) {4726; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nswnuw4727; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4728; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], splat (i32 15)4729; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 112)4730; CHECK-NEXT: ret <2 x i32> [[R]]4731;4732 %a = add nsw nuw <2 x i32> <i32 112, i32 112>, %x ; <0x00000070, 0x00000070>4733 %r = or <2 x i32> <i32 15, i32 15>, %a ; <0x0000000F, 0x0000000F>4734 ret <2 x i32> %r4735}4736 4737define <2 x i32> @canonicalize_logic_first_or_vector1(<2 x i32> %x) {4738; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector14739; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4740; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176>4741; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>4742; CHECK-NEXT: ret <2 x i32> [[R]]4743;4744 %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>4745 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F>4746 ret <2 x i32> %r4747}4748 4749define <2 x i32> @canonicalize_logic_first_or_vector1_nsw(<2 x i32> %x) {4750; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nsw4751; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4752; CHECK-NEXT: [[A:%.*]] = add nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176>4753; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>4754; CHECK-NEXT: ret <2 x i32> [[R]]4755;4756 %a = add nsw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>4757 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F>4758 ret <2 x i32> %r4759}4760 4761define <2 x i32> @canonicalize_logic_first_or_vector1_nswnuw(<2 x i32> %x) {4762; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nswnuw4763; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4764; CHECK-NEXT: [[A:%.*]] = add nuw nsw <2 x i32> [[X]], <i32 -8388608, i32 2071986176>4765; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>4766; CHECK-NEXT: ret <2 x i32> [[R]]4767;4768 %a = add nsw nuw <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>4769 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F>4770 ret <2 x i32> %r4771}4772 4773define <2 x i32> @canonicalize_logic_first_or_vector2(<2 x i32> %x) {4774; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector24775; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4776; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640>4777; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], <i32 32783, i32 2063>4778; CHECK-NEXT: ret <2 x i32> [[R]]4779;4780 %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8>4781 %r = or <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F>4782 ret <2 x i32> %r4783}4784 4785define i32 @canonicalize_logic_first_or_mult_use1(i32 %x) {4786; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_mult_use14787; CHECK-SAME: (i32 [[X:%.*]]) {4788; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], 1124789; CHECK-NEXT: call void @use(i32 [[A]])4790; CHECK-NEXT: [[R:%.*]] = or i32 [[A]], 154791; CHECK-NEXT: ret i32 [[R]]4792;4793 %a = add i32 %x, 112 ; 011100004794 call void @use(i32 %a)4795 %r = or i32 %a, 15 ; 000011114796 ret i32 %r4797}4798 4799define i32 @canonicalize_logic_first_or_bad_constraints2(i32 %x) {4800; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_bad_constraints24801; CHECK-SAME: (i32 [[X:%.*]]) {4802; CHECK-NEXT: [[A:%.*]] = add i32 [[X]], 1124803; CHECK-NEXT: [[R:%.*]] = or i32 [[A]], 164804; CHECK-NEXT: ret i32 [[R]]4805;4806 %a = add i32 %x, 112 ; 011100004807 %r = or i32 %a, 16 ; 000100004808 ret i32 %r4809}4810 4811define i8 @canonicalize_logic_first_and0(i8 %x) {4812; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and04813; CHECK-SAME: (i8 [[X:%.*]]) {4814; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -104815; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 484816; CHECK-NEXT: ret i8 [[R]]4817;4818 %b = add i8 %x, 48 ; 001100004819 %r = and i8 %b, -10 ; 111101104820 ret i8 %r4821}4822 4823define i8 @canonicalize_logic_first_and0_nsw(i8 %x) {4824; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nsw4825; CHECK-SAME: (i8 [[X:%.*]]) {4826; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -104827; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[TMP1]], 484828; CHECK-NEXT: ret i8 [[R]]4829;4830 %b = add nsw i8 %x, 48 ; 001100004831 %r = and i8 %b, -10 ; 111101104832 ret i8 %r4833}4834 4835define i8 @canonicalize_logic_first_and0_nswnuw(i8 %x) {4836; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nswnuw4837; CHECK-SAME: (i8 [[X:%.*]]) {4838; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -104839; CHECK-NEXT: [[R:%.*]] = add nuw nsw i8 [[TMP1]], 484840; CHECK-NEXT: ret i8 [[R]]4841;4842 %b = add nsw nuw i8 %x, 48 ; 001100004843 %r = and i8 %b, -10 ; 111101104844 ret i8 %r4845}4846 4847define <2 x i8> @canonicalize_logic_first_and_vector0(<2 x i8> %x) {4848; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector04849; CHECK-SAME: (<2 x i8> [[X:%.*]]) {4850; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)4851; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], splat (i8 48)4852; CHECK-NEXT: ret <2 x i8> [[R]]4853;4854 %a = add <2 x i8> <i8 48, i8 48>, %x4855 %r = and <2 x i8> <i8 -10, i8 -10>, %a4856 ret <2 x i8> %r4857}4858 4859define <2 x i8> @canonicalize_logic_first_and_vector0_nsw(<2 x i8> %x) {4860; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nsw4861; CHECK-SAME: (<2 x i8> [[X:%.*]]) {4862; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)4863; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i8> [[TMP1]], splat (i8 48)4864; CHECK-NEXT: ret <2 x i8> [[R]]4865;4866 %a = add nsw <2 x i8> <i8 48, i8 48>, %x4867 %r = and <2 x i8> <i8 -10, i8 -10>, %a4868 ret <2 x i8> %r4869}4870 4871define <2 x i8> @canonicalize_logic_first_and_vector0_nswnuw(<2 x i8> %x) {4872; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nswnuw4873; CHECK-SAME: (<2 x i8> [[X:%.*]]) {4874; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], splat (i8 -10)4875; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i8> [[TMP1]], splat (i8 48)4876; CHECK-NEXT: ret <2 x i8> [[R]]4877;4878 %a = add nsw nuw <2 x i8> <i8 48, i8 48>, %x4879 %r = and <2 x i8> <i8 -10, i8 -10>, %a4880 ret <2 x i8> %r4881}4882 4883; element-wise the constants match constraints4884define <2 x i8> @canonicalize_logic_first_and_vector1(<2 x i8> %x) {4885; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector14886; CHECK-SAME: (<2 x i8> [[X:%.*]]) {4887; CHECK-NEXT: [[A:%.*]] = add <2 x i8> [[X]], <i8 48, i8 32>4888; CHECK-NEXT: [[R:%.*]] = and <2 x i8> [[A]], <i8 -10, i8 -4>4889; CHECK-NEXT: ret <2 x i8> [[R]]4890;4891 %a = add <2 x i8> <i8 48, i8 32>, %x4892 %r = and <2 x i8> <i8 -10, i8 -4>, %a4893 ret <2 x i8> %r4894}4895 4896; elementwise these constants do match constraints needed to canonicalize4897; logic op first then math op4898define <2 x i32> @canonicalize_logic_first_and_vector2(<2 x i32> %x) {4899; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector24900; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4901; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], splat (i32 612368384)4902; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768>4903; CHECK-NEXT: ret <2 x i32> [[R]]4904;4905 %a = add <2 x i32> <i32 612368384, i32 612368384>, %x ; <0x24800000, 0x24800000>4906 %r = and <2 x i32> <i32 -65536, i32 -32768>, %a ; <0xFFFF0000, 0xFFFF8000>4907 ret <2 x i32> %r4908}4909 4910define <2 x i32> @canonicalize_logic_first_and_vector3(<2 x i32> %x) {4911; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector34912; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4913; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 32768, i32 16384>4914; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], <i32 -65536, i32 -32768>4915; CHECK-NEXT: ret <2 x i32> [[R]]4916;4917 %a = add <2 x i32> <i32 32768, i32 16384>, %x ; <0x00008000, 0x00004000>4918 %r = and <2 x i32> <i32 -65536, i32 -32768>, %a ; <0xFFFF0000, 0xFFFF8000>4919 ret <2 x i32> %r4920}4921 4922define i8 @canonicalize_logic_first_and_mult_use1(i8 %x) {4923; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_mult_use14924; CHECK-SAME: (i8 [[X:%.*]]) {4925; CHECK-NEXT: [[B:%.*]] = add i8 [[X]], 484926; CHECK-NEXT: call void @use_i8(i8 [[B]])4927; CHECK-NEXT: [[R:%.*]] = and i8 [[B]], -104928; CHECK-NEXT: ret i8 [[R]]4929;4930 %b = add i8 %x, 48 ; 001100004931 call void @use_i8(i8 %b)4932 %r = and i8 %b, -10 ; 111101104933 ret i8 %r4934}4935 4936define i8 @canonicalize_logic_first_and_bad_constraints2(i8 %x) {4937; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_bad_constraints24938; CHECK-SAME: (i8 [[X:%.*]]) {4939; CHECK-NEXT: [[B:%.*]] = add i8 [[X]], 484940; CHECK-NEXT: [[R:%.*]] = and i8 [[B]], -264941; CHECK-NEXT: ret i8 [[R]]4942;4943 %b = add i8 %x, 48 ; 001100004944 %r = and i8 %b, -26 ; 111001104945 ret i8 %r4946}4947 4948define i8 @canonicalize_logic_first_xor_0(i8 %x) {4949; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_04950; CHECK-SAME: (i8 [[X:%.*]]) {4951; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 314952; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 964953; CHECK-NEXT: ret i8 [[R]]4954;4955 %a = add i8 %x, 96 ; 011000004956 %r = xor i8 %a, 31 ; 000111114957 ret i8 %r4958}4959 4960define i8 @canonicalize_logic_first_xor_0_nsw(i8 %x) {4961; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nsw4962; CHECK-SAME: (i8 [[X:%.*]]) {4963; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 314964; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[TMP1]], 964965; CHECK-NEXT: ret i8 [[R]]4966;4967 %a = add nsw i8 %x, 96 ; 011000004968 %r = xor i8 %a, 31 ; 000111114969 ret i8 %r4970}4971 4972define i8 @canonicalize_logic_first_xor_0_nswnuw(i8 %x) {4973; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nswnuw4974; CHECK-SAME: (i8 [[X:%.*]]) {4975; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 314976; CHECK-NEXT: [[R:%.*]] = add nuw nsw i8 [[TMP1]], 964977; CHECK-NEXT: ret i8 [[R]]4978;4979 %a = add nsw nuw i8 %x, 96 ; 011000004980 %r = xor i8 %a, 31 ; 000111114981 ret i8 %r4982}4983 4984define <2 x i32> @canonicalize_logic_first_xor_vector0(<2 x i32> %x) {4985; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector04986; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4987; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)4988; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], splat (i32 -8388608)4989; CHECK-NEXT: ret <2 x i32> [[R]]4990;4991 %a = add <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>4992 %r = xor <2 x i32> <i32 32783, i32 32783>, %a ; <0x0000800F, 0x0000800F>4993 ret <2 x i32> %r4994}4995 4996define <2 x i32> @canonicalize_logic_first_xor_vector0_nsw(<2 x i32> %x) {4997; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nsw4998; CHECK-SAME: (<2 x i32> [[X:%.*]]) {4999; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)5000; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i32> [[TMP1]], splat (i32 -8388608)5001; CHECK-NEXT: ret <2 x i32> [[R]]5002;5003 %a = add nsw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>5004 %r = xor <2 x i32> <i32 32783, i32 32783>, %a ; <0x0000800F, 0x0000800F>5005 ret <2 x i32> %r5006}5007 5008define <2 x i32> @canonicalize_logic_first_xor_vector0_nswnuw(<2 x i32> %x) {5009; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nswnuw5010; CHECK-SAME: (<2 x i32> [[X:%.*]]) {5011; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], splat (i32 32783)5012; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i32> [[TMP1]], splat (i32 -8388608)5013; CHECK-NEXT: ret <2 x i32> [[R]]5014;5015 %a = add nsw nuw <2 x i32> <i32 -8388608, i32 -8388608>, %x ; <0xFF800000, 0xFF800000>5016 %r = xor <2 x i32> <i32 32783, i32 32783>, %a ; <0x0000800F, 0x0000800F>5017 ret <2 x i32> %r5018}5019 5020define <2 x i32> @canonicalize_logic_first_xor_vector1(<2 x i32> %x) {5021; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector15022; CHECK-SAME: (<2 x i32> [[X:%.*]]) {5023; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 -8388608, i32 2071986176>5024; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063>5025; CHECK-NEXT: ret <2 x i32> [[R]]5026;5027 %a = add <2 x i32> <i32 -8388608, i32 2071986176>, %x ; <0xFF800000, 0x7B800000>5028 %r = xor <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F>5029 ret <2 x i32> %r5030}5031 5032define <2 x i32> @canonicalize_logic_first_xor_vector2(<2 x i32> %x) {5033; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector25034; CHECK-SAME: (<2 x i32> [[X:%.*]]) {5035; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[X]], <i32 2147483632, i32 2147483640>5036; CHECK-NEXT: [[R:%.*]] = xor <2 x i32> [[A]], <i32 32783, i32 2063>5037; CHECK-NEXT: ret <2 x i32> [[R]]5038;5039 %a = add <2 x i32> <i32 2147483632, i32 2147483640>, %x ; <0x7FFFFFF0, 0x7FFFFFF8>5040 %r = xor <2 x i32> <i32 32783, i32 2063>, %a ; <0x0000800F, 0x0000080F>5041 ret <2 x i32> %r5042}5043 5044define i8 @canonicalize_logic_first_xor_mult_use1(i8 %x) {5045; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_mult_use15046; CHECK-SAME: (i8 [[X:%.*]]) {5047; CHECK-NEXT: [[A:%.*]] = add i8 [[X]], 965048; CHECK-NEXT: call void @use_i8(i8 [[A]])5049; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], 315050; CHECK-NEXT: ret i8 [[R]]5051;5052 %a = add i8 %x, 96 ; 011000005053 call void @use_i8(i8 %a)5054 %r = xor i8 %a, 31 ; 000111115055 ret i8 %r5056}5057 5058define i8 @canonicalize_logic_first_xor_bad_constants2(i8 %x) {5059; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_bad_constants25060; CHECK-SAME: (i8 [[X:%.*]]) {5061; CHECK-NEXT: [[A:%.*]] = add i8 [[X]], 965062; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], 325063; CHECK-NEXT: ret i8 [[R]]5064;5065 %a = add i8 %x, 96 ; 011000005066 %r = xor i8 %a, 32 ; 001000005067 ret i8 %r5068}5069 5070@g = external global i85071 5072define i32 @canonicalize_logic_first_constexpr(i32 %x) {5073; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr5074; CHECK-SAME: (i32 [[X:%.*]]) {5075; CHECK-NEXT: [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -105076; CHECK-NEXT: ret i32 [[R]]5077;5078 %a = add i32 ptrtoint (ptr @g to i32), 485079 %r = and i32 %a, -105080 ret i32 %r5081}5082 5083define i32 @canonicalize_logic_first_constexpr_nuw(i32 %x) {5084; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_constexpr_nuw5085; CHECK-SAME: (i32 [[X:%.*]]) {5086; CHECK-NEXT: [[R:%.*]] = and i32 add (i32 ptrtoint (ptr @g to i32), i32 48), -105087; CHECK-NEXT: ret i32 [[R]]5088;5089 %a = add nuw i32 ptrtoint (ptr @g to i32), 485090 %r = and i32 %a, -105091 ret i32 %r5092}5093 5094define i1 @test_and_xor_freely_invertable(i32 %x, i32 %y, i1 %z) {5095; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable5096; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) {5097; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[X]], [[Y]]5098; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[Z]]5099; CHECK-NEXT: ret i1 [[AND]]5100;5101 %cmp = icmp sgt i32 %x, %y5102 %xor = xor i1 %cmp, %z5103 %and = and i1 %xor, %z5104 ret i1 %and5105}5106 5107define i1 @test_and_xor_freely_invertable_multiuse(i32 %x, i32 %y, i1 %z) {5108; CHECK-LABEL: define {{[^@]+}}@test_and_xor_freely_invertable_multiuse5109; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[Z:%.*]]) {5110; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]5111; CHECK-NEXT: call void @use_i1(i1 [[CMP]])5112; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[CMP]], true5113; CHECK-NEXT: [[AND:%.*]] = and i1 [[Z]], [[TMP1]]5114; CHECK-NEXT: ret i1 [[AND]]5115;5116 %cmp = icmp sgt i32 %x, %y5117 call void @use_i1(i1 %cmp)5118 %xor = xor i1 %cmp, %z5119 %and = and i1 %xor, %z5120 ret i1 %and5121}5122