aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-11-04 23:50:51 +0000
committerChris Lattner <sabre@nondot.org>2003-11-04 23:50:51 +0000
commitad5b4fb6b73990bfab5f84fe08c6f262c39f10bb (patch)
tree16286506adf48b94ca8659f842357ada365502c4 /lib/Transforms/Scalar
parent519c6965f5bfe025634a7859ff8e609ef9836bb0 (diff)
downloadexternal_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.cpp20
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;
}
}
}