diff options
author | Chris Lattner <sabre@nondot.org> | 2003-09-19 15:35:42 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-09-19 15:35:42 +0000 |
commit | 9d5890d435dc902da16991ce50eb896b89e3850d (patch) | |
tree | c78dda01580703d7de8d3c04d5712f19692bc78e /lib | |
parent | b55650aad637b2cdcb727bd0047fafd392a1cc18 (diff) |
Implement InstCombine/add.ll:test(15|16)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8604 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 47e53b56f3..037b05515d 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -764,6 +764,43 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { return BinaryOperator::create(Instruction::And, Or, RHS); } } + } else if (Op0I->getOpcode() == Instruction::Add && + Op0I->use_size() == 1) { + // Adding a one to a single bit bit-field should be turned into an XOR + // of the bit. First thing to check is to see if this AND is with a + // single bit constant. + unsigned long long AndRHS = cast<ConstantInt>(RHS)->getRawValue(); + + // Clear bits that are not part of the constant. + AndRHS &= (1ULL << RHS->getType()->getPrimitiveSize()*8)-1; + + // If there is only one bit set... + if ((AndRHS & (AndRHS-1)) == 0) { + // Ok, at this point, we know that we are masking the result of the + // ADD down to exactly one bit. If the constant we are adding has + // no bits set below this bit, then we can eliminate the ADD. + unsigned long long AddRHS = cast<ConstantInt>(Op0CI)->getRawValue(); + + // Check to see if any bits below the one bit set in AndRHS are set. + if ((AddRHS & (AndRHS-1)) == 0) { + // If not, the only thing that can effect the output of the AND is + // the bit specified by AndRHS. If that bit is set, the effect of + // the XOR is to toggle the bit. If it is clear, then the ADD has + // no effect. + if ((AddRHS & AndRHS) == 0) { // Bit is not set, noop + I.setOperand(0, Op0I->getOperand(0)); + return &I; + } else { + std::string Name = Op0I->getName(); Op0I->setName(""); + // Pull the XOR out of the AND. + Instruction *NewAnd = + BinaryOperator::create(Instruction::And, Op0I->getOperand(0), + RHS, Name); + InsertNewInstBefore(NewAnd, I); + return BinaryOperator::create(Instruction::Xor, NewAnd, RHS); + } + } + } } } } |