diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-10-26 15:40:07 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-10-26 15:40:07 +0000 | 
| commit | 683eed3286ea1837f8ad8adf1229bf6294604632 (patch) | |
| tree | bf6e765664e827e3b296b9c941bf67d2ce10ea6c /llvm/lib/Transforms | |
| parent | d632f89596f77e0df731280adedf3ac7e8fd1d4f (diff) | |
| download | bcm5719-llvm-683eed3286ea1837f8ad8adf1229bf6294604632.tar.gz bcm5719-llvm-683eed3286ea1837f8ad8adf1229bf6294604632.zip | |
reapply r85085 with a bugfix to avoid infinite looping.
All of the 'demorgan' related xforms need to use 
dyn_castNotVal, not m_Not.
llvm-svn: 85119
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 55 | 
1 files changed, 47 insertions, 8 deletions
| diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 81423b740b6..a1d3c9736ef 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -631,9 +631,32 @@ static inline Value *dyn_castFNegVal(Value *V) {    return 0;  } -static inline Value *dyn_castNotVal(Value *V) { +/// isFreeToInvert - Return true if the specified value is free to invert (apply +/// ~ to).  This happens in cases where the ~ can be eliminated. +static inline bool isFreeToInvert(Value *V) { +  // ~(~(X)) -> X.    if (BinaryOperator::isNot(V)) -    return BinaryOperator::getNotArgument(V); +    return true; +   +  // Constants can be considered to be not'ed values. +  if (isa<ConstantInt>(V)) +    return true; +   +  // Compares can be inverted if they have a single use. +  if (CmpInst *CI = dyn_cast<CmpInst>(V)) +    return CI->hasOneUse(); +   +  return false; +} + +static inline Value *dyn_castNotVal(Value *V) { +  // If this is not(not(x)) don't return that this is a not: we want the two +  // not's to be folded first. +  if (BinaryOperator::isNot(V)) { +    Value *Operand = BinaryOperator::getNotArgument(V); +    if (!isFreeToInvert(Operand)) +      return Operand; +  }    // Constants can be considered to be not'ed values...    if (ConstantInt *C = dyn_cast<ConstantInt>(V)) @@ -641,6 +664,8 @@ static inline Value *dyn_castNotVal(Value *V) {    return 0;  } + +  // dyn_castFoldableMul - If this value is a multiply that can be folded into  // other computations (because it has a constant operand), return the  // non-constant operand of the multiply, and set CST to point to the multiplier. @@ -4166,7 +4191,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {        if (Instruction *CastOp = dyn_cast<Instruction>(CI->getOperand(0))) {          if ((isa<TruncInst>(CI) || isa<BitCastInst>(CI)) &&              CastOp->getNumOperands() == 2) -          if (ConstantInt *AndCI = dyn_cast<ConstantInt>(CastOp->getOperand(1))) { +          if (ConstantInt *AndCI =dyn_cast<ConstantInt>(CastOp->getOperand(1))){              if (CastOp->getOpcode() == Instruction::And) {                // Change: and (cast (and X, C1) to T), C2                // into  : and (cast X to T), trunc_or_bitcast(C1)&C2 @@ -4960,14 +4985,14 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {      if (Ret) return Ret;    } -  if (match(Op0, m_Not(m_Value(A)))) {   // ~A | Op1 +  if ((A = dyn_castNotVal(Op0))) {   // ~A | Op1      if (A == Op1)   // ~A | A == -1        return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType()));    } else {      A = 0;    }    // Note, A is still live here! -  if (match(Op1, m_Not(m_Value(B)))) {   // Op0 | ~B +  if ((B = dyn_castNotVal(Op1))) {   // Op0 | ~B      if (Op0 == B)        return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType())); @@ -5064,12 +5089,13 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {    // Is this a ~ operation?    if (Value *NotOp = dyn_castNotVal(&I)) { -    // ~(~X & Y) --> (X | ~Y) - De Morgan's Law -    // ~(~X | Y) === (X & ~Y) - De Morgan's Law      if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(NotOp)) {        if (Op0I->getOpcode() == Instruction::And ||             Op0I->getOpcode() == Instruction::Or) { -        if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands(); +        // ~(~X & Y) --> (X | ~Y) - De Morgan's Law +        // ~(~X | Y) === (X & ~Y) - De Morgan's Law +        if (dyn_castNotVal(Op0I->getOperand(1))) +          Op0I->swapOperands();          if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) {            Value *NotY =              Builder->CreateNot(Op0I->getOperand(1), @@ -5078,6 +5104,19 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {              return BinaryOperator::CreateOr(Op0NotVal, NotY);            return BinaryOperator::CreateAnd(Op0NotVal, NotY);          } +         +        // ~(X & Y) --> (~X | ~Y) - De Morgan's Law +        // ~(X | Y) === (~X & ~Y) - De Morgan's Law +        if (isFreeToInvert(Op0I->getOperand(0)) &&  +            isFreeToInvert(Op0I->getOperand(1))) { +          Value *NotX = +            Builder->CreateNot(Op0I->getOperand(0), "notlhs"); +          Value *NotY = +            Builder->CreateNot(Op0I->getOperand(1), "notrhs"); +          if (Op0I->getOpcode() == Instruction::And) +            return BinaryOperator::CreateOr(NotX, NotY); +          return BinaryOperator::CreateAnd(NotX, NotY); +        }        }      }    } | 

