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.