brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.9 KiB · 641f32c Raw
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