[llvm] r268059 - [InstCombine] add helper function for ICmp with constant canonicalization; NFCI
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 29 09:22:25 PDT 2016
Author: spatel
Date: Fri Apr 29 11:22:25 2016
New Revision: 268059
URL: http://llvm.org/viewvc/llvm-project?rev=268059&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=268059&r1=268058&r2=268059&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Fri Apr 29 11:22:25 2016
@@ -3070,6 +3070,41 @@ bool InstCombiner::replacedSelectWithOpe
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
}
}
+ if (ICmpInst *NewICmp = canonicalizeCmpWithConstant(I, *Builder))
+ return NewICmp;
+
unsigned BitWidth = 0;
if (Ty->isIntOrIntVectorTy())
BitWidth = Ty->getScalarSizeInBits();
@@ -3227,30 +3265,6 @@ Instruction *InstCombiner::visitICmpInst
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))) ||
More information about the llvm-commits
mailing list