https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63411
Bug ID: 63411 Summary: [4.9/5 regression] ivopt produces wrong struct offset Product: gcc Version: 5.0 Status: UNCONFIRMED Keywords: wrong-code Severity: critical Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Host: i686-linux-gnu Target: sh*-*-* 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' 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.