brintos

brintos / llvm-project-archived public Read only

0
0
Text · 173.7 KiB · 8046f34 Raw
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