diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 28 | 
1 files changed, 28 insertions, 0 deletions
| diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index e8f52d11573..948eb329040 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2219,6 +2219,8 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,      if (AllZeros)        return FoldGEPSetCC(GEPRHS, GEPLHS->getOperand(0),                            SetCondInst::getSwappedCondition(Cond), I); + +    // If the other GEP has all zero indices, recurse.      AllZeros = true;      for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i)        if (!isa<Constant>(GEPRHS->getOperand(i)) || @@ -2229,6 +2231,32 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,      if (AllZeros)        return FoldGEPSetCC(GEPLHS, GEPRHS->getOperand(0), Cond, I); +    if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands()) { +      // If the GEPs only differ by one index, compare it. +      unsigned NumDifferences = 0;  // Keep track of # differences. +      unsigned DiffOperand = 0;     // The operand that differs. +      for (unsigned i = 1, e = GEPRHS->getNumOperands(); i != e; ++i) +        if (GEPLHS->getOperand(i) != GEPRHS->getOperand(i)) { +          if (GEPLHS->getOperand(i)->getType() !=  +                     GEPRHS->getOperand(i)->getType()) { +            // Irreconsilable differences. +            NumDifferences = 2; +            break; +          } else { +            if (NumDifferences++) break; +            DiffOperand = i; +          } +        } + +      if (NumDifferences == 0)   // SAME GEP? +        return ReplaceInstUsesWith(I, // No comparison is needed here. +                                 ConstantBool::get(Cond == Instruction::SetEQ)); +      else if (NumDifferences == 1) { +        return new SetCondInst(Cond, GEPLHS->getOperand(DiffOperand), +                               GEPRHS->getOperand(DiffOperand)); +      } +    } +      // Only lower this if the setcc is the only user of the GEP or if we expect      // the result to fold to a constant!      if ((isa<ConstantExpr>(GEPLHS) || GEPLHS->hasOneUse()) && | 

