forked from OSchip/llvm-project
Minor cleanup, plus implement InstCombine/xor.ll:test17
llvm-svn: 9711
This commit is contained in:
parent
f6368c803c
commit
e580666532
|
@ -1001,22 +1001,36 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||||
return new SetCondInst(SCI->getInverseCondition(),
|
return new SetCondInst(SCI->getInverseCondition(),
|
||||||
SCI->getOperand(0), SCI->getOperand(1));
|
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 (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
|
||||||
if (Op0I->getOpcode() == Instruction::Add) {
|
switch (Op0I->getOpcode()) {
|
||||||
|
case Instruction::Add:
|
||||||
// ~(X-c) --> (-c-1)-X
|
// ~(X-c) --> (-c-1)-X
|
||||||
if (RHS->isAllOnesValue())
|
if (RHS->isAllOnesValue())
|
||||||
return BinaryOperator::create(Instruction::Sub,
|
return BinaryOperator::create(Instruction::Sub,
|
||||||
*-*Op0CI -
|
*-*Op0CI -
|
||||||
*ConstantInt::get(I.getType(), 1),
|
*ConstantInt::get(I.getType(), 1),
|
||||||
Op0I->getOperand(0));
|
Op0I->getOperand(0));
|
||||||
} else if (Op0I->getOpcode() == Instruction::And) {
|
break;
|
||||||
|
case Instruction::And:
|
||||||
// (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
|
// (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
|
||||||
if ((*RHS & *Op0CI)->isNullValue())
|
if ((*RHS & *Op0CI)->isNullValue())
|
||||||
return BinaryOperator::create(Instruction::Or, Op0, RHS);
|
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
|
// (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
|
||||||
if ((*RHS & *Op0CI) == RHS)
|
if ((*RHS & *Op0CI) == RHS)
|
||||||
return BinaryOperator::create(Instruction::And, Op0, ~*RHS);
|
return BinaryOperator::create(Instruction::And, Op0, ~*RHS);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue