If one side of and/or is known to be 0/-1, it doesn't matter

if the other side is overdefined.

This allows us to fold conditions like:  if (X < Y || Y > Z) in some cases.

llvm-svn: 18807
This commit is contained in:
Chris Lattner 2004-12-11 23:15:19 +00:00
parent 2c14b32e2b
commit cbc0161d1f
1 changed files with 37 additions and 0 deletions

View File

@ -615,6 +615,43 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
LatticeVal &V2State = getValueState(I.getOperand(1));
if (V1State.isOverdefined() || V2State.isOverdefined()) {
// If this is an AND or OR with 0 or -1, it doesn't matter that the other
// operand is overdefined.
if (I.getOpcode() == Instruction::And || I.getOpcode() == Instruction::Or) {
LatticeVal *NonOverdefVal = 0;
if (!V1State.isOverdefined()) {
NonOverdefVal = &V1State;
} else if (!V2State.isOverdefined()) {
NonOverdefVal = &V2State;
}
if (NonOverdefVal) {
if (NonOverdefVal->isUndefined()) {
// Could annihilate value.
if (I.getOpcode() == Instruction::And)
markConstant(IV, &I, Constant::getNullValue(I.getType()));
else
markConstant(IV, &I, ConstantInt::getAllOnesValue(I.getType()));
return;
} else {
if (I.getOpcode() == Instruction::And) {
if (NonOverdefVal->getConstant()->isNullValue()) {
markConstant(IV, &I, NonOverdefVal->getConstant());
return; // X or 0 = -1
}
} else {
if (ConstantIntegral *CI =
dyn_cast<ConstantIntegral>(NonOverdefVal->getConstant()))
if (CI->isAllOnesValue()) {
markConstant(IV, &I, NonOverdefVal->getConstant());
return; // X or -1 = -1
}
}
}
}
}
// If both operands are PHI nodes, it is possible that this instruction has
// a constant value, despite the fact that the PHI node doesn't. Check for
// this condition now.