http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52244

--- Comment #6 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-02-14 
12:10:10 UTC ---
The issue is that SRA thinks

  u.b = 1;

is

access { base = (1716)'u', offset = 0, size = 8, expr = u.b, type = _Bool, ...

note 'size = 8'.  That is what get_ref_base_and_extent says, but it in the
end boils down to the question of how we handle type precision vs. mode
precision.  For example we happily fold VIEW_CONVERT_EXPR<_Bool>(18)
to 0.  So, as SRA will create value replacements it cannot consider
u.b an access of size 8.  OTOH aliasing has to assume that a store to u.b
conflicts with any other QImode store at the same location, so it cannot
simply say "well, it's only one bit".

With a patch SRA to make SRA not assume size 8 but size 1 in this case we
generate

<bb 2>:
  u.b = 1;
  u$b_6 = MEM[(_Bool *)&1].b;
  SR.3_8 = 18;
  u = VIEW_CONVERT_EXPR<union u_t>(SR.3_8);
  u$b_9 = MEM[(union u_r *)&u].b;
  MEM[(union u_r *)&u].b = u$b_9;
  D.1729 = u;
  u ={v} {CLOBBER};
  return D.1729;

instead which happens to work (double-ugh for the MEM[(_Bool *)&1].b though,
fortunately it's unused).

With a patch that makes SRA generate replacements that cover the whole
size with their replacements we generate

foo ()
{
  unsigned char SR.3;
  <unnamed-unsigned:8> u;
  union u_t D.1741;
  union u_t u;
  union u_t D.1729;

<bb 2>:
  u_7 = 1;
  SR.3_6 = 18;
  u_2 = SR.3_6;
  MEM[(union u_r *)&D.1729] = u_2;
  return D.1729;

Another alternative would be to somehow disqualify the whole aggregate
when the situation (scalar field with size != precision and parent that
does not have all fields scalarized) happens.

I'm testing the replacement change.

Reply via email to