Fold (X|C1)^C2 -> X^(C1|C2) when possible. This implements
authorChris Lattner <sabre@nondot.org>
Sun, 26 Feb 2006 19:57:54 +0000 (19:57 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 26 Feb 2006 19:57:54 +0000 (19:57 +0000)
InstCombine/or.ll:test23.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26385 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index b98228c0923a2988a15504b8f155d6aa95220bb4..99677cc5de63a19b656b8ba9dc2ac7c161b29246 100644 (file)
@@ -2846,6 +2846,20 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
                                              ConstantInt::get(I.getType(), 1)),
                                           Op0I->getOperand(0));
           }
+        } else if (Op0I->getOpcode() == Instruction::Or) {
+          // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0
+          if (MaskedValueIsZero(Op0I->getOperand(0), Op0CI->getZExtValue())) {
+            Constant *NewRHS = ConstantExpr::getOr(Op0CI, RHS);
+            // Anything in both C1 and C2 is known to be zero, remove it from
+            // NewRHS.
+            Constant *CommonBits = ConstantExpr::getAnd(Op0CI, RHS);
+            NewRHS = ConstantExpr::getAnd(NewRHS, 
+                                          ConstantExpr::getNot(CommonBits));
+            WorkList.push_back(Op0I);
+            I.setOperand(0, Op0I->getOperand(0));
+            I.setOperand(1, NewRHS);
+            return &I;
+          }
         }
     }