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

--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> ---
(In reply to Oleg Endo from comment #2)
> Interestingly, the following function shows some improved behavior (notice
> the removed volatile mem store):
> 
> int test_2_1 (int* a, int b, int c)
> {
>   a[1] = b != 0;
> 
>   if (b == 0)
>     a[10] = c;
> 
>   return b == 0;
> }
> 
> -O2 -m2a:
>         tst     r5,r5
>         movrt   r1
>         mov.l   r1,@(4,r4)
>         bf      .L4
>         mov.l   r6,@(40,r4)
> .L4:
>         rts
>         movt    r0
> 
> 
> This is already minimal.
> However, for non-SH2A it's still the same:
>         tst     r5,r5
>         mov     #-1,r1
>         negc    r1,r1
>         tst     r5,r5
>         bf/s    .L4
>         mov.l   r1,@(4,r4)
>         mov.l   r6,@(40,r4)
>         tst     r5,r5
> .L4:
>         rts
>         movt    r0

One of the problems in this case is that negc clobbers the T bit.  Another
alternative
    movt   r0
    xor    #1,r0

should be selected here.  This could be done by looking at the insns around the
negc-movrt and check whether some insn after negc-movrt sets the T bit in the
same way as it was set before the negc-movrt.  In this case not clobbering the
T bit would eliminate the redundant test.  However, if this pattern occurs in a
loop or pressure on R0 is high, using negc and the redundant test is probably
going to be better.

Reply via email to