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 | cbc0161d1fd73d79b3ea751f80327ee4cc4162a1 (patch) | |
| tree | 619feb5d00416c09283cfe0f186a02847366e556 /llvm/lib/Transforms | |
| parent | 2c14b32e2b8c3658f8f4c7a302a01bae9ed324cf (diff) | |
| download | bcm5719-llvm-cbc0161d1fd73d79b3ea751f80327ee4cc4162a1.tar.gz bcm5719-llvm-cbc0161d1fd73d79b3ea751f80327ee4cc4162a1.zip | |
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
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 37 | 
1 files changed, 37 insertions, 0 deletions
| diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index f5ca6f2fc4c..b51f3ad68cb 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/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. | 

