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.