http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59138
--- Comment #5 from Eric Botcazou <ebotcazou at gcc dot gnu.org> --- > Latent issue in the alias.c machinery: output_dependence returns 0 on > > (insn 21 20 22 2 (set (mem/c:DI (const:DI (plus:DI (symbol_ref:DI ("b") > [flags 0x2] <var_decl 0x7ffff6e4d2f8 b>) > (const_int 8 [0x8]))) [0 +8 S8 A64]) > (reg:DI 1 dx [99])) pr59138.c:20 85 {*movdi_internal} > (expr_list:REG_DEAD (reg:DI 1 dx [99]) > (nil))) > > (insn 22 21 23 2 (set (mem/c:HI (symbol_ref:DI ("a") [flags 0x2] <var_decl > 0x7ffff6e4d260 a>) [2 a+0 S2 A16]) > (const_int 0 [0])) pr59138.c:21 87 {*movhi_internal} > (nil)) > > because base_alias_check returns 0 for different symbols... I guess this means that we shouldn't be accessing "a" when writing to "b" in the first place, but get_best_mode decides otherwise. So this seems to be the old issue with get_best_mode, visible directly on a bitfield write: extern void abort (void); #pragma pack(1) struct S0 { int f0; int f1; long long f2 : 48; }; short a = 1; struct S0 b = { 1 }, c; long long fn1() { return c.f2; } void fn2 (void) { b.f2 = fn1 (); a = 0; } int main (void) { fn2 (); if (a != 0) abort (); return 0; } with GCC 4.6 or earlier and presumably fixed by the implementation of the new memory model.