841 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i4)5 6; PR15107 8; (a | b) & ~(a & b) --> a ^ b9 10define i32 @and_to_xor1(i32 %a, i32 %b) {11; CHECK-LABEL: @and_to_xor1(12; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]13; CHECK-NEXT: ret i32 [[AND2]]14;15 %or = or i32 %a, %b16 %and = and i32 %a, %b17 %not = xor i32 %and, -118 %and2 = and i32 %or, %not19 ret i32 %and220}21 22; ~(a & b) & (a | b) --> a ^ b23 24define i32 @and_to_xor2(i32 %a, i32 %b) {25; CHECK-LABEL: @and_to_xor2(26; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]27; CHECK-NEXT: ret i32 [[AND2]]28;29 %or = or i32 %a, %b30 %and = and i32 %a, %b31 %not = xor i32 %and, -132 %and2 = and i32 %not, %or33 ret i32 %and234}35 36; (a | b) & ~(b & a) --> a ^ b37 38define i32 @and_to_xor3(i32 %a, i32 %b) {39; CHECK-LABEL: @and_to_xor3(40; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]41; CHECK-NEXT: ret i32 [[AND2]]42;43 %or = or i32 %a, %b44 %and = and i32 %b, %a45 %not = xor i32 %and, -146 %and2 = and i32 %or, %not47 ret i32 %and248}49 50; ~(a & b) & (b | a) --> a ^ b51 52define i32 @and_to_xor4(i32 %a, i32 %b) {53; CHECK-LABEL: @and_to_xor4(54; CHECK-NEXT: [[AND2:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]55; CHECK-NEXT: ret i32 [[AND2]]56;57 %or = or i32 %b, %a58 %and = and i32 %a, %b59 %not = xor i32 %and, -160 %and2 = and i32 %not, %or61 ret i32 %and262}63 64define <4 x i32> @and_to_xor1_vec(<4 x i32> %a, <4 x i32> %b) {65; CHECK-LABEL: @and_to_xor1_vec(66; CHECK-NEXT: [[AND2:%.*]] = xor <4 x i32> [[A:%.*]], [[B:%.*]]67; CHECK-NEXT: ret <4 x i32> [[AND2]]68;69 %or = or <4 x i32> %a, %b70 %and = and <4 x i32> %a, %b71 %not = xor <4 x i32> %and, < i32 -1, i32 -1, i32 -1, i32 -1 >72 %and2 = and <4 x i32> %or, %not73 ret <4 x i32> %and274}75 76; In the next 4 tests, cast instructions are used to thwart operand complexity77; canonicalizations, so we can test all of the commuted patterns.78 79; (a | ~b) & (~a | b) --> ~(a ^ b)80 81define i32 @and_to_nxor1(float %fa, float %fb) {82; CHECK-LABEL: @and_to_nxor1(83; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i3284; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i3285; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]86; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -187; CHECK-NEXT: ret i32 [[AND]]88;89 %a = fptosi float %fa to i3290 %b = fptosi float %fb to i3291 %nota = xor i32 %a, -192 %notb = xor i32 %b, -193 %or1 = or i32 %a, %notb94 %or2 = or i32 %nota, %b95 %and = and i32 %or1, %or296 ret i32 %and97}98 99; (a | ~b) & (b | ~a) --> ~(a ^ b)100 101define i32 @and_to_nxor2(float %fa, float %fb) {102; CHECK-LABEL: @and_to_nxor2(103; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32104; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32105; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]106; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1107; CHECK-NEXT: ret i32 [[AND]]108;109 %a = fptosi float %fa to i32110 %b = fptosi float %fb to i32111 %nota = xor i32 %a, -1112 %notb = xor i32 %b, -1113 %or1 = or i32 %a, %notb114 %or2 = or i32 %b, %nota115 %and = and i32 %or1, %or2116 ret i32 %and117}118 119; (~a | b) & (a | ~b) --> ~(a ^ b)120 121define i32 @and_to_nxor3(float %fa, float %fb) {122; CHECK-LABEL: @and_to_nxor3(123; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32124; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32125; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[A]]126; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1127; CHECK-NEXT: ret i32 [[AND]]128;129 %a = fptosi float %fa to i32130 %b = fptosi float %fb to i32131 %nota = xor i32 %a, -1132 %notb = xor i32 %b, -1133 %or1 = or i32 %nota, %b134 %or2 = or i32 %a, %notb135 %and = and i32 %or1, %or2136 ret i32 %and137}138 139; (~a | b) & (~b | a) --> ~(a ^ b)140 141define i32 @and_to_nxor4(float %fa, float %fb) {142; CHECK-LABEL: @and_to_nxor4(143; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32144; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32145; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[A]]146; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], -1147; CHECK-NEXT: ret i32 [[AND]]148;149 %a = fptosi float %fa to i32150 %b = fptosi float %fb to i32151 %nota = xor i32 %a, -1152 %notb = xor i32 %b, -1153 %or1 = or i32 %nota, %b154 %or2 = or i32 %notb, %a155 %and = and i32 %or1, %or2156 ret i32 %and157}158 159; (a & ~b) | (~a & b) --> a ^ b160 161define i32 @or_to_xor1(float %fa, float %fb) {162; CHECK-LABEL: @or_to_xor1(163; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32164; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32165; CHECK-NEXT: [[OR:%.*]] = xor i32 [[A]], [[B]]166; CHECK-NEXT: ret i32 [[OR]]167;168 %a = fptosi float %fa to i32169 %b = fptosi float %fb to i32170 %nota = xor i32 %a, -1171 %notb = xor i32 %b, -1172 %and1 = and i32 %a, %notb173 %and2 = and i32 %nota, %b174 %or = or i32 %and1, %and2175 ret i32 %or176}177 178; (a & ~b) | (b & ~a) --> a ^ b179 180define i32 @or_to_xor2(float %fa, float %fb) {181; CHECK-LABEL: @or_to_xor2(182; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32183; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32184; CHECK-NEXT: [[OR:%.*]] = xor i32 [[A]], [[B]]185; CHECK-NEXT: ret i32 [[OR]]186;187 %a = fptosi float %fa to i32188 %b = fptosi float %fb to i32189 %nota = xor i32 %a, -1190 %notb = xor i32 %b, -1191 %and1 = and i32 %a, %notb192 %and2 = and i32 %b, %nota193 %or = or i32 %and1, %and2194 ret i32 %or195}196 197; (~a & b) | (~b & a) --> a ^ b198 199define i32 @or_to_xor3(float %fa, float %fb) {200; CHECK-LABEL: @or_to_xor3(201; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32202; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32203; CHECK-NEXT: [[OR:%.*]] = xor i32 [[B]], [[A]]204; CHECK-NEXT: ret i32 [[OR]]205;206 %a = fptosi float %fa to i32207 %b = fptosi float %fb to i32208 %nota = xor i32 %a, -1209 %notb = xor i32 %b, -1210 %and1 = and i32 %nota, %b211 %and2 = and i32 %notb, %a212 %or = or i32 %and1, %and2213 ret i32 %or214}215 216; (~a & b) | (a & ~b) --> a ^ b217 218define i32 @or_to_xor4(float %fa, float %fb) {219; CHECK-LABEL: @or_to_xor4(220; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32221; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32222; CHECK-NEXT: [[OR:%.*]] = xor i32 [[B]], [[A]]223; CHECK-NEXT: ret i32 [[OR]]224;225 %a = fptosi float %fa to i32226 %b = fptosi float %fb to i32227 %nota = xor i32 %a, -1228 %notb = xor i32 %b, -1229 %and1 = and i32 %nota, %b230 %and2 = and i32 %a, %notb231 %or = or i32 %and1, %and2232 ret i32 %or233}234 235; (a & b) | ~(a | b) --> ~(a ^ b)236 237define i32 @or_to_nxor1(i32 %a, i32 %b) {238; CHECK-LABEL: @or_to_nxor1(239; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]240; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1241; CHECK-NEXT: ret i32 [[OR2]]242;243 %and = and i32 %a, %b244 %or = or i32 %a, %b245 %notor = xor i32 %or, -1246 %or2 = or i32 %and, %notor247 ret i32 %or2248}249 250; (a & b) | ~(b | a) --> ~(a ^ b)251 252define i32 @or_to_nxor2(i32 %a, i32 %b) {253; CHECK-LABEL: @or_to_nxor2(254; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]255; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1256; CHECK-NEXT: ret i32 [[OR2]]257;258 %and = and i32 %a, %b259 %or = or i32 %b, %a260 %notor = xor i32 %or, -1261 %or2 = or i32 %and, %notor262 ret i32 %or2263}264 265; ~(a | b) | (a & b) --> ~(a ^ b)266 267define i32 @or_to_nxor3(i32 %a, i32 %b) {268; CHECK-LABEL: @or_to_nxor3(269; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]270; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1271; CHECK-NEXT: ret i32 [[OR2]]272;273 %and = and i32 %a, %b274 %or = or i32 %a, %b275 %notor = xor i32 %or, -1276 %or2 = or i32 %notor, %and277 ret i32 %or2278}279 280; ~(a | b) | (b & a) --> ~(a ^ b)281 282define i32 @or_to_nxor4(i32 %a, i32 %b) {283; CHECK-LABEL: @or_to_nxor4(284; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]285; CHECK-NEXT: [[OR2:%.*]] = xor i32 [[TMP1]], -1286; CHECK-NEXT: ret i32 [[OR2]]287;288 %and = and i32 %b, %a289 %or = or i32 %a, %b290 %notor = xor i32 %or, -1291 %or2 = or i32 %notor, %and292 ret i32 %or2293}294 295; (a & b) ^ (a | b) --> a ^ b296 297define i32 @xor_to_xor1(i32 %a, i32 %b) {298; CHECK-LABEL: @xor_to_xor1(299; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]300; CHECK-NEXT: ret i32 [[XOR]]301;302 %and = and i32 %a, %b303 %or = or i32 %a, %b304 %xor = xor i32 %and, %or305 ret i32 %xor306}307 308; (a & b) ^ (b | a) --> a ^ b309 310define i32 @xor_to_xor2(i32 %a, i32 %b) {311; CHECK-LABEL: @xor_to_xor2(312; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]313; CHECK-NEXT: ret i32 [[XOR]]314;315 %and = and i32 %a, %b316 %or = or i32 %b, %a317 %xor = xor i32 %and, %or318 ret i32 %xor319}320 321; (a | b) ^ (a & b) --> a ^ b322 323define i32 @xor_to_xor3(i32 %a, i32 %b) {324; CHECK-LABEL: @xor_to_xor3(325; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]326; CHECK-NEXT: ret i32 [[XOR]]327;328 %or = or i32 %a, %b329 %and = and i32 %a, %b330 %xor = xor i32 %or, %and331 ret i32 %xor332}333 334; (a | b) ^ (b & a) --> a ^ b335 336define i32 @xor_to_xor4(i32 %a, i32 %b) {337; CHECK-LABEL: @xor_to_xor4(338; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]339; CHECK-NEXT: ret i32 [[XOR]]340;341 %or = or i32 %a, %b342 %and = and i32 %b, %a343 %xor = xor i32 %or, %and344 ret i32 %xor345}346 347; (a | ~b) ^ (~a | b) --> a ^ b348 349; In the next 8 tests, cast instructions are used to thwart operand complexity350; canonicalizations, so we can test all of the commuted patterns.351 352define i32 @xor_to_xor5(float %fa, float %fb) {353; CHECK-LABEL: @xor_to_xor5(354; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32355; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32356; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]357; CHECK-NEXT: ret i32 [[XOR]]358;359 %a = fptosi float %fa to i32360 %b = fptosi float %fb to i32361 %nota = xor i32 %a, -1362 %notb = xor i32 %b, -1363 %or1 = or i32 %a, %notb364 %or2 = or i32 %nota, %b365 %xor = xor i32 %or1, %or2366 ret i32 %xor367}368 369; (a | ~b) ^ (b | ~a) --> a ^ b370 371define i32 @xor_to_xor6(float %fa, float %fb) {372; CHECK-LABEL: @xor_to_xor6(373; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32374; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32375; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]376; CHECK-NEXT: ret i32 [[XOR]]377;378 %a = fptosi float %fa to i32379 %b = fptosi float %fb to i32380 %nota = xor i32 %a, -1381 %notb = xor i32 %b, -1382 %or1 = or i32 %a, %notb383 %or2 = or i32 %b, %nota384 %xor = xor i32 %or1, %or2385 ret i32 %xor386}387 388; (~a | b) ^ (a | ~b) --> a ^ b389 390define i32 @xor_to_xor7(float %fa, float %fb) {391; CHECK-LABEL: @xor_to_xor7(392; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32393; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32394; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]395; CHECK-NEXT: ret i32 [[XOR]]396;397 %a = fptosi float %fa to i32398 %b = fptosi float %fb to i32399 %nota = xor i32 %a, -1400 %notb = xor i32 %b, -1401 %or1 = or i32 %a, %notb402 %or2 = or i32 %nota, %b403 %xor = xor i32 %or2, %or1404 ret i32 %xor405}406 407; (~a | b) ^ (~b | a) --> a ^ b408 409define i32 @xor_to_xor8(float %fa, float %fb) {410; CHECK-LABEL: @xor_to_xor8(411; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32412; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32413; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]414; CHECK-NEXT: ret i32 [[XOR]]415;416 %a = fptosi float %fa to i32417 %b = fptosi float %fb to i32418 %nota = xor i32 %a, -1419 %notb = xor i32 %b, -1420 %or1 = or i32 %notb, %a421 %or2 = or i32 %nota, %b422 %xor = xor i32 %or2, %or1423 ret i32 %xor424}425 426; (a & ~b) ^ (~a & b) --> a ^ b427 428define i32 @xor_to_xor9(float %fa, float %fb) {429; CHECK-LABEL: @xor_to_xor9(430; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32431; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32432; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]433; CHECK-NEXT: ret i32 [[XOR]]434;435 %a = fptosi float %fa to i32436 %b = fptosi float %fb to i32437 %nota = xor i32 %a, -1438 %notb = xor i32 %b, -1439 %and1 = and i32 %a, %notb440 %and2 = and i32 %nota, %b441 %xor = xor i32 %and1, %and2442 ret i32 %xor443}444 445; (a & ~b) ^ (b & ~a) --> a ^ b446 447define i32 @xor_to_xor10(float %fa, float %fb) {448; CHECK-LABEL: @xor_to_xor10(449; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32450; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32451; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A]], [[B]]452; CHECK-NEXT: ret i32 [[XOR]]453;454 %a = fptosi float %fa to i32455 %b = fptosi float %fb to i32456 %nota = xor i32 %a, -1457 %notb = xor i32 %b, -1458 %and1 = and i32 %a, %notb459 %and2 = and i32 %b, %nota460 %xor = xor i32 %and1, %and2461 ret i32 %xor462}463 464; (~a & b) ^ (a & ~b) --> a ^ b465 466define i32 @xor_to_xor11(float %fa, float %fb) {467; CHECK-LABEL: @xor_to_xor11(468; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32469; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32470; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]471; CHECK-NEXT: ret i32 [[XOR]]472;473 %a = fptosi float %fa to i32474 %b = fptosi float %fb to i32475 %nota = xor i32 %a, -1476 %notb = xor i32 %b, -1477 %and1 = and i32 %a, %notb478 %and2 = and i32 %nota, %b479 %xor = xor i32 %and2, %and1480 ret i32 %xor481}482 483; (~a & b) ^ (~b & a) --> a ^ b484 485define i32 @xor_to_xor12(float %fa, float %fb) {486; CHECK-LABEL: @xor_to_xor12(487; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32488; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32489; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[A]]490; CHECK-NEXT: ret i32 [[XOR]]491;492 %a = fptosi float %fa to i32493 %b = fptosi float %fb to i32494 %nota = xor i32 %a, -1495 %notb = xor i32 %b, -1496 %and1 = and i32 %notb, %a497 %and2 = and i32 %nota, %b498 %xor = xor i32 %and2, %and1499 ret i32 %xor500}501 502; https://bugs.llvm.org/show_bug.cgi?id=32830503; Make sure we're matching operands correctly and not folding things wrongly.504 505define i64 @PR32830(i64 %a, i64 %b, i64 %c) {506; CHECK-LABEL: @PR32830(507; CHECK-NEXT: [[NOTA:%.*]] = xor i64 [[A:%.*]], -1508; CHECK-NEXT: [[NOTB:%.*]] = xor i64 [[B:%.*]], -1509; CHECK-NEXT: [[OR1:%.*]] = or i64 [[A]], [[NOTB]]510; CHECK-NEXT: [[OR2:%.*]] = or i64 [[C:%.*]], [[NOTA]]511; CHECK-NEXT: [[AND:%.*]] = and i64 [[OR1]], [[OR2]]512; CHECK-NEXT: ret i64 [[AND]]513;514 %nota = xor i64 %a, -1515 %notb = xor i64 %b, -1516 %or1 = or i64 %notb, %a517 %or2 = or i64 %nota, %c518 %and = and i64 %or1, %or2519 ret i64 %and520}521 522; (~a | b) & (~b | a) --> ~(a ^ b)523; TODO: this increases instruction count if the pieces have additional users524define i32 @and_to_nxor_multiuse(float %fa, float %fb) {525; CHECK-LABEL: @and_to_nxor_multiuse(526; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32527; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32528; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1529; CHECK-NEXT: [[NOTB:%.*]] = xor i32 [[B]], -1530; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOTA]], [[B]]531; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOTB]], [[A]]532; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR1]], [[OR2]]533; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[OR1]], [[OR2]]534; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL1]], [[AND]]535; CHECK-NEXT: ret i32 [[MUL2]]536;537 %a = fptosi float %fa to i32538 %b = fptosi float %fb to i32539 %nota = xor i32 %a, -1540 %notb = xor i32 %b, -1541 %or1 = or i32 %nota, %b542 %or2 = or i32 %notb, %a543 %and = and i32 %or1, %or2544 %mul1 = mul i32 %or1, %or2 ; here to increase the use count of the inputs to the and545 %mul2 = mul i32 %mul1, %and546 ret i32 %mul2547}548 549; (a & b) | ~(a | b) --> ~(a ^ b)550; TODO: this increases instruction count if the pieces have additional users551define i32 @or_to_nxor_multiuse(i32 noundef %a, i32 noundef %b) {552; CHECK-LABEL: @or_to_nxor_multiuse(553; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]]554; CHECK-NEXT: [[OR:%.*]] = or i32 [[A]], [[B]]555; CHECK-NEXT: [[NOTOR:%.*]] = xor i32 [[OR]], -1556; CHECK-NEXT: [[OR2:%.*]] = or disjoint i32 [[AND]], [[NOTOR]]557; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[AND]], [[NOTOR]]558; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL1]], [[OR2]]559; CHECK-NEXT: ret i32 [[MUL2]]560;561 %and = and i32 %a, %b562 %or = or i32 %a, %b563 %notor = xor i32 %or, -1564 %or2 = or i32 %and, %notor565 %mul1 = mul i32 %and, %notor ; here to increase the use count of the inputs to the or566 %mul2 = mul i32 %mul1, %or2567 ret i32 %mul2568}569 570; (a | b) ^ (~a | ~b) --> ~(a ^ b)571define i32 @xor_to_xnor1(float %fa, float %fb) {572; CHECK-LABEL: @xor_to_xnor1(573; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32574; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32575; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]576; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1577; CHECK-NEXT: ret i32 [[XOR]]578;579 %a = fptosi float %fa to i32580 %b = fptosi float %fb to i32581 %nota = xor i32 %a, -1582 %notb = xor i32 %b, -1583 %or1 = or i32 %a, %b584 %or2 = or i32 %nota, %notb585 %xor = xor i32 %or1, %or2586 ret i32 %xor587}588 589; (a | b) ^ (~b | ~a) --> ~(a ^ b)590define i32 @xor_to_xnor2(float %fa, float %fb) {591; CHECK-LABEL: @xor_to_xnor2(592; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32593; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32594; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]595; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1596; CHECK-NEXT: ret i32 [[XOR]]597;598 %a = fptosi float %fa to i32599 %b = fptosi float %fb to i32600 %nota = xor i32 %a, -1601 %notb = xor i32 %b, -1602 %or1 = or i32 %a, %b603 %or2 = or i32 %notb, %nota604 %xor = xor i32 %or1, %or2605 ret i32 %xor606}607 608; (~a | ~b) ^ (a | b) --> ~(a ^ b)609define i32 @xor_to_xnor3(float %fa, float %fb) {610; CHECK-LABEL: @xor_to_xnor3(611; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32612; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32613; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A]], [[B]]614; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1615; CHECK-NEXT: ret i32 [[XOR]]616;617 %a = fptosi float %fa to i32618 %b = fptosi float %fb to i32619 %nota = xor i32 %a, -1620 %notb = xor i32 %b, -1621 %or1 = or i32 %nota, %notb622 %or2 = or i32 %a, %b623 %xor = xor i32 %or1, %or2624 ret i32 %xor625}626 627; (~a | ~b) ^ (b | a) --> ~(a ^ b)628define i32 @xor_to_xnor4(float %fa, float %fb) {629; CHECK-LABEL: @xor_to_xnor4(630; CHECK-NEXT: [[A:%.*]] = fptosi float [[FA:%.*]] to i32631; CHECK-NEXT: [[B:%.*]] = fptosi float [[FB:%.*]] to i32632; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], [[A]]633; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], -1634; CHECK-NEXT: ret i32 [[XOR]]635;636 %a = fptosi float %fa to i32637 %b = fptosi float %fb to i32638 %nota = xor i32 %a, -1639 %notb = xor i32 %b, -1640 %or1 = or i32 %nota, %notb641 %or2 = or i32 %b, %a642 %xor = xor i32 %or1, %or2643 ret i32 %xor644}645 646define i4 @simplify_or_common_op_commute0(i4 %x, i4 %y, i4 %z) {647; CHECK-LABEL: @simplify_or_common_op_commute0(648; CHECK-NEXT: ret i4 -1649;650 %xy = and i4 %x, %y651 %xyz = and i4 %xy, %z652 %not_xyz = xor i4 %xyz, -1653 %r = or i4 %not_xyz, %x654 ret i4 %r655}656 657define i4 @simplify_or_common_op_commute1(i4 %x, i4 %y, i4 %z) {658; CHECK-LABEL: @simplify_or_common_op_commute1(659; CHECK-NEXT: ret i4 -1660;661 %xy = and i4 %y, %x662 %xyz = and i4 %xy, %z663 %not_xyz = xor i4 %xyz, -1664 %r = or i4 %not_xyz, %x665 ret i4 %r666}667 668; The common operand may bubble through multiple instructions.669 670define i4 @simplify_or_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q) {671; CHECK-LABEL: @simplify_or_common_op_commute2(672; CHECK-NEXT: ret i4 -1673;674 %z = mul i4 %p, %p ; thwart complexity-based canonicalization675 %xy = and i4 %x, %y676 %xyz = and i4 %z, %xy677 %xyzq = and i4 %xyz, %q678 %not_xyzq = xor i4 %xyzq, -1679 %r = or i4 %not_xyzq, %x680 ret i4 %r681}682 683define <2 x i4> @simplify_or_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p) {684; CHECK-LABEL: @simplify_or_common_op_commute3(685; CHECK-NEXT: ret <2 x i4> splat (i4 -1)686;687 %z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization688 %xy = and <2 x i4> %y, %x689 %xyz = and <2 x i4> %z, %xy690 %not_xyz = xor <2 x i4> %xyz, <i4 -1, i4 -1>691 %r = or <2 x i4> %x, %not_xyz692 ret <2 x i4> %r693}694 695define i4 @simplify_and_common_op_commute0(i4 %x, i4 %y, i4 %z) {696; CHECK-LABEL: @simplify_and_common_op_commute0(697; CHECK-NEXT: call void @use(i4 [[X:%.*]])698; CHECK-NEXT: ret i4 0699;700 %xy = or i4 %x, %y701 call void @use(i4 %x)702 %xyz = or i4 %xy, %z703 %not_xyz = xor i4 %xyz, -1704 %r = and i4 %not_xyz, %x705 ret i4 %r706}707 708define i4 @simplify_and_common_op_commute1(i4 %x, i4 %y, i4 %z) {709; CHECK-LABEL: @simplify_and_common_op_commute1(710; CHECK-NEXT: ret i4 0711;712 %xy = or i4 %y, %x713 %xyz = or i4 %xy, %z714 %not_xyz = xor i4 %xyz, -1715 %r = and i4 %not_xyz, %x716 ret i4 %r717}718 719; The common operand may bubble through multiple instructions.720 721define i4 @simplify_and_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q) {722; CHECK-LABEL: @simplify_and_common_op_commute2(723; CHECK-NEXT: ret i4 0724;725 %z = mul i4 %p, %p ; thwart complexity-based canonicalization726 %xy = or i4 %x, %y727 %xyz = or i4 %z, %xy728 %xyzq = or i4 %xyz, %q729 %not_xyzq = xor i4 %xyzq, -1730 %r = and i4 %not_xyzq, %x731 ret i4 %r732}733 734define <2 x i4> @simplify_and_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p) {735; CHECK-LABEL: @simplify_and_common_op_commute3(736; CHECK-NEXT: ret <2 x i4> zeroinitializer737;738 %z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization739 %xy = or <2 x i4> %y, %x740 %xyz = or <2 x i4> %z, %xy741 %not_xyz = xor <2 x i4> %xyz, <i4 -1, i4 -1>742 %r = and <2 x i4> %x, %not_xyz743 ret <2 x i4> %r744}745 746define i4 @simplify_and_common_op_use1(i4 %x, i4 %y, i4 %z) {747; CHECK-LABEL: @simplify_and_common_op_use1(748; CHECK-NEXT: call void @use(i4 [[Y:%.*]])749; CHECK-NEXT: ret i4 0750;751 %xy = or i4 %x, %y752 call void @use(i4 %y)753 %xyz = or i4 %xy, %z754 %not_xyz = xor i4 %xyz, -1755 %r = and i4 %not_xyz, %x756 ret i4 %r757}758 759; TODO: This should simplify.760 761define i4 @simplify_and_common_op_use2(i4 %x, i4 %y, i4 %z) {762; CHECK-LABEL: @simplify_and_common_op_use2(763; CHECK-NEXT: call void @use(i4 [[Y:%.*]])764; CHECK-NEXT: ret i4 0765;766 %xy = or i4 %y, %x767 call void @use(i4 %y)768 %xyz = or i4 %xy, %z769 %not_xyz = xor i4 %xyz, -1770 %r = and i4 %not_xyz, %x771 ret i4 %r772}773 774; TODO: This should simplify.775 776define i4 @simplify_and_common_op_use3(i4 %x, i4 %y, i4 %z) {777; CHECK-LABEL: @simplify_and_common_op_use3(778; CHECK-NEXT: call void @use(i4 [[Z:%.*]])779; CHECK-NEXT: ret i4 0780;781 %xy = or i4 %x, %y782 %xyz = or i4 %xy, %z783 call void @use(i4 %z)784 %not_xyz = xor i4 %xyz, -1785 %r = and i4 %not_xyz, %x786 ret i4 %r787}788 789define i4 @reduce_xor_common_op_commute0(i4 %x, i4 %y, i4 %z) {790; CHECK-LABEL: @reduce_xor_common_op_commute0(791; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[Y:%.*]], [[Z:%.*]]792; CHECK-NEXT: [[R:%.*]] = or i4 [[TMP1]], [[X:%.*]]793; CHECK-NEXT: ret i4 [[R]]794;795 %xy = xor i4 %x, %y796 %xyz = xor i4 %xy, %z797 %r = or i4 %xyz, %x798 ret i4 %r799}800 801define i4 @reduce_xor_common_op_commute1(i4 %x, i4 %y, i4 %z) {802; CHECK-LABEL: @reduce_xor_common_op_commute1(803; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[Y:%.*]], [[Z:%.*]]804; CHECK-NEXT: [[R:%.*]] = or i4 [[TMP1]], [[X:%.*]]805; CHECK-NEXT: ret i4 [[R]]806;807 %xy = xor i4 %y, %x808 %xyz = xor i4 %xy, %z809 %r = or i4 %xyz, %x810 ret i4 %r811}812 813define i4 @annihilate_xor_common_op_commute2(i4 %x, i4 %y, i4 %p, i4 %q) {814; CHECK-LABEL: @annihilate_xor_common_op_commute2(815; CHECK-NEXT: [[Z:%.*]] = mul i4 [[P:%.*]], [[P]]816; CHECK-NEXT: [[TMP1:%.*]] = xor i4 [[Y:%.*]], [[Z]]817; CHECK-NEXT: [[TMP2:%.*]] = xor i4 [[TMP1]], [[Q:%.*]]818; CHECK-NEXT: ret i4 [[TMP2]]819;820 %z = mul i4 %p, %p ; thwart complexity-based canonicalization821 %xy = xor i4 %x, %y822 %xyz = xor i4 %z, %xy823 %xyzq = xor i4 %xyz, %q824 %r = xor i4 %xyzq, %x825 ret i4 %r826}827 828define <2 x i4> @reduce_xor_common_op_commute3(<2 x i4> %x, <2 x i4> %y, <2 x i4> %p) {829; CHECK-LABEL: @reduce_xor_common_op_commute3(830; CHECK-NEXT: [[Z:%.*]] = mul <2 x i4> [[P:%.*]], [[P]]831; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i4> [[Y:%.*]], [[Z]]832; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[X:%.*]], [[TMP1]]833; CHECK-NEXT: ret <2 x i4> [[R]]834;835 %z = mul <2 x i4> %p, %p ; thwart complexity-based canonicalization836 %xy = xor <2 x i4> %y, %x837 %xyz = xor <2 x i4> %z, %xy838 %r = or <2 x i4> %x, %xyz839 ret <2 x i4> %r840}841