[Patch] Teach InstCombine to work with smaller legal types in icmp (shl %v, C1), C2
Arnaud A. de Grandmaison
arnaud.adegm at gmail.com
Fri Feb 15 04:14:23 PST 2013
Patch updated according to your comments. See my answers below.
On 02/14/2013 09:56 PM, Duncan Sands wrote:
> Hi Arnaud,
>
>> @@ -1331,6 +1331,24 @@ Instruction
>> *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
>> return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE :
>> ICmpInst::ICMP_EQ,
>> And, Constant::getNullValue(And->getType()));
>> }
>> +
>> + // Transform (icmp pred iM (shl iM %v, N), CI)
>> + // -> (icmp pred i(M-N) (trunc %v iM to i(N-N)), (asr CI, N))
>> + // Transform the shl to a trunc if (asr CI, N) has no loss.
>> + // This enables to get rid of the shift in favor of a trunc
>> which can be
>> + // free on the target. It has the additional benefit of
>> comparing to a
>> + // smaller constant, which will be target friendly.
>> + if (ShAmt->getZExtValue() &&
>
> you can use !ShAmt->isZero(). I don't like getZExtValue() because it
> will crash
> if the value doesn't fit in 64 bits, which is theoretically possible.
> You can
> also use !RHS->isNullValue().
Ok.
> Also, won't ShAmt->getZExtValue() crash if this
> is a vector shift?
>
ShAmt is enforced to be a ConstantInt a few lines upper, when entering
the "(icmp pred (shl X, ShAmt), CI)" case.
I am not familiar with how vector are handled; looking at the function,
nobody seems to care --- which is not an excuse :), but should be a
different patch.
It is also checked when entering the case that the ShAmt is in range,
i.e. no undefined shift can occur.
> Alternatively, you could do:
> unsigned BitWidth = RHS->getType()->getPrimitiveSizeInBits();
> unsigned Amt = ShAmt->getLimitedValue(BitWidth);
> Then use Amt rather than ShAmt->getZExtValue() everywhere. This is
> valid since
> if the shift amount is bigger than the bitwidth then the shift represents
> undefined behaviour. Maybe better is to use BitWidth-1, since that is
> still OK
> and avoids the possible DestTypeSize being zero problem described below.
ShAmt < TypeBits, so this can not happen.
>
>> + RHS->getValue().countTrailingZeros() >=
>> ShAmt->getZExtValue()) {
>
>
>> + unsigned DestTypeSize =
>> + LHSI->getType()->getPrimitiveSizeInBits() -
>> ShAmt->getZExtValue();
>
> If RHS is zero (so countTrailingZeros is equal to the bitwidth), and
> ShAmt->getZExtValue() is equal to the bitwidth, then DestTypeSize will
> be zero and you will crash below.
Can not happen (see above)
> Also, since everything so far was in
> terms of RHS, it seems odd to pass to LHSI, you could use RHS->getType().
Ok. This has been reworded.
Cheers,
--
Arnaud
>> + Type *NTy = IntegerType::get(LHSI->getContext(), DestTypeSize);
>> + Constant *NCI = ConstantExpr::getAShr(RHS, ShAmt);
>> + return new ICmpInst(ICI.getPredicate(),
>> + Builder->CreateTrunc(LHSI->getOperand(0),
>> NTy),
>> + ConstantExpr::getTrunc(NCI, NTy));
>> + }
>> +
>> break;
>> }
>>
>
> Ciao, Duncan.
--
Arnaud A. de Grandmaison
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Teach-InstCombine-to-work-with-smaller-legal-types-i.patch
Type: text/x-patch
Size: 4217 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130215/b1c2d03a/attachment.bin>
More information about the llvm-commits
mailing list