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

--- Comment #2 from bin.cheng <amker.cheng at gmail dot com> ---
(In reply to Oleg Endo from comment #0)
> Compiling the following as C or C++:
> 
> typedef struct
> {
>   unsigned char sprindex;
>   unsigned char y;
>   unsigned char index;
>   unsigned char attr;
>   unsigned char x;
>   unsigned short pattern;
> } oam;
> 
> extern oam OAM3[8];
> 
> int test2 (unsigned c, int r)
> {
>   for (unsigned i = 0; i < c; ++i)
>   {
>     oam* s = &(OAM3[i]);
>     if (s->attr & 0x40)
>       r += s->pattern;
>   }
>   return r;
> }
> 
> on SH (big or little endian, any CPU type) with -O2 results in the following
> wrong code:
> 
> _test2:
>         tst     r4,r4
>         bt      .L12
>         mov.l   .L14,r1
>         .align 2
> .L4:
>         mov.b   @r1,r0
>         tst     #64,r0
>         bt/s    .L3
>         mov     r1,r2
>         add     #3,r2     <<< wrong struct offset '3'
But r2 is initialized with [.L14] which is _OAM3+3, so the offset actually is 6
here, No?

>         mov.w   @r2,r2    <<< should be '3*2', i.e. '6'.
>         extu.w  r2,r2
>         add     r2,r5
> .L3:
>         dt      r4
>         bf/s    .L4
>         add     #8,r1
> .L12:
>         rts
>         mov     r5,r0
> .L15:
>         .align 2
> .L14:
>         .long   _OAM3+3
>         .size   _test2, .-_test2
>         .ident  "GCC: (GNU) 4.9.2 20140929 (prerelease)"
> 
> 
> Disabling ivopt with '-fno-ivopts' produces correct code:
> 
> _test2:
>         tst     r4,r4
>         bt      .L12
>         mov     #0,r2
>         mov.l   .L14,r3
>         .align 2
> .L4:
>         mov     r2,r1
>         shll2   r1
>         add     r1,r1
>         add     r3,r1
>         mov.b   @(3,r1),r0
>         tst     #64,r0
>         bt      .L3
>         mov.w   @(6,r1),r0    <<< correct struct offset '6'
>         extu.w  r0,r1
>         add     r1,r5
> .L3:
>         dt      r4
>         bf/s    .L4
>         add     #1,r2
> .L12:
>         rts
>         mov     r5,r0
> .L15:
>         .align 2
> .L14:
>         .long   _OAM3
>         .size   _test2, .-_test2
>         .ident  "GCC: (GNU) 4.9.2 20140929 (prerelease)"
> 
> 
> I haven't checked whether this happens on other targets, but I guess this is
> not SH specific.
> 
> This happens on the current 4.9 branch and trunk.  4.8 branch is not
> affected.

Reply via email to