https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53987

--- Comment #5 from Oleg Endo <olegendo at gcc dot gnu.org> ---
(In reply to Oleg Endo from comment #4)
> It seems that converting unsigned values to signed values, i.e. replacing
> zero-extensions with sign-extensions and recombining sign-extensions with
> loads could make sense in general.
> 
> For example, the following code from CSiBE
> mpeg2dec-0.3.1/libmpeg2/motion_comp.s contains sequences like:
> 
> _MC_put_x_8_c:
>       .align 2
> .L24:
>         mov.b   @r5,r0
>         sett
>         extu.b  r0,r1
>         mov.b   @(1,r5),r0
>         extu.b  r0,r0
>         addc    r1,r0
>         shar    r0
>         mov.b   r0,@r4
>         sett
>         mov.b   @(1,r5),r0
>         extu.b  r0,r3
>         mov.b   @(2,r5),r0
>         extu.b  r0,r1
>         mov     r3,r0
>         addc    r1,r0
>         shar    r0
>         mov.b   r0,@(1,r4)
>         ....
> 
> Here effectively only 8 bit values are calculated.  The zero-extensions can
> be omitted, since the higher bits do not influence the result of the lowest
> 8 bits and the higher bits are discarded after the 8 bit stores.

Sorry, bad example.  The zero-extensions can't be emitted in this case because
of the right shift.  In the following example bits > 15 are don't care


void test_0 (unsigned short* x, int y, int z)
{
  x[11] = ((x[0] + x[1] + 1) << 1) + ((x[2] + x[3] + 1) << 2) - y;
}

.. and there are no zero-extensions in this case.  Using function arguments
instead:

void test_1 (unsigned short* x,
             unsigned short a, unsigned short b, unsigned short c,
             unsigned short d, unsigned short e)
{
  x[11] = ((a + b + 1) << 1) + ((c + d + 1) << 2) - e;
}


... brings back the zero extensions.  This is probably because of the SH ABI
(PR 52441), but in this case the extensions are really not needed.

Reply via email to