On Wed, 20 May 2026, Xin Wang wrote: > Restructure mem_ref_hasher::equal so the non-decomposed fallback > and the decomposed comparison path are explicit. The non-decomposed > lookup still compares the original refs with operand_equal_p, while > the decomposed path keeps the same base, offset, size, max_size, > volatile, alias-set, and type checks as before. This matches the split > in gather_mem_refs_stmt, where non-decomposed references are marked > with an unknown max_size and decomposed references are hashed from > base, offset, and size.
Thanks for doing this, this is OK and I'm going to push it momentarily. Sorry for the delay, Richard. > Signed-off-by: Xin Wang <[email protected]> > --- > gcc/tree-ssa-loop-im.cc | 64 +++++++++++++++++++++++------------------ > 1 file changed, 36 insertions(+), 28 deletions(-) > > diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc > index 2651e3919e3..1e99728218f 100644 > --- a/gcc/tree-ssa-loop-im.cc > +++ b/gcc/tree-ssa-loop-im.cc > @@ -202,34 +202,43 @@ mem_ref_hasher::hash (const im_mem_ref *mem) > inline bool > mem_ref_hasher::equal (const im_mem_ref *mem1, const ao_ref *obj2) > { > - if (obj2->max_size_known_p ()) > - return (mem1->ref_decomposed > - && ((TREE_CODE (mem1->mem.base) == MEM_REF > - && TREE_CODE (obj2->base) == MEM_REF > - && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0), > - TREE_OPERAND (obj2->base, 0), 0) > - && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT + > mem1->mem.offset, > - mem_ref_offset (obj2->base) * BITS_PER_UNIT + > obj2->offset)) > - || (operand_equal_p (mem1->mem.base, obj2->base, 0) > - && known_eq (mem1->mem.offset, obj2->offset))) > - && known_eq (mem1->mem.size, obj2->size) > - && known_eq (mem1->mem.max_size, obj2->max_size) > - && mem1->mem.volatile_p == obj2->volatile_p > - && (mem1->mem.ref_alias_set == obj2->ref_alias_set > - /* We are not canonicalizing alias-sets but for the > - special-case we didn't canonicalize yet and the > - incoming ref is a alias-set zero MEM we pick > - the correct one already. */ > - || (!mem1->ref_canonical > - && (TREE_CODE (obj2->ref) == MEM_REF > - || TREE_CODE (obj2->ref) == TARGET_MEM_REF) > - && obj2->ref_alias_set == 0) > - /* Likewise if there's a canonical ref with alias-set zero. */ > - || (mem1->ref_canonical && mem1->mem.ref_alias_set == 0)) > - && types_compatible_p (TREE_TYPE (mem1->mem.ref), > - TREE_TYPE (obj2->ref))); > - else > + if (!obj2->max_size_known_p ()) > return operand_equal_p (mem1->mem.ref, obj2->ref, 0); > + > + if (!mem1->ref_decomposed) > + return false; > + > + /* obj2 is now known decomposable and the hash is based on offset, > + size and base, matching gather_mem_refs_stmt. */ > + bool refs_equal > + = ((TREE_CODE (mem1->mem.base) == MEM_REF > + && TREE_CODE (obj2->base) == MEM_REF > + && operand_equal_p (TREE_OPERAND (mem1->mem.base, 0), > + TREE_OPERAND (obj2->base, 0), 0) > + && known_eq (mem_ref_offset (mem1->mem.base) * BITS_PER_UNIT > + + mem1->mem.offset, > + mem_ref_offset (obj2->base) * BITS_PER_UNIT > + + obj2->offset)) > + || (operand_equal_p (mem1->mem.base, obj2->base, 0) > + && known_eq (mem1->mem.offset, obj2->offset))); > + > + return (refs_equal > + && known_eq (mem1->mem.size, obj2->size) > + && known_eq (mem1->mem.max_size, obj2->max_size) > + && mem1->mem.volatile_p == obj2->volatile_p > + && (mem1->mem.ref_alias_set == obj2->ref_alias_set > + /* We are not canonicalizing alias-sets but for the > + special-case we didn't canonicalize yet and the > + incoming ref is a alias-set zero MEM we pick > + the correct one already. */ > + || (!mem1->ref_canonical > + && (TREE_CODE (obj2->ref) == MEM_REF > + || TREE_CODE (obj2->ref) == TARGET_MEM_REF) > + && obj2->ref_alias_set == 0) > + /* Likewise if there's a canonical ref with alias-set zero. */ > + || (mem1->ref_canonical && mem1->mem.ref_alias_set == 0)) > + && types_compatible_p (TREE_TYPE (mem1->mem.ref), > + TREE_TYPE (obj2->ref))); > } > > > @@ -3875,4 +3884,3 @@ make_pass_lim (gcc::context *ctxt) > return new pass_lim (ctxt); > } > > - > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
