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)))));
 }

Reply via email to