746 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; PR12535define i1 @test0(i32 %A) {6; CHECK-LABEL: @test0(7; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 08; CHECK-NEXT: ret i1 [[C]]9;10 %B = xor i32 %A, -214748364811 %C = icmp sgt i32 %B, -112 ret i1 %C13}14 15define <2 x i1> @test0vec(<2 x i32> %A) {16; CHECK-LABEL: @test0vec(17; CHECK-NEXT: [[C:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer18; CHECK-NEXT: ret <2 x i1> [[C]]19;20 %B = xor <2 x i32> %A, <i32 -2147483648, i32 -2147483648>21 %C = icmp sgt <2 x i32> %B, <i32 -1, i32 -1>22 ret <2 x i1> %C23}24 25define i1 @test1(i32 %A) {26; CHECK-LABEL: @test1(27; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[A:%.*]], 028; CHECK-NEXT: ret i1 [[C]]29;30 %B = xor i32 %A, 1234531 %C = icmp slt i32 %B, 032 ret i1 %C33}34 35; PR101436define i32 @test2(i32 %t1) {37; CHECK-LABEL: @test2(38; CHECK-NEXT: [[OVM:%.*]] = and i32 [[T1:%.*]], 3239; CHECK-NEXT: [[OV110:%.*]] = or disjoint i32 [[OVM]], 840; CHECK-NEXT: ret i32 [[OV110]]41;42 %ovm = and i32 %t1, 3243 %ov3 = add i32 %ovm, 14544 %ov110 = xor i32 %ov3, 15345 ret i32 %ov11046}47 48define i32 @test3(i32 %t1) {49; CHECK-LABEL: @test3(50; CHECK-NEXT: [[OVM:%.*]] = and i32 [[T1:%.*]], 3251; CHECK-NEXT: [[OV110:%.*]] = or disjoint i32 [[OVM]], 852; CHECK-NEXT: ret i32 [[OV110]]53;54 %ovm = or i32 %t1, 14555 %ov31 = and i32 %ovm, 17756 %ov110 = xor i32 %ov31, 15357 ret i32 %ov11058}59 60; defect-2 in rdar://1232973061; (X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)62; where the "X" has more than one use63define i32 @test5(i32 %val1) {64; CHECK-LABEL: @test5(65; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[VAL1:%.*]], 123466; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[VAL1]], 867; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[SHR]], 568; CHECK-NEXT: [[ADD:%.*]] = add i32 [[XOR1]], [[XOR]]69; CHECK-NEXT: ret i32 [[ADD]]70;71 %xor = xor i32 %val1, 123472 %shr = lshr i32 %xor, 873 %xor1 = xor i32 %shr, 174 %add = add i32 %xor1, %xor75 ret i32 %add76}77 78; defect-1 in rdar://1232973079; Simplify (X^Y) -> X or Y in the user's context if we know that80; only bits from X or Y are demanded.81; e.g. the "x ^ 1234" can be optimized into x in the context of "t >> 16".82; Put in other word, t >> 16 -> x >> 16.83; unsigned foo(unsigned x) { unsigned t = x ^ 1234; ; return (t >> 16) + t;}84define i32 @test6(i32 %x) {85; CHECK-LABEL: @test6(86; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X:%.*]], 123487; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 1688; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SHR]], [[XOR]]89; CHECK-NEXT: ret i32 [[ADD]]90;91 %xor = xor i32 %x, 123492 %shr = lshr i32 %xor, 1693 %add = add i32 %shr, %xor94 ret i32 %add95}96 97 98; (A | B) ^ (~A) -> (A | ~B)99define i32 @test7(i32 %a, i32 %b) {100; CHECK-LABEL: @test7(101; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1102; CHECK-NEXT: [[XOR:%.*]] = or i32 [[A:%.*]], [[B_NOT]]103; CHECK-NEXT: ret i32 [[XOR]]104;105 %or = or i32 %a, %b106 %neg = xor i32 %a, -1107 %xor = xor i32 %or, %neg108 ret i32 %xor109}110 111; (~A) ^ (A | B) -> (A | ~B)112define i32 @test8(i32 %a, i32 %b) {113; CHECK-LABEL: @test8(114; CHECK-NEXT: [[B_NOT:%.*]] = xor i32 [[B:%.*]], -1115; CHECK-NEXT: [[XOR:%.*]] = or i32 [[A:%.*]], [[B_NOT]]116; CHECK-NEXT: ret i32 [[XOR]]117;118 %neg = xor i32 %a, -1119 %or = or i32 %a, %b120 %xor = xor i32 %neg, %or121 ret i32 %xor122}123 124; (A & B) ^ (A ^ B) -> (A | B)125define i32 @test9(i32 %b, i32 %c) {126; CHECK-LABEL: @test9(127; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]128; CHECK-NEXT: ret i32 [[XOR2]]129;130 %and = and i32 %b, %c131 %xor = xor i32 %b, %c132 %xor2 = xor i32 %and, %xor133 ret i32 %xor2134}135 136; (A & B) ^ (B ^ A) -> (A | B)137define i32 @test9b(i32 %b, i32 %c) {138; CHECK-LABEL: @test9b(139; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]140; CHECK-NEXT: ret i32 [[XOR2]]141;142 %and = and i32 %b, %c143 %xor = xor i32 %c, %b144 %xor2 = xor i32 %and, %xor145 ret i32 %xor2146}147 148; (A ^ B) ^ (A & B) -> (A | B)149define i32 @test10(i32 %b, i32 %c) {150; CHECK-LABEL: @test10(151; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]152; CHECK-NEXT: ret i32 [[XOR2]]153;154 %xor = xor i32 %b, %c155 %and = and i32 %b, %c156 %xor2 = xor i32 %xor, %and157 ret i32 %xor2158}159 160; (A ^ B) ^ (A & B) -> (A | B)161define i32 @test10b(i32 %b, i32 %c) {162; CHECK-LABEL: @test10b(163; CHECK-NEXT: [[XOR2:%.*]] = or i32 [[B:%.*]], [[C:%.*]]164; CHECK-NEXT: ret i32 [[XOR2]]165;166 %xor = xor i32 %b, %c167 %and = and i32 %c, %b168 %xor2 = xor i32 %xor, %and169 ret i32 %xor2170}171 172define i32 @test11(i32 %A, i32 %B) {173; CHECK-LABEL: @test11(174; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]175; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]176; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1177; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]178; CHECK-NEXT: ret i32 [[AND]]179;180 %xor1 = xor i32 %B, %A181 %not = xor i32 %A, -1182 %xor2 = xor i32 %not, %B183 %and = and i32 %xor1, %xor2184 ret i32 %and185}186 187define i32 @test11b(i32 %A, i32 %B) {188; CHECK-LABEL: @test11b(189; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]190; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]191; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1192; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]193; CHECK-NEXT: ret i32 [[AND]]194;195 %xor1 = xor i32 %B, %A196 %not = xor i32 %A, -1197 %xor2 = xor i32 %not, %B198 %and = and i32 %xor2, %xor1199 ret i32 %and200}201 202define i32 @test11c(i32 %A, i32 %B) {203; CHECK-LABEL: @test11c(204; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]205; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]206; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1207; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]208; CHECK-NEXT: ret i32 [[AND]]209;210 %xor1 = xor i32 %A, %B211 %not = xor i32 %A, -1212 %xor2 = xor i32 %not, %B213 %and = and i32 %xor1, %xor2214 ret i32 %and215}216 217define i32 @test11d(i32 %A, i32 %B) {218; CHECK-LABEL: @test11d(219; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]220; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]221; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1222; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]223; CHECK-NEXT: ret i32 [[AND]]224;225 %xor1 = xor i32 %A, %B226 %not = xor i32 %A, -1227 %xor2 = xor i32 %not, %B228 %and = and i32 %xor2, %xor1229 ret i32 %and230}231 232define i32 @test11e(i32 %A, i32 %B, i32 %C) {233; CHECK-LABEL: @test11e(234; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]]235; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]]236; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[FORCE]]237; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1238; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]239; CHECK-NEXT: ret i32 [[AND]]240;241 %force = mul i32 %B, %C242 %xor1 = xor i32 %force, %A243 %not = xor i32 %A, -1244 %xor2 = xor i32 %force, %not245 %and = and i32 %xor1, %xor2246 ret i32 %and247}248 249define i32 @test11f(i32 %A, i32 %B, i32 %C) {250; CHECK-LABEL: @test11f(251; CHECK-NEXT: [[FORCE:%.*]] = mul i32 [[B:%.*]], [[C:%.*]]252; CHECK-NEXT: [[XOR1:%.*]] = xor i32 [[FORCE]], [[A:%.*]]253; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[FORCE]]254; CHECK-NEXT: [[XOR2:%.*]] = xor i32 [[TMP1]], -1255; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR1]], [[XOR2]]256; CHECK-NEXT: ret i32 [[AND]]257;258 %force = mul i32 %B, %C259 %xor1 = xor i32 %force, %A260 %not = xor i32 %A, -1261 %xor2 = xor i32 %force, %not262 %and = and i32 %xor2, %xor1263 ret i32 %and264}265 266define i32 @test12(i32 %a, i32 %b) {267; CHECK-LABEL: @test12(268; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]269; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1270; CHECK-NEXT: ret i32 [[XOR]]271;272 %negb = xor i32 %b, -1273 %and = and i32 %a, %negb274 %nega = xor i32 %a, -1275 %xor = xor i32 %and, %nega276 ret i32 %xor277}278 279define i32 @test12commuted(i32 %a, i32 %b) {280; CHECK-LABEL: @test12commuted(281; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]282; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1283; CHECK-NEXT: ret i32 [[XOR]]284;285 %negb = xor i32 %b, -1286 %and = and i32 %negb, %a287 %nega = xor i32 %a, -1288 %xor = xor i32 %and, %nega289 ret i32 %xor290}291 292; This is a test of canonicalization via operand complexity.293; The final xor has a binary operator and a (fake) unary operator,294; so binary (more complex) should come first.295 296define i32 @test13(i32 %a, i32 %b) {297; CHECK-LABEL: @test13(298; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]299; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1300; CHECK-NEXT: ret i32 [[XOR]]301;302 %nega = xor i32 %a, -1303 %negb = xor i32 %b, -1304 %and = and i32 %a, %negb305 %xor = xor i32 %nega, %and306 ret i32 %xor307}308 309define i32 @test13commuted(i32 %a, i32 %b) {310; CHECK-LABEL: @test13commuted(311; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]312; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1313; CHECK-NEXT: ret i32 [[XOR]]314;315 %nega = xor i32 %a, -1316 %negb = xor i32 %b, -1317 %and = and i32 %negb, %a318 %xor = xor i32 %nega, %and319 ret i32 %xor320}321 322; (A ^ C) ^ (A | B) -> ((~A) & B) ^ C323 324define i32 @xor_or_xor_common_op_commute1(i32 %a, i32 %b, i32 %c) {325; CHECK-LABEL: @xor_or_xor_common_op_commute1(326; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1327; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]328; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]329; CHECK-NEXT: ret i32 [[R]]330;331 %ac = xor i32 %a, %c332 %ab = or i32 %a, %b333 %r = xor i32 %ac, %ab334 ret i32 %r335}336 337; (C ^ A) ^ (A | B) -> ((~A) & B) ^ C338 339define i32 @xor_or_xor_common_op_commute2(i32 %a, i32 %b, i32 %c) {340; CHECK-LABEL: @xor_or_xor_common_op_commute2(341; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1342; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]343; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]344; CHECK-NEXT: ret i32 [[R]]345;346 %ac = xor i32 %c, %a347 %ab = or i32 %a, %b348 %r = xor i32 %ac, %ab349 ret i32 %r350}351 352; (A ^ C) ^ (B | A) -> ((~A) & B) ^ C353 354define i32 @xor_or_xor_common_op_commute3(i32 %a, i32 %b, i32 %c) {355; CHECK-LABEL: @xor_or_xor_common_op_commute3(356; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1357; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]358; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]359; CHECK-NEXT: ret i32 [[R]]360;361 %ac = xor i32 %a, %c362 %ab = or i32 %b, %a363 %r = xor i32 %ac, %ab364 ret i32 %r365}366 367; (C ^ A) ^ (B | A) -> ((~A) & B) ^ C368 369define i32 @xor_or_xor_common_op_commute4(i32 %a, i32 %b, i32 %c) {370; CHECK-LABEL: @xor_or_xor_common_op_commute4(371; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1372; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]373; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]374; CHECK-NEXT: ret i32 [[R]]375;376 %ac = xor i32 %c, %a377 %ab = or i32 %b, %a378 %r = xor i32 %ac, %ab379 ret i32 %r380}381 382; (A | B) ^ (A ^ C) -> ((~A) & B) ^ C383 384define i32 @xor_or_xor_common_op_commute5(i32 %a, i32 %b, i32 %c) {385; CHECK-LABEL: @xor_or_xor_common_op_commute5(386; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1387; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]388; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]389; CHECK-NEXT: ret i32 [[R]]390;391 %ac = xor i32 %a, %c392 %ab = or i32 %a, %b393 %r = xor i32 %ab, %ac394 ret i32 %r395}396 397; (A | B) ^ (C ^ A) -> ((~A) & B) ^ C398 399define i32 @xor_or_xor_common_op_commute6(i32 %a, i32 %b, i32 %c) {400; CHECK-LABEL: @xor_or_xor_common_op_commute6(401; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1402; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]403; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]404; CHECK-NEXT: ret i32 [[R]]405;406 %ac = xor i32 %c, %a407 %ab = or i32 %a, %b408 %r = xor i32 %ab, %ac409 ret i32 %r410}411 412; (B | A) ^ (A ^ C) -> ((~A) & B) ^ C413 414define i32 @xor_or_xor_common_op_commute7(i32 %a, i32 %b, i32 %c) {415; CHECK-LABEL: @xor_or_xor_common_op_commute7(416; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1417; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]418; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]419; CHECK-NEXT: ret i32 [[R]]420;421 %ac = xor i32 %a, %c422 %ab = or i32 %b, %a423 %r = xor i32 %ab, %ac424 ret i32 %r425}426 427; (B | A) ^ (C ^ A) -> ((~A) & B) ^ C428 429define i32 @xor_or_xor_common_op_commute8(i32 %a, i32 %b, i32 %c) {430; CHECK-LABEL: @xor_or_xor_common_op_commute8(431; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], -1432; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[B:%.*]], [[TMP1]]433; CHECK-NEXT: [[R:%.*]] = xor i32 [[TMP2]], [[C:%.*]]434; CHECK-NEXT: ret i32 [[R]]435;436 %ac = xor i32 %c, %a437 %ab = or i32 %b, %a438 %r = xor i32 %ab, %ac439 ret i32 %r440}441 442define i32 @xor_or_xor_common_op_extra_use1(i32 %a, i32 %b, i32 %c, ptr %p) {443; CHECK-LABEL: @xor_or_xor_common_op_extra_use1(444; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]445; CHECK-NEXT: store i32 [[AC]], ptr [[P:%.*]], align 4446; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]]447; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]]448; CHECK-NEXT: ret i32 [[R]]449;450 %ac = xor i32 %a, %c451 store i32 %ac, ptr %p452 %ab = or i32 %a, %b453 %r = xor i32 %ac, %ab454 ret i32 %r455}456 457define i32 @xor_or_xor_common_op_extra_use2(i32 %a, i32 %b, i32 %c, ptr %p) {458; CHECK-LABEL: @xor_or_xor_common_op_extra_use2(459; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]460; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]]461; CHECK-NEXT: store i32 [[AB]], ptr [[P:%.*]], align 4462; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]]463; CHECK-NEXT: ret i32 [[R]]464;465 %ac = xor i32 %a, %c466 %ab = or i32 %a, %b467 store i32 %ab, ptr %p468 %r = xor i32 %ac, %ab469 ret i32 %r470}471 472define i32 @xor_or_xor_common_op_extra_use3(i32 %a, i32 %b, i32 %c, ptr %p1, ptr %p2) {473; CHECK-LABEL: @xor_or_xor_common_op_extra_use3(474; CHECK-NEXT: [[AC:%.*]] = xor i32 [[A:%.*]], [[C:%.*]]475; CHECK-NEXT: store i32 [[AC]], ptr [[P1:%.*]], align 4476; CHECK-NEXT: [[AB:%.*]] = or i32 [[A]], [[B:%.*]]477; CHECK-NEXT: store i32 [[AB]], ptr [[P2:%.*]], align 4478; CHECK-NEXT: [[R:%.*]] = xor i32 [[AC]], [[AB]]479; CHECK-NEXT: ret i32 [[R]]480;481 %ac = xor i32 %a, %c482 store i32 %ac, ptr %p1483 %ab = or i32 %a, %b484 store i32 %ab, ptr %p2485 %r = xor i32 %ac, %ab486 ret i32 %r487}488 489define i8 @test15(i8 %A, i8 %B) {490; CHECK-LABEL: @test15(491; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]492; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[B]]493; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 33494; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR1]], [[XOR2]]495; CHECK-NEXT: [[RES:%.*]] = mul i8 [[AND]], [[XOR2]]496; CHECK-NEXT: ret i8 [[RES]]497;498 %xor1 = xor i8 %B, %A499 %not = xor i8 %A, 33500 %xor2 = xor i8 %not, %B501 %and = and i8 %xor1, %xor2502 %res = mul i8 %and, %xor2 ; to increase the use count for the xor503 ret i8 %res504}505 506define i8 @test16(i8 %A, i8 %B) {507; CHECK-LABEL: @test16(508; CHECK-NEXT: [[XOR1:%.*]] = xor i8 [[B:%.*]], [[A:%.*]]509; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[B]]510; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[TMP1]], 33511; CHECK-NEXT: [[AND:%.*]] = and i8 [[XOR2]], [[XOR1]]512; CHECK-NEXT: [[RES:%.*]] = mul i8 [[AND]], [[XOR2]]513; CHECK-NEXT: ret i8 [[RES]]514;515 %xor1 = xor i8 %B, %A516 %not = xor i8 %A, 33517 %xor2 = xor i8 %not, %B518 %and = and i8 %xor2, %xor1519 %res = mul i8 %and, %xor2 ; to increase the use count for the xor520 ret i8 %res521}522 523; Canonicalize ~((A & B) ^ (A | ?)) -> (A & B) | ~(A | ?)524 525define i3 @not_xor_to_or_not1(i3 %a, i3 %b, i3 %c) {526; CHECK-LABEL: @not_xor_to_or_not1(527; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]528; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]]529; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1530; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]531; CHECK-NEXT: ret i3 [[NOT]]532;533 %or = or i3 %b, %c534 %and = and i3 %a, %c535 %xor = xor i3 %and, %or536 %not = xor i3 %xor, -1537 ret i3 %not538}539 540define i3 @not_xor_to_or_not2(i3 %a, i3 %b, i3 %c) {541; CHECK-LABEL: @not_xor_to_or_not2(542; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]543; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]]544; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1545; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]546; CHECK-NEXT: ret i3 [[NOT]]547;548 %or = or i3 %c, %b549 %and = and i3 %a, %c550 %xor = xor i3 %and, %or551 %not = xor i3 %xor, -1552 ret i3 %not553}554 555define i3 @not_xor_to_or_not3(i3 %a, i3 %b, i3 %c) {556; CHECK-LABEL: @not_xor_to_or_not3(557; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]558; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]]559; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1560; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]561; CHECK-NEXT: ret i3 [[NOT]]562;563 %or = or i3 %c, %b564 %and = and i3 %c, %a565 %xor = xor i3 %and, %or566 %not = xor i3 %xor, -1567 ret i3 %not568}569 570define i3 @not_xor_to_or_not4(i3 %a, i3 %b, i3 %c) {571; CHECK-LABEL: @not_xor_to_or_not4(572; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]573; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]]574; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1575; CHECK-NEXT: [[NOT:%.*]] = or i3 [[AND]], [[TMP1]]576; CHECK-NEXT: ret i3 [[NOT]]577;578 %or = or i3 %b, %c579 %and = and i3 %c, %a580 %xor = xor i3 %and, %or581 %not = xor i3 %xor, -1582 ret i3 %not583}584 585define <3 x i5> @not_xor_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {586; CHECK-LABEL: @not_xor_to_or_not_vector(587; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]588; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]589; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)590; CHECK-NEXT: [[NOT:%.*]] = or <3 x i5> [[AND]], [[TMP1]]591; CHECK-NEXT: ret <3 x i5> [[NOT]]592;593 %or = or <3 x i5> %b, %c594 %and = and <3 x i5> %a, %c595 %xor = xor <3 x i5> %or, %and596 %not = xor <3 x i5> %xor, <i5 -1, i5 -1, i5 -1>597 ret <3 x i5> %not598}599 600define <3 x i5> @not_xor_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {601; CHECK-LABEL: @not_xor_to_or_not_vector_poison(602; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]603; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]604; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)605; CHECK-NEXT: [[NOT:%.*]] = or <3 x i5> [[AND]], [[TMP1]]606; CHECK-NEXT: ret <3 x i5> [[NOT]]607;608 %or = or <3 x i5> %b, %c609 %and = and <3 x i5> %a, %c610 %xor = xor <3 x i5> %or, %and611 %not = xor <3 x i5> %xor, <i5 poison, i5 -1, i5 -1>612 ret <3 x i5> %not613}614 615; negative test : not one use616 617define i3 @not_xor_to_or_not_2use(i3 %a, i3 %b, i3 %c) {618; CHECK-LABEL: @not_xor_to_or_not_2use(619; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]620; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]]621; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]]622; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1623; CHECK-NEXT: call void @use3(i3 [[XOR]])624; CHECK-NEXT: ret i3 [[NOT]]625;626 %or = or i3 %b, %c627 %and = and i3 %a, %c628 %xor = xor i3 %and, %or629 %not = xor i3 %xor, -1630 call void @use3(i3 %xor)631 ret i3 %not632}633 634; Canonicalize ~(A & B) ^ (A | ?) -> (A & B) | ~(A | ?)635 636define i3 @xor_notand_to_or_not1(i3 %a, i3 %b, i3 %c) {637; CHECK-LABEL: @xor_notand_to_or_not1(638; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]639; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]]640; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1641; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]642; CHECK-NEXT: ret i3 [[XOR]]643;644 %or = or i3 %b, %c645 %and = and i3 %a, %c646 %not = xor i3 %and, -1647 %xor = xor i3 %not, %or648 ret i3 %xor649}650 651define i3 @xor_notand_to_or_not2(i3 %a, i3 %b, i3 %c) {652; CHECK-LABEL: @xor_notand_to_or_not2(653; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]654; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]]655; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1656; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]657; CHECK-NEXT: ret i3 [[XOR]]658;659 %or = or i3 %c, %b660 %and = and i3 %a, %c661 %not = xor i3 %and, -1662 %xor = xor i3 %not, %or663 ret i3 %xor664}665 666define i3 @xor_notand_to_or_not3(i3 %a, i3 %b, i3 %c) {667; CHECK-LABEL: @xor_notand_to_or_not3(668; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]]669; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]]670; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1671; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]672; CHECK-NEXT: ret i3 [[XOR]]673;674 %or = or i3 %c, %b675 %and = and i3 %c, %a676 %not = xor i3 %and, -1677 %xor = xor i3 %not, %or678 ret i3 %xor679}680 681define i3 @xor_notand_to_or_not4(i3 %a, i3 %b, i3 %c) {682; CHECK-LABEL: @xor_notand_to_or_not4(683; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]684; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]]685; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[OR]], -1686; CHECK-NEXT: [[XOR:%.*]] = or i3 [[AND]], [[TMP1]]687; CHECK-NEXT: ret i3 [[XOR]]688;689 %or = or i3 %b, %c690 %and = and i3 %c, %a691 %not = xor i3 %and, -1692 %xor = xor i3 %not, %or693 ret i3 %xor694}695 696define <3 x i5> @xor_notand_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {697; CHECK-LABEL: @xor_notand_to_or_not_vector(698; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]699; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]700; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)701; CHECK-NEXT: [[XOR:%.*]] = or <3 x i5> [[AND]], [[TMP1]]702; CHECK-NEXT: ret <3 x i5> [[XOR]]703;704 %or = or <3 x i5> %b, %c705 %and = and <3 x i5> %a, %c706 %not = xor <3 x i5> %and, <i5 -1, i5 -1, i5 -1>707 %xor = xor <3 x i5> %not, %or708 ret <3 x i5> %xor709}710 711define <3 x i5> @xor_notand_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) {712; CHECK-LABEL: @xor_notand_to_or_not_vector_poison(713; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]]714; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]]715; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[OR]], splat (i5 -1)716; CHECK-NEXT: [[XOR:%.*]] = or <3 x i5> [[AND]], [[TMP1]]717; CHECK-NEXT: ret <3 x i5> [[XOR]]718;719 %or = or <3 x i5> %b, %c720 %and = and <3 x i5> %a, %c721 %not = xor <3 x i5> %and, <i5 -1, i5 poison, i5 -1>722 %xor = xor <3 x i5> %not, %or723 ret <3 x i5> %xor724}725 726; negative test : not one use727 728define i3 @xor_notand_to_or_not_2use(i3 %a, i3 %b, i3 %c) {729; CHECK-LABEL: @xor_notand_to_or_not_2use(730; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]]731; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]]732; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[AND]], -1733; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[OR]], [[NOT]]734; CHECK-NEXT: call void @use3(i3 [[NOT]])735; CHECK-NEXT: ret i3 [[XOR]]736;737 %or = or i3 %b, %c738 %and = and i3 %a, %c739 %not = xor i3 %and, -1740 %xor = xor i3 %not, %or741 call void @use3(i3 %not)742 ret i3 %xor743}744 745declare void @use3(i3)746