diff options
author | Chris Lattner <sabre@nondot.org> | 2003-11-04 23:50:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-11-04 23:50:51 +0000 |
commit | ad5b4fb6b73990bfab5f84fe08c6f262c39f10bb (patch) | |
tree | 16286506adf48b94ca8659f842357ada365502c4 /lib/Transforms/Scalar | |
parent | 519c6965f5bfe025634a7859ff8e609ef9836bb0 (diff) | |
download | external_llvm-ad5b4fb6b73990bfab5f84fe08c6f262c39f10bb.zip external_llvm-ad5b4fb6b73990bfab5f84fe08c6f262c39f10bb.tar.gz external_llvm-ad5b4fb6b73990bfab5f84fe08c6f262c39f10bb.tar.bz2 |
Minor cleanup, plus implement InstCombine/xor.ll:test17
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9711 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 88026c3..dafd756 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1000,23 +1000,37 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { if (RHS == ConstantBool::True && SCI->hasOneUse()) return new SetCondInst(SCI->getInverseCondition(), SCI->getOperand(0), SCI->getOperand(1)); + + // ~(c-X) == X-(c-1) == X+(-c+1) + if (Op0I->getOpcode() == Instruction::Sub && RHS->isAllOnesValue() && + isa<Constant>(Op0I->getOperand(0))) { + Constant *ConstantRHS = *-*cast<Constant>(Op0I->getOperand(0)) + + *ConstantInt::get(I.getType(), 1); + return BinaryOperator::create(Instruction::Add, Op0I->getOperand(1), + ConstantRHS); + } if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) - if (Op0I->getOpcode() == Instruction::Add) { + switch (Op0I->getOpcode()) { + case Instruction::Add: // ~(X-c) --> (-c-1)-X if (RHS->isAllOnesValue()) return BinaryOperator::create(Instruction::Sub, *-*Op0CI - *ConstantInt::get(I.getType(), 1), Op0I->getOperand(0)); - } else if (Op0I->getOpcode() == Instruction::And) { + break; + case 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) { + break; + case Instruction::Or: // (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2 if ((*RHS & *Op0CI) == RHS) return BinaryOperator::create(Instruction::And, Op0, ~*RHS); + break; + default: break; } } } |