[llvm] r177856 - InstCombine: simplify comparisons to zero of (shl %x, Cst) or (mul %x, Cst)
Duncan Sands
baldrick at free.fr
Mon Mar 25 03:22:21 PDT 2013
Hi Arnaud,
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Mon Mar 25 04:48:49 2013
> @@ -139,6 +139,42 @@ static bool isSignBitCheck(ICmpInst::Pre
> }
> }
>
> +/// Returns true if the exploded icmp can be expressed as a comparison to zero
> +/// and update the predicate accordingly. The signedness of the comparison is
This comment is incomplete.
> +static bool isSignTest(ICmpInst::Predicate &pred, const ConstantInt *RHS) {
> + if (!ICmpInst::isSigned(pred))
> + return false;
> +
> + if (RHS->isZero())
> + return true;
> +
> + if (RHS->isOne())
> + switch (pred) {
> + case ICmpInst::ICMP_SGE:
Is this case needed? I thought instcombine normalized SGE to SGT whenever
possible. Likewise for SLE below.
> + pred = ICmpInst::ICMP_SGT;
> + return true;
> + case ICmpInst::ICMP_SLT:
> + pred = ICmpInst::ICMP_SLE;
> + return true;
> + default:
> + return false;
> + }
> +
> + if (RHS->isAllOnesValue())
> + switch (pred) {
> + case ICmpInst::ICMP_SLE:
> + pred = ICmpInst::ICMP_SLT;
> + return true;
> + case ICmpInst::ICMP_SGT:
> + pred = ICmpInst::ICMP_SGE;
> + return true;
> + default:
> + return false;
> + }
> +
> + return false;
> +}
> +
> // isHighOnes - Return true if the constant is of the form 1+0+.
> // This is the same as lowones(~X).
> static bool isHighOnes(const ConstantInt *CI) {
> @@ -1282,6 +1318,25 @@ Instruction *InstCombiner::visitICmpInst
> break;
> }
>
> + case Instruction::Mul: { // (icmp pred (mul X, Val), CI)
> + ConstantInt *Val = dyn_cast<ConstantInt>(LHSI->getOperand(1));
> + if (!Val) break;
> +
> + if (!ICI.isEquality()) {
Is this check needed? Won't the isSignTest check take care of it? If not, it
probably should.
> + // If this is a signed comparison to 0 and the mul is sign preserving,
> + // use the mul LHS operand instead.
> + ICmpInst::Predicate pred = ICI.getPredicate();
> + if (isSignTest(pred, RHS) && !Val->isZero() &&
> + cast<BinaryOperator>(LHSI)->hasNoSignedWrap())
> + return new ICmpInst(Val->isNegative() ?
> + ICmpInst::getSwappedPredicate(pred) : pred,
> + LHSI->getOperand(0),
> + Constant::getNullValue(RHS->getType()));
> + }
> +
> + break;
> + }
> +
> case Instruction::Shl: { // (icmp pred (shl X, ShAmt), CI)
> ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1));
> if (!ShAmt) break;
> @@ -1541,6 +1611,19 @@ Instruction *InstCombiner::visitICmpInst
> return new ICmpInst(pred, X, NegX);
> }
> }
> + break;
> + case Instruction::Mul:
> + if (RHSV == 0) {
> + if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
> + // The trivial case (mul X, 0) is handled by InstSimplify
> + // General case : (mul X, C) != 0 iff X != 0
> + // (mul X, C) == 0 iff X == 0
> + if (!BOC->isZero())
> + return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
> + Constant::getNullValue(RHS->getType()));
Looks like you forgot to check for nsw here.
Ciao, Duncan.
More information about the llvm-commits
mailing list