diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2016-04-29 16:22:25 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2016-04-29 16:22:25 +0000 |
| commit | d5b0e54b492f2433d8ea099f5a25254465585a37 (patch) | |
| tree | 656f33f661eeb372a9eaa94ad337eb1f30bb1ffd /llvm/lib/Transforms | |
| parent | 7225cd52e70c02479ffc3bdc4dded02a688b8da4 (diff) | |
| download | bcm5719-llvm-d5b0e54b492f2433d8ea099f5a25254465585a37.tar.gz bcm5719-llvm-d5b0e54b492f2433d8ea099f5a25254465585a37.zip | |
[InstCombine] add helper function for ICmp with constant canonicalization; NFCI
As suggested in http://reviews.llvm.org/D17859 , we should enhance this
to support vectors.
llvm-svn: 268059
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 52e2229c2e5..3bfe49bbae3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3070,6 +3070,41 @@ bool InstCombiner::replacedSelectWithOperand(SelectInst *SI, return false; } +/// If we have an icmp le or icmp ge instruction with a constant operand, turn +/// it into the appropriate icmp lt or icmp gt instruction. This transform +/// allows them to be folded in visitICmpInst. +static ICmpInst *canonicalizeCmpWithConstant(ICmpInst &I, + InstCombiner::BuilderTy &Builder) { + Value *Op0 = I.getOperand(0); + Value *Op1 = I.getOperand(1); + + if (auto *Op1C = dyn_cast<ConstantInt>(Op1)) { + // For scalars, SimplifyICmpInst has already handled the edge cases for us, + // so we just assert on them. + APInt Op1Val = Op1C->getValue(); + switch (I.getPredicate()) { + case ICmpInst::ICMP_ULE: + assert(!Op1C->isMaxValue(false)); // A <=u MAX -> TRUE + return new ICmpInst(ICmpInst::ICMP_ULT, Op0, Builder.getInt(Op1Val + 1)); + case ICmpInst::ICMP_SLE: + assert(!Op1C->isMaxValue(true)); // A <=s MAX -> TRUE + return new ICmpInst(ICmpInst::ICMP_SLT, Op0, Builder.getInt(Op1Val + 1)); + case ICmpInst::ICMP_UGE: + assert(!Op1C->isMinValue(false)); // A >=u MIN -> TRUE + return new ICmpInst(ICmpInst::ICMP_UGT, Op0, Builder.getInt(Op1Val - 1)); + case ICmpInst::ICMP_SGE: + assert(!Op1C->isMinValue(true)); // A >=s MIN -> TRUE + return new ICmpInst(ICmpInst::ICMP_SGT, Op0, Builder.getInt(Op1Val - 1)); + default: + break; + } + } + + // TODO: Handle vectors. + + return nullptr; +} + Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { bool Changed = false; Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -3153,6 +3188,9 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { } } + if (ICmpInst *NewICmp = canonicalizeCmpWithConstant(I, *Builder)) + return NewICmp; + unsigned BitWidth = 0; if (Ty->isIntOrIntVectorTy()) BitWidth = Ty->getScalarSizeInBits(); @@ -3227,30 +3265,6 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { return new ICmpInst(ICmpInst::ICMP_SLE, A, B); } - // If we have an icmp le or icmp ge instruction, turn it into the - // appropriate icmp lt or icmp gt instruction. This allows us to rely on - // them being folded in the code below. The SimplifyICmpInst code has - // already handled the edge cases for us, so we just assert on them. - switch (I.getPredicate()) { - default: break; - case ICmpInst::ICMP_ULE: - assert(!CI->isMaxValue(false)); // A <=u MAX -> TRUE - return new ICmpInst(ICmpInst::ICMP_ULT, Op0, - Builder->getInt(CI->getValue()+1)); - case ICmpInst::ICMP_SLE: - assert(!CI->isMaxValue(true)); // A <=s MAX -> TRUE - return new ICmpInst(ICmpInst::ICMP_SLT, Op0, - Builder->getInt(CI->getValue()+1)); - case ICmpInst::ICMP_UGE: - assert(!CI->isMinValue(false)); // A >=u MIN -> TRUE - return new ICmpInst(ICmpInst::ICMP_UGT, Op0, - Builder->getInt(CI->getValue()-1)); - case ICmpInst::ICMP_SGE: - assert(!CI->isMinValue(true)); // A >=s MIN -> TRUE - return new ICmpInst(ICmpInst::ICMP_SGT, Op0, - Builder->getInt(CI->getValue()-1)); - } - if (I.isEquality()) { ConstantInt *CI2; if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(A))) || |

