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.

Reply via email to