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

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
As for the FRE (actually SCCVN) issue, seems this affects more than
GOMP_SIMD_LANE, seems there is insufficient canonicalization of the references
performed by SCCVN, so the same references, but in slightly different form,
aren't considered the same.
Please see e.g.
struct A { float x, y; };
struct B { struct A u, v; };
void bar (struct A *);

float
f1 (struct B *x, int y)
{
  struct A p;
  p.x = 1.0f;
  p.y = 2.0f;
  struct A *q = &x[y].u;
  *q = p;
  x[y].v.x = 3.0f;
  x[y].v.y = 4.0f;
  float f = x[y].u.x + x[y].u.y + x[y].v.x + x[y].v.y;
  bar (&p);
  return f;
}

float
f2 (struct B *x, int y)
{
  struct A p;
  p.x = 1.0f;
  p.y = 2.0f;
  x[y].u = p;
  x[y].v.x = 3.0f;
  x[y].v.y = 4.0f;
  float f = x[y].u.x + x[y].u.y + x[y].v.x + x[y].v.y;
  bar (&p);
  return f;
}

float
f3 (struct B *x, int y)
{
  struct A p;
  p.x = 1.0f;
  p.y = 2.0f;
  struct A *q = &x[y].u;
  __builtin_memcpy (&q, &p.x, sizeof (float));
  __builtin_memcpy (&q->y, &p.y, sizeof (float));
  *q = p;
  x[y].v.x = 3.0f;
  x[y].v.y = 4.0f;
  float f = x[y].u.x + x[y].u.y + x[y].v.x + x[y].v.y;
  bar (&p);
  return f;
}

float
f4 (struct B *x, int y)
{
  struct A p;
  p.x = 1.0f;
  p.y = 2.0f;
  __builtin_memcpy (&x[y].u.x, &p.x, sizeof (float));
  __builtin_memcpy (&x[y].u.y, &p.y, sizeof (float));
  x[y].v.x = 3.0f;
  x[y].v.y = 4.0f;
  float f = x[y].u.x + x[y].u.y + x[y].v.x + x[y].v.y;
  bar (&p);
  return f;
}

at -O2, FRE is able to optimize f2 and f4, but not f1 and f3, despite all 4
functions doing the same thing.

Reply via email to