http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54089

--- Comment #18 from Oleg Endo <olegendo at gcc dot gnu.org> 2012-09-17 
23:29:52 UTC ---
Created attachment 28207
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=28207
Arithmetic right shift rework

I have tried to apply the same strategies to the arithmetic right shift
patterns as for logical right/left shift patterns.
What happens then is that combine will see arithmetic right shift patterns (for
shift amounts > 1) and will fail to convert arithmetic right shifts to logical
right shifts where it would actually be possible.  This results in bigger code
since arithmetic shifts on SH are more expensive than logical shifts.

Unfortunately, combine will only do the shift type conversion if it can combine
the logical shift with some other insn -- which is not very likely on SH. 
Thus, the logical shift is discarded.  If however, no arithmetic shift pattern
is there that matches the shift amount (which is currently the case), combine
will split out the logical shift.

Not having arithmetic right shift patterns makes it difficult to write combine
patterns for things like ... 

char test (int x)
{
  return x >> 24;
}

which ends up as:
-m4:
        mov    #-24,r1
        shad    r1,r4
        rts
        exts.b    r4,r0

-m2:
        mov.l    .L3,r1
        sts.l    pr,@-r15
        jsr    @r1
        nop
        mov
        lds.l    @r15+,pr
        rts    
        nop
.L4:
    .align 2
.L3:
    .long    ___ashiftrt_r4_24


On the other hand, the following is handled almost as expected:

unsigned char test (int a)
{
  return a >> 24;
}

-m4:
        mov    r4,r0
        shlr16    r0
        rts
        shlr8    r0

-m2:
        mov.l    .L3,r1
        sts.l    pr,@-r15
        jsr    @r1
        nop
        extu.b    r4,r0
        lds.l    @r15+,p
        rts    
        nop
.L4:
        .align 2
.L3:
        .long    ___ashiftrt_r4_24


According to my understanding, to fix those issues something like the attached
patch would be required.  However, it would also require a separate arithmetic
right shift to logical right shift conversion pass.

Reply via email to