]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/alias.c
re PR middle-end/42834 (memcpy folding overeager)
[thirdparty/gcc.git] / gcc / alias.c
index 08c38bf661601af8c749d541f088ff88c9ca9f7c..30717127be235356f43e76914880ed6cbee895dc 100644 (file)
@@ -279,7 +279,8 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
 
   /* If this is a pointer dereference of a non-SSA_NAME punt.
      ???  We could replace it with a pointer to anything.  */
-  if (INDIRECT_REF_P (base)
+  if ((INDIRECT_REF_P (base)
+       || TREE_CODE (base) == MEM_REF)
       && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME)
     return false;
 
@@ -293,10 +294,7 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
       void *namep;
       namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
       if (namep)
-       {
-         ref->base_alias_set = get_alias_set (base);
-         ref->base = build1 (INDIRECT_REF, TREE_TYPE (base), *(tree *)namep);
-       }
+       ref->base = build_simple_mem_ref (*(tree *)namep);
     }
 
   ref->ref_alias_set = MEM_ALIAS_SET (mem);
@@ -648,8 +646,8 @@ get_alias_set (tree t)
     {
       tree inner;
 
-      /* Remove any nops, then give the language a chance to do
-        something with this tree before we look at it.  */
+      /* Give the language a chance to do something with this tree
+        before we look at it.  */
       STRIP_NOPS (t);
       set = lang_hooks.get_alias_set (t);
       if (set != -1)
@@ -659,21 +657,41 @@ get_alias_set (tree t)
       if (TREE_CODE (t) == TARGET_MEM_REF)
        t = TMR_ORIGINAL (t);
 
-      /* First see if the actual object referenced is an INDIRECT_REF from a
-        restrict-qualified pointer or a "void *".  */
+      /* Get the base object of the reference.  */
       inner = t;
       while (handled_component_p (inner))
        {
+         /* If there is a VIEW_CONVERT_EXPR in the chain we cannot use
+            the type of any component references that wrap it to
+            determine the alias-set.  */
+         if (TREE_CODE (inner) == VIEW_CONVERT_EXPR)
+           t = TREE_OPERAND (inner, 0);
          inner = TREE_OPERAND (inner, 0);
-         STRIP_NOPS (inner);
        }
 
+      /* Handle pointer dereferences here, they can override the
+        alias-set.  */
       if (INDIRECT_REF_P (inner))
        {
          set = get_deref_alias_set_1 (TREE_OPERAND (inner, 0));
          if (set != -1)
            return set;
        }
+      else if (TREE_CODE (inner) == MEM_REF)
+       {
+         set = get_deref_alias_set_1 (TREE_OPERAND (inner, 1));
+         if (set != -1)
+           return set;
+       }
+
+      /* If the innermost reference is a MEM_REF that has a
+        conversion embedded treat it like a VIEW_CONVERT_EXPR above,
+        using the memory access type for determining the alias-set.  */
+     if (TREE_CODE (inner) == MEM_REF
+        && (TYPE_MAIN_VARIANT (TREE_TYPE (inner))
+            != TYPE_MAIN_VARIANT
+                 (TREE_TYPE (TREE_TYPE (TREE_OPERAND (inner, 1))))))
+       return get_deref_alias_set (TREE_OPERAND (inner, 1));
 
       /* Otherwise, pick up the outermost object that we could have a pointer
         to, processing conversions as above.  */