From 5840326ae678f5e39f8099beb22c31e8c6ecfa58 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 23 Jul 2003 19:25:52 +0000 Subject: [PATCH] - InstCombine: (X | C1) & C2 --> X & C2 iff C1 & C1 == 0 - InstCombine: (X | C) & C --> C - InstCombine: (X | C1) & C2 --> (X | (C1&C2)) & C2 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7269 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index df0b3566bee..70546612449 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -497,16 +497,39 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { if (RHS->isAllOnesValue()) return ReplaceInstUsesWith(I, Op0); - // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) - if (Instruction *Op0I = dyn_cast(Op0)) - if (Op0I->getOpcode() == Instruction::Xor && isOnlyUse(Op0)) - if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) { - std::string Op0Name = Op0I->getName(); Op0I->setName(""); - Instruction *And = BinaryOperator::create(Instruction::And, - Op0I->getOperand(0), RHS, - Op0Name); - InsertNewInstBefore(And, I); - return BinaryOperator::create(Instruction::Xor, And, *RHS & *Op0CI); + if (BinaryOperator *Op0I = dyn_cast(Op0)) + if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) + if (Op0I->getOpcode() == Instruction::Xor) { + if (isOnlyUse(Op0)) { + // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2) + std::string Op0Name = Op0I->getName(); Op0I->setName(""); + Instruction *And = BinaryOperator::create(Instruction::And, + Op0I->getOperand(0), RHS, + Op0Name); + InsertNewInstBefore(And, I); + return BinaryOperator::create(Instruction::Xor, And, *RHS & *Op0CI); + } + } else if (Op0I->getOpcode() == Instruction::Or) { + // (X | C1) & C2 --> X & C2 iff C1 & C1 == 0 + if ((*RHS & *Op0CI)->isNullValue()) + return BinaryOperator::create(Instruction::And, Op0I->getOperand(0), + RHS); + + Constant *Together = *RHS & *Op0CI; + if (Together == RHS) // (X | C) & C --> C + return ReplaceInstUsesWith(I, RHS); + + if (isOnlyUse(Op0)) { + if (Together != Op0CI) { + // (X | C1) & C2 --> (X | (C1&C2)) & C2 + std::string Op0Name = Op0I->getName(); Op0I->setName(""); + Instruction *Or = BinaryOperator::create(Instruction::Or, + Op0I->getOperand(0), + Together, Op0Name); + InsertNewInstBefore(Or, I); + return BinaryOperator::create(Instruction::And, Or, RHS); + } + } } } -- 2.34.1