@@ -2365,53 +2365,48 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
23652365 {
23662366 const APInt *RHSC;
23672367 if (match (Op1, m_APInt (RHSC))) {
2368- Value *V ;
2368+ Value *X ;
23692369 const APInt *C;
2370- if (match (Op0, m_Sub (m_APInt (C), m_Value (V )))) {
2370+ if (match (Op0, m_Sub (m_APInt (C), m_Value (X )))) {
23712371 // ~(c-X) == X-c-1 == X+(-c-1)
23722372 if (RHSC->isAllOnesValue ()) {
23732373 Constant *NewC = ConstantInt::get (I.getType (), -(*C) - 1 );
2374- return BinaryOperator::CreateAdd (V , NewC);
2374+ return BinaryOperator::CreateAdd (X , NewC);
23752375 }
23762376 if (RHSC->isSignMask ()) {
23772377 // (C - X) ^ signmask -> (C + signmask - X)
23782378 Constant *NewC = ConstantInt::get (I.getType (), *C + *RHSC);
2379- return BinaryOperator::CreateSub (NewC, V );
2379+ return BinaryOperator::CreateSub (NewC, X );
23802380 }
2381- } else if (match (Op0, m_Add (m_Value (V ), m_APInt (C)))) {
2381+ } else if (match (Op0, m_Add (m_Value (X ), m_APInt (C)))) {
23822382 // ~(X-c) --> (-c-1)-X
23832383 if (RHSC->isAllOnesValue ()) {
23842384 Constant *NewC = ConstantInt::get (I.getType (), -(*C) - 1 );
2385- return BinaryOperator::CreateSub (NewC, V );
2385+ return BinaryOperator::CreateSub (NewC, X );
23862386 }
23872387 if (RHSC->isSignMask ()) {
23882388 // (X + C) ^ signmask -> (X + C + signmask)
23892389 Constant *NewC = ConstantInt::get (I.getType (), *C + *RHSC);
2390- return BinaryOperator::CreateAdd (V , NewC);
2390+ return BinaryOperator::CreateAdd (X , NewC);
23912391 }
23922392 }
2393+
2394+ // (X|C1)^C2 -> X^(C1^C2) iff X&~C1 == 0
2395+ if (match (Op0, m_Or (m_Value (X), m_APInt (C))) &&
2396+ MaskedValueIsZero (X, *C, 0 , &I)) {
2397+ Constant *NewC = ConstantInt::get (I.getType (), *C ^ *RHSC);
2398+ Worklist.Add (cast<Instruction>(Op0));
2399+ I.setOperand (0 , X);
2400+ I.setOperand (1 , NewC);
2401+ return &I;
2402+ }
23932403 }
23942404 }
23952405
23962406 if (ConstantInt *RHSC = dyn_cast<ConstantInt>(Op1)) {
23972407 if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
23982408 if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand (1 ))) {
2399- if (Op0I->getOpcode () == Instruction::Or) {
2400- // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0
2401- if (MaskedValueIsZero (Op0I->getOperand (0 ), Op0CI->getValue (),
2402- 0 , &I)) {
2403- Constant *NewRHS = ConstantExpr::getOr (Op0CI, RHSC);
2404- // Anything in both C1 and C2 is known to be zero, remove it from
2405- // NewRHS.
2406- Constant *CommonBits = ConstantExpr::getAnd (Op0CI, RHSC);
2407- NewRHS = ConstantExpr::getAnd (NewRHS,
2408- ConstantExpr::getNot (CommonBits));
2409- Worklist.Add (Op0I);
2410- I.setOperand (0 , Op0I->getOperand (0 ));
2411- I.setOperand (1 , NewRHS);
2412- return &I;
2413- }
2414- } else if (Op0I->getOpcode () == Instruction::LShr) {
2409+ if (Op0I->getOpcode () == Instruction::LShr) {
24152410 // ((X^C1) >> C2) ^ C3 -> (X>>C2) ^ ((C1>>C2)^C3)
24162411 // E1 = "X ^ C1"
24172412 BinaryOperator *E1 ;
0 commit comments