[PATCH] Move transforms from InstCombine to InstSimplify
David Majnemer
david.majnemer at gmail.com
Thu Jul 11 17:49:26 PDT 2013
On Thu, Jul 11, 2013 at 3:18 PM, David Majnemer <david.majnemer at gmail.com>wrote:
> On Thu, Jul 11, 2013 at 12:49 AM, Duncan Sands <duncan.sands at gmail.com>wrote:
>
>> Hi David,
>>
>>
>> On 11/07/13 00:26, David Majnemer wrote:
>>
>>> InstCombine was pattern matching for (icmp (shl 1, X), Cst) to try to
>>> transform
>>> these icmps to true/false if we could prove that Cst must be in/out of
>>> range.
>>>
>>> However, there are two problems:
>>> 1. This sort of thing belongs in InstSimplify
>>> 2. This can be generalized further
>>>
>>> Attached is a patch that moves over these transforms to
>>> InstructionSimplify and
>>> handles arbitrary constants on the left hand side of the shift and
>>> constrains
>>> the possible range further by analyzing the nsw/nuw flags on the shift.
>>>
>>
>> --- lib/Analysis/**InstructionSimplify.cpp (revision 186043)
>>> +++ lib/Analysis/**InstructionSimplify.cpp (working copy)
>>> @@ -1995,6 +1995,27 @@
>>> Lower = IntMin.sdiv(Val);
>>> Upper = IntMax.sdiv(Val) + 1;
>>> }
>>> + } else if (match(LHS, m_Shl(m_ConstantInt(CI2), m_Value()))) {
>>> + const APInt &CI2Value = CI2->getValue();
>>> + if (cast<**OverflowingBinaryOperator>(**LHS)->hasNoUnsignedWrap())
>>> {
>>> + // 'shl nuw CI2, x' produces [CI2, CI2 << CLZ(CI2)]
>>> + Lower = CI2Value;
>>> + Upper = (CI2Value << CI2Value.countLeadingZeros()) + 1;
>>> + } else if (cast<**OverflowingBinaryOperator>(**LHS)->hasNoSignedWrap())
>>> {
>>> + if (CI2->isNegative()) {
>>> + // 'shl nsw CI2, x' [CI2 << (CLO(CI2)-1), CI2]
>>> + Lower = (CI2Value << (CI2Value.countLeadingOnes() - 1));
>>> + Upper = CI2Value + 1;
>>> + } else {
>>> + // 'shl nsw CI2, x' [CI2, CI2 << (CLZ(CI2)-1)]
>>> + Lower = CI2Value;
>>> + Upper = (CI2Value << (CI2Value.countLeadingZeros() - 1)) + 1;
>>> + }
>>>
>>
>> the cases above look OK, but
>>
>> + } else {
>>> + // 'shl CI2, x' produces [CI2, CI2 << (Width-1)]
>>> + Lower = CI2Value;
>>> + Upper = CI2Value.shl(Width - 1) + 1;
>>>
>>
>> this one seems wrong to me. Consider for example CI2 (in binary) equal to
>> 10001000
>> Then Lower=10001000, Upper=00000001, but a left-shift by 1 of CI2 is
>> 00010000 which is not in the range Lower .. Upper.
>>
>
> Thanks, I've updated the patch so that we will set Lower to zero and Upper
> to CI2 << CLZ(CI2) which is conservative but, AFAIK, correct.
>
Sorry for the noise but I was able to tighten the bounds if CI2 is a power
of two.
>
>
>>
>> Ciao, Duncan.
>> ______________________________**_________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/**mailman/listinfo/llvm-commits<http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130711/863dd3e8/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: shfcmpv3.diff
Type: application/octet-stream
Size: 5362 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130711/863dd3e8/attachment.obj>
More information about the llvm-commits
mailing list