[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
This commit is contained in:
Sanjay Patel 2016-04-29 16:22:25 +00:00
parent 7225cd52e7
commit d5b0e54b49
1 changed files with 38 additions and 24 deletions

View File

@ -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))) ||