I took an attempt at addressing this through the RTL GCSE pass. This attempt
tweaks
mem_attrs_eq_p to return true if its comparing something like poly+8 and MEM
[&poly + 8].
Is this a more suitable approach?
Thanks,
Simon
+/* Return true if p and q reference the same location by the same name but
+ through VAR_DECL and MEM_REF. */
+
+static bool
+mem_locations_match_p (const struct mem_attrs *p, const struct mem_attrs *q)
+{
+ HOST_WIDE_INT var_offset;
+ tree var, memref;
+
+ if (p->expr == NULL_TREE || q->expr == NULL_TREE)
+ return false;
+
+ if (TREE_CODE (p->expr) == MEM_REF && TREE_CODE (q->expr) == VAR_DECL)
+ {
+ var = q->expr;
+ var_offset = q->offset;
+ memref = p->expr;
+ }
+ else if (TREE_CODE (q->expr) == MEM_REF && TREE_CODE (p->expr) == VAR_DECL)
+ {
+ var = p->expr;
+ var_offset = p->offset;
+ memref = q->expr;
+ }
+ else
+ return false;
+
+ if (TREE_OPERAND (TREE_OPERAND (memref, 0), 0) != var)
+ return false;
+
+ if (TREE_TYPE (TREE_TYPE (var)) != TREE_TYPE (memref))
+ return false;
+
+ tree offset = TREE_OPERAND (memref, 1);
+ if ((TREE_CODE (offset) == INTEGER_CST && tree_fits_shwi_p (offset)
+ && tree_to_shwi (offset) == var_offset)
+ || offset == NULL_TREE && var_offset == 0)
+ return true;
+
+ return false;
+
+}
+
/* Return true if the given memory attributes are equal. */
bool
@@ -254,16 +298,16 @@ mem_attrs_eq_p (const struct mem_attrs *p, const struct
mem_attrs *q)
return false;
return (p->alias == q->alias
&& p->offset_known_p == q->offset_known_p
- && (!p->offset_known_p || p->offset == q->offset)
&& p->size_known_p == q->size_known_p
&& (!p->size_known_p || p->size == q->size)
&& p->align == q->align
&& p->addrspace == q->addrspace
- && (p->expr == q->expr
- || (p->expr != NULL_TREE && q->expr != NULL_TREE
- && operand_equal_p (p->expr, q->expr, 0))));
+ && (mem_locations_match_p (p, q)
+ || (!p->offset_known_p || p->offset == q->offset)
+ && (p->expr == q->expr
+ || (p->expr != NULL_TREE && q->expr != NULL_TREE
+ && operand_equal_p (p->expr, q->expr, 0)))));
}