[Patch] Teach InstCombine to work with smaller legal types in icmp (shl %v, C1), C2
Arnaud A. de Grandmaison
arnaud.adegm at gmail.com
Thu Feb 14 08:19:02 PST 2013
Patch update after discussing with Duncan Sand on irc.
Cheers,
--
Arnaud de Grandmaison
On 02/14/2013 04:05 PM, Arnaud A. de Grandmaison wrote:
> Hi Duncan,
>
> On 02/14/2013 01:58 PM, Duncan Sands wrote:
>> Hi Arnaud,
>>
>> On 14/02/13 11:02, Arnaud A. de Grandmaison wrote:
>>> This patch teaches InstCombine to work with smaller legal types in icmp
>>> (shl %v, C1), C2.
>> I think it best to avoid using target information in the generic IR
>> optimizers
>> if possible. If you just drop this check, what happens if you
>> truncate to a
>> type that is too small for the target? I suspect the type legalizer
>> will fix it
>> up in a reasonable way.
>>
> I dropped the target information, and this makes this patch kick in the
> InstCombine/exact.ll testcase : Instcombine will converge to the same
> result, but following different combining steps, so the intermediate
> names had to be changed. Beside, dropping the target information
> simplifies the patch.
>
>>> Using smaller constants is target friendly, at least for those which can
>>> compare to immediate. It also avoids inserting a shift in favor of a
>>> trunc, which can be free on those targets where we are using a legal
>>> type.
>>>
>>> This used to work up to LLVM-3.1, but regressed with the 3.2 release.
>>>
>>> This pattern can occur frequently because of the integer promotion rules
>>> in C/C++ code, which will generate "icmp (sext(trunc %v)), constant".
>>> With 3.2, the sext(trunc) is combined to shifts by visitSExt, before the
>>> icmp combining has a chance to kick in. When it kicks in, it faces a
>>> pattern which is not recognized.
>>>
>>> Any comments or ok to commit ?
>> At a glance it looks like it is only correct for signed comparisons
>> and may
>> give wrong results for unsigned comparisons.
>>
> I do not get this one. The constant I compare to is checked for bits'
> loss, and there is no information loss for the shifted variable ---
> unless I am mistaken.
>
> Thanks for the comments,
> --
> Arnaud
>
>> Ciao, Duncan.
>>
>>> I found it with the following testcase :
>>>
>>> $ cat testcase.c
>>> #include <stdint.h>
>>>
>>> uint16_t
>>> sw_modulo (uint16_t val)
>>> {
>>> uint16_t start = 0;
>>> uint16_t end = 349;
>>> int16_t res = 0;
>>>
>>> do {
>>> uint16_t cpt_i = (start + end)/2;
>>> res = val - cpt_i*36;
>>>
>>> if (res < 0)
>>> end = cpt_i - 1;
>>> else
>>> start = cpt_i + 1;
>>>
>>> } while ( (res >= 36) || (res < 0) );
>>>
>>> return res;
>>> }
>>>
>>>
>>> Without the patch, the X86_64 loop code looks like :
>>> ...
>>> .LBB0_2: # %.thread
>>> addl $65535, %edx # imm = 0xFFFF
>>> movzwl %dx, %r8d
>>> .align 16, 0x90
>>> .LBB0_1: # %.critedge
>>> movzwl %cx, %edx
>>> addl %r8d, %edx
>>> shrl %edx
>>> movzwl %dx, %eax
>>> imull $-36, %eax, %eax
>>> addl %edi, %eax
>>> movl %eax, %esi
>>> shll $16, %esi
>>> testl %esi, %esi
>>> js .LBB0_2
>>> incl %edx
>>> cmpl $2293760, %esi # imm = 0x230000
>>> movw %dx, %cx
>>> ja .LBB0_1
>>> ...
>>>
>>> With the patch:
>>> ...
>>> .LBB0_2: # %.thread
>>> addl $65535, %edx # imm = 0xFFFF
>>> movzwl %dx, %eax
>>> .align 16, 0x90
>>> .LBB0_1: # %.critedge
>>> movzwl %cx, %edx
>>> addl %eax, %edx
>>> shrl %edx
>>> imull $-36, %edx, %esi
>>> addl %edi, %esi
>>> testw %si, %si
>>> js .LBB0_2
>>> incl %edx
>>> cmpw $35, %si
>>> movw %dx, %cx
>>> ja .LBB0_1
>>> ...
>>>
>>> Cheers,
>>>
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>
>> _______________________________________________
>> 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-Teach-InstCombine-to-work-with-smaller-legal-types-i.patch
Type: text/x-patch
Size: 4322 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130214/3b870971/attachment.bin>
More information about the llvm-commits
mailing list