When removing the MEM_ATTR unification hash I didn't grep for MEM_ATTR equality comares which now causes PR61672, missed optimizations at least in PRE. The following fixes that by exporting and using mem_attrs_eq_p.
Bootstrapped and tested on x86_64-unknown-linux-gnu - as this is a regression on the 4.9 branch I'd like to eventually backport this. Richard. 2014-08-05 Richard Biener <rguent...@suse.de> PR rtl-optimization/61672 * emit-rtl.h (mem_attrs_eq_p): Declare. * emit-rtl.c (mem_attrs_eq_p): Export. Handle NULL mem-attrs. * cse.c (exp_equiv_p): Use mem_attrs_eq_p. * cfgcleanup.c (merge_memattrs): Likewise. Include emit-rtl.h. Index: gcc/emit-rtl.h =================================================================== --- gcc/emit-rtl.h (revision 208113) +++ gcc/emit-rtl.h (working copy) @@ -20,6 +20,9 @@ along with GCC; see the file COPYING3. #ifndef GCC_EMIT_RTL_H #define GCC_EMIT_RTL_H +/* Return whether two MEM_ATTRs are equal. */ +bool mem_attrs_eq_p (const struct mem_attrs *, const struct mem_attrs *); + /* Set the alias set of MEM to SET. */ extern void set_mem_alias_set (rtx, alias_set_type); Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c (revision 208113) +++ gcc/emit-rtl.c (working copy) @@ -245,9 +245,13 @@ const_fixed_htab_eq (const void *x, cons /* Return true if the given memory attributes are equal. */ -static bool +bool mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q) { + if (p == q) + return true; + if (!p || !q) + return false; return (p->alias == q->alias && p->offset_known_p == q->offset_known_p && (!p->offset_known_p || p->offset == q->offset) Index: gcc/cse.c =================================================================== --- gcc/cse.c (revision 208113) +++ gcc/cse.c (working copy) @@ -2680,7 +2680,7 @@ exp_equiv_p (const_rtx x, const_rtx y, i But because really all MEM attributes should be the same for equivalent MEMs, we just use the invariant that MEMs that have the same attributes share the same mem_attrs data structure. */ - if (MEM_ATTRS (x) != MEM_ATTRS (y)) + if (!mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y))) return 0; } break; Index: gcc/cfgcleanup.c =================================================================== --- gcc/cfgcleanup.c (revision 208113) +++ gcc/cfgcleanup.c (working copy) @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. #include "df.h" #include "dce.h" #include "dbgcnt.h" +#include "emit-rtl.h" #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) @@ -882,7 +883,7 @@ merge_memattrs (rtx x, rtx y) if (GET_MODE (x) != GET_MODE (y)) return; - if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y)) + if (code == MEM && !mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y))) { if (! MEM_ATTRS (x)) MEM_ATTRS (y) = 0;