diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2016-05-13 15:10:46 +0000 | 
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2016-05-13 15:10:46 +0000 | 
| commit | b79ab27853b8b4c9473005d5418895c1450c72c7 (patch) | |
| tree | 86f519ece91654d6eee5edca944c90297d4ab59f /llvm/lib | |
| parent | 8793c521bceb007921a202e670c8b4469e77a3ef (diff) | |
| download | bcm5719-llvm-b79ab27853b8b4c9473005d5418895c1450c72c7.tar.gz bcm5719-llvm-b79ab27853b8b4c9473005d5418895c1450c72c7.zip  | |
[InstCombine] canonicalize* LE/GE vector integer comparisons to LT/GT (PR26701, PR26819)
*We don't currently handle the  edge case constants (min/max values), so it's not a complete
canonicalization.
To fully solve the motivating bugs, we need to enhance this to recognize a zero vector
too because that's a ConstantAggregateZero which is a ConstantData, not a ConstantVector
or a ConstantDataVector.
Differential Revision: http://reviews.llvm.org/D17859 
llvm-svn: 269426
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 57 | 
1 files changed, 55 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 6ed94cda342..acc03e722f0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3125,11 +3125,64 @@ static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I,        assert(!Op1C->isMinValue(true));  // A >=s MIN -> TRUE        return new ICmpInst(ICmpInst::ICMP_SGT, Op0, Builder.getInt(Op1Val - 1));      default: -      break; +      return nullptr;      }    } -  // TODO: Handle vectors. +  // The usual vector types are ConstantDataVector. Exotic vector types are +  // ConstantVector. They both derive from Constant. +  if (isa<ConstantDataVector>(Op1) || isa<ConstantVector>(Op1)) { +    Constant *Op1C = cast<Constant>(Op1); +    Type *Op1Type = Op1->getType(); +    unsigned NumElts = Op1Type->getVectorNumElements(); + +    // Set the new comparison predicate and splat a vector of 1 or -1 to +    // increment or decrement the vector constants. But first, check that no +    // elements of the constant vector would overflow/underflow when we +    // increment/decrement the constants. +    // +    // TODO? If the edge cases for vectors were guaranteed to be handled as they +    // are for scalar, we could remove the min/max checks here. However, to do +    // that, we would have to use insertelement/shufflevector to replace edge +    // values. +     +    CmpInst::Predicate NewPred; +    Constant *OneOrNegOne = nullptr; +    switch (I.getPredicate()) { +    case ICmpInst::ICMP_ULE: +      for (unsigned i = 0; i != NumElts; ++i) +        if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMaxValue(false)) +          return nullptr; +      NewPred = ICmpInst::ICMP_ULT; +      OneOrNegOne = ConstantInt::get(Op1Type, 1); +      break; +    case ICmpInst::ICMP_SLE: +      for (unsigned i = 0; i != NumElts; ++i) +        if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMaxValue(true)) +          return nullptr; +      NewPred = ICmpInst::ICMP_SLT; +      OneOrNegOne = ConstantInt::get(Op1Type, 1); +      break; +    case ICmpInst::ICMP_UGE: +      for (unsigned i = 0; i != NumElts; ++i) +        if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMinValue(false)) +          return nullptr; +      NewPred = ICmpInst::ICMP_UGT; +      OneOrNegOne = ConstantInt::get(Op1Type, -1); +      break; +    case ICmpInst::ICMP_SGE: +      for (unsigned i = 0; i != NumElts; ++i) +        if (cast<ConstantInt>(Op1C->getAggregateElement(i))->isMinValue(true)) +          return nullptr; +      NewPred = ICmpInst::ICMP_SGT; +      OneOrNegOne = ConstantInt::get(Op1Type, -1); +      break; +    default: +      return nullptr; +    } + +    return new ICmpInst(NewPred, Op0, ConstantExpr::getAdd(Op1C, OneOrNegOne)); +  }    return nullptr;  }  | 

