This makes dom2 identify e.g. MEM[(int[8] *)...] with MEM[(int *)...].
These are not generally equivalent as they have different aliasing behaviour
but they have the same value as far as dom is concerned and so this helps
find more equivalences.

There is some question over the best policy here, but using the result type of
the MEM_REF seemed the most normalizing. Of course this will not catch e.g.
e.g. reading a V2SI vector from a block of memory which was written as
two separate SImode writes; but fixing that will require a much heavier-weight
approach.

gcc/ChangeLog:

        * tree-ssa-dom.c (dom_normalize_single_rhs): Add case for MEM_REFs.
---
 gcc/tree-ssa-dom.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index fca8a80..d74fb70 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1931,6 +1931,28 @@ dom_normalize_single_rhs (tree expr)
 
       return fold_build2 (MEM_REF, TREE_TYPE (expr), base, offset);
     }
+    case MEM_REF:
+    {
+      /* Make the target of the pointer equal to the result type of the 
MEM_REF.
+        (This is not generally equivalent as it has different aliasing
+        properties but has the same value and so finds more equivalences.)  */
+
+      tree off = TREE_OPERAND (expr, 1);
+
+      gcc_assert (POINTER_TYPE_P (TREE_TYPE (off)));
+      tree ptr_target_type = TREE_TYPE (TREE_TYPE (off));
+
+      if (ptr_target_type == TREE_TYPE (expr))
+       return NULL_TREE;
+
+      tree nref = copy_node (expr);
+      TREE_OPERAND (nref, 1) = copy_node (off);
+
+      TREE_TYPE (TREE_OPERAND (nref, 1)) =
+       build_pointer_type (TREE_TYPE (expr));
+
+      return nref;
+    }
     default:
       return NULL_TREE;
   }
-- 
1.9.1

Reply via email to