https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89505

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2019-02-26
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
     Ever confirmed|0                           |1

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
So what happens is that this points to an aggregate with a lot of fields and
field-sensitive analysis when gathering what are restrict pointed-to's only
looks at the first field.  Thus if you'd have

struct this { int x; void *p; };

and

  _13 = &this_29(D)->nColCount;
  # _116 = PHI <_13(9), &D.857772(10)>
  _15 = *_116;

here _13 does not point to the _first_ field (note you need meaningful
fields - aka pointers - for points-to to separate fields fod analysis)
then we miss that _116 also points to the same thing as this_29.

Then you need a plain this_29 based access and a indirect ref to _13
to get things wrong.

struct S { int i; void *p; int j; };
int a;
int foo (struct S * __restrict p, int q)
{
  int *x = &p->j;
  if (q)
    x = &a;
  p->j = 1;
  *x = 2;
  return p->j;
}

shows wrong alias info:

  # PT = null { D.1921 } (nonlocal, restrict)
  struct S * restrict p_2(D) = p;
...
  <bb 4> :
  # PT = null { D.1909 D.1921 } (nonlocal, interposable)
  # x_1 = PHI <x_3(2), &a(3)>
  MEM[(struct S *)p_2(D) clique 1 base 1].j = 1;
  MEM[(int *)x_1 clique 1 base 0] = 2;
  _9 = MEM[(struct S *)p_2(D) clique 1 base 1].j;

and FRE optimizing the load.


struct S { int i; void *p; int j; };
int a;
int __attribute__((noinline))
foo (struct S * __restrict p, int q)
{
  int *x = &p->j;
  if (q)
    x = &a;
  p->j = 1;
  *x = 2;
  return p->j;
}

int main()
{
  struct S s;
  if (foo (&s, 0) != 2)
    __builtin_abort ();
  return 0;
}

Reply via email to