diff options
author | Chris Lattner <sabre@nondot.org> | 2004-12-11 23:15:19 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-12-11 23:15:19 +0000 |
commit | a177c6747195f2abe5a0fc10e1a65d6c0afb85b5 (patch) | |
tree | 2143a5b9674a47f631aa7387bf1b368d08bfdde8 /lib/Transforms | |
parent | e0e50dbb9fe975b4f4b3d2eb061b2ac74a5cc7c0 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18807 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index f5ca6f2fc4..b51f3ad68c 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -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. |