brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.3 KiB · e06e1b1 Raw
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