diff options
author | Chris Lattner <sabre@nondot.org> | 2003-07-23 21:37:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-07-23 21:37:07 +0000 |
commit | eca0c5c3799ad04a0d3764b58bbdc6006aa2fb14 (patch) | |
tree | 415994bd0a6db58bdb4cf8edd73a90a0971c7065 | |
parent | ae623cb3032d841ce6f07fd5247bf13ce81b71a9 (diff) |
Remove explicit check for: not (not X) = X, it is already handled because xor is commutative
- InstCombine: (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
- InstCombine: (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7282 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 32a2d6251f..7411428f40 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -625,22 +625,28 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { if (Op0 == Op1) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - if (ConstantIntegral *Op1C = dyn_cast<ConstantIntegral>(Op1)) { + if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) { // xor X, 0 == X - if (Op1C->isNullValue()) + if (RHS->isNullValue()) return ReplaceInstUsesWith(I, Op0); - // Is this a "NOT" instruction? - if (Op1C->isAllOnesValue()) { - // xor (xor X, -1), -1 = not (not X) = X - if (Value *X = dyn_castNotVal(Op0)) - return ReplaceInstUsesWith(I, X); - + if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) { // xor (setcc A, B), true = not (setcc A, B) = setncc A, B - if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0)) - if (SCI->use_size() == 1) + if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0I)) + if (RHS == ConstantBool::True && SCI->use_size() == 1) return new SetCondInst(SCI->getInverseCondition(), SCI->getOperand(0), SCI->getOperand(1)); + + if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) + if (Op0I->getOpcode() == Instruction::And) { + // (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0 + if ((*RHS & *Op0CI)->isNullValue()) + return BinaryOperator::create(Instruction::Or, Op0, RHS); + } else if (Op0I->getOpcode() == Instruction::Or) { + // (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2 + if ((*RHS & *Op0CI) == RHS) + return BinaryOperator::create(Instruction::And, Op0, ~*RHS); + } } } |