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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, reduced testcase for -O2 -fno-tree-dse is like:
struct allocation_pool_list
{
  struct allocation_pool_list *next;
};
struct et_node;
struct et_occ
{
  struct et_node *of;
  struct et_occ *parent, *prev, *next;
  int depth;
  int min;
  struct et_occ *min_occ;
};

struct et_occ *
et_new_occ (struct et_node *node)
{
  struct allocation_pool_list *p = __builtin_malloc (sizeof (struct et_occ));
  p->next = 0;
  struct et_occ *nw = (struct et_occ *)(void *)p;
  nw->of = node;
  nw->parent = 0;
  nw->prev = 0;
  nw->next = 0;
  nw->depth = 0;
  nw->min_occ = nw;
  nw->min = 0;
  return nw;
}

(the original has some inlined functions and operator new).
And the problem is that r254536 aliasing changes for some reason allow this to
be optimized as:
   p_3 = __builtin_malloc (48);
-  p_3->next = 0B;
   MEM[(struct et_occ *)p_3].of = node_5(D);
+  MEM[(struct et_occ *)p_3].min_occ = p_3;
+  p_3->next = 0B;
   MEM[(struct et_occ *)p_3].parent = 0B;
   MEM[(struct et_occ *)p_3].prev = 0B;
   MEM[(struct et_occ *)p_3].next = 0B;
-  MEM[(struct et_occ *)p_3].depth = 0;
-  MEM[(struct et_occ *)p_3].min_occ = p_3;
-  MEM[(struct et_occ *)p_3].min = 0;
+  MEM[(int *)p_3 + 32B] = 0;
which is wrong, because the p_3->next store is at the same offset/size (i.e.
must alias) as MEM[(struct et_occ *)p_3].of and by moving p_3->next = 0B;
after it the of field will not be whatever has been passed, but NULL instead.

Reply via email to