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