[llvm] r177856 - InstCombine: simplify comparisons to zero of (shl %x, Cst) or (mul %x, Cst)

Arnaud A. de Grandmaison arnaud.adegm at gmail.com
Mon Mar 25 04:31:29 PDT 2013


On 03/25/2013 11:22 AM, Duncan Sands wrote:
> Hi Arnaud,
>

Hi Duncan,

> > --- 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.
>

Fixed.

>> +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.
>

I was not aware of this invariant. I removed those cases and the tests
still passes, so the invariant seems to hold :) This does simplify the
routine.

>> +      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.

I addressed this in the rework of isSignTest.

>
>> +      // 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.

Fixed.

>
> Ciao, Duncan.
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


-- 
Arnaud A. de Grandmaison

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Address-issues-found-by-Duncan-during-post-commit-re.patch
Type: text/x-patch
Size: 4501 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130325/e974a480/attachment.bin>


More information about the llvm-commits mailing list