Hello!

There is a logic error in Honza's patch "Transparent alias suport part
10" [1]. The part in memrefs_conflict_p should be changed to:

-      /* If decls are different or we know by offsets that there is no overlap,
- we win.  */
-      if (!cmp || !offset_overlap_p (c, xsize, ysize))
+      /* If decls are different and we know by offsets that
+ there is no overlap, we win.  */
+      if (!cmp && !offset_overlap_p (c, xsize, ysize))
  return 0;
-      /* Decls may or may not be different and offsets overlap....*/
+      /* Decls are different and offsets overlap....*/

Even if decls are different, their offsets shouldn't overlap!
Addresses with alignment ANDs depend on increased xsize and ysize, so
no wonder gcc fails to bootstrap on alpha.

In addition to this, the check for SYMBOL_REFs in base_alias_check
should be moved after checks for addresses.

The patch also adds some simplification. If
symtab_address::equal_address_to returns -1 for "unknown" (as is
otherwise customary throughout the sources), we can simplify
compare_base_decls a bit.

2015-12-23  Uros Bizjak  <ubiz...@gmail.com>

    PR middle-end/68999
    * symtab.c (symtab_node::equal_address_to): Return -1 instead of 2
    if we can't determine address equivalence.
    * alias.c (compare_base_decl): Update for changed return value of
    symtab_node::equal_address_to.
    (memrefs_conflict_p): Return 0 when decls are different
    and offsets don't overlap.
    (base_alias_check): Move check for addresses with alignment ANDs
    before the call for compare_base_decls.

The patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32} and alpha-linux-gnu [2], which is a massive user of addresses
with alignment ANDs

OK for mainline?

[1] https://gcc.gnu.org/ml/gcc-patches/2015-12/msg01076.html
[2] https://gcc.gnu.org/ml/gcc-testresults/2015-12/msg02372.html

Uros.
Index: alias.c
===================================================================
--- alias.c     (revision 231896)
+++ alias.c     (working copy)
@@ -2047,8 +2047,6 @@ compare_base_decls (tree base1, tree base2)
     return 0;
   ret = symtab_node::get_create (base1)->equal_address_to
                 (symtab_node::get_create (base2), true);
-  if (ret == 2)
-    return -1;
   return ret;
 }
 
@@ -2089,17 +2087,6 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_
   if (rtx_equal_p (x_base, y_base))
     return 1;
 
-  if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
-    {
-      tree x_decl = SYMBOL_REF_DECL (x_base);
-      tree y_decl = SYMBOL_REF_DECL (y_base);
-
-      /* We can assume that no stores are made to labels.  */
-      if (!x_decl || !y_decl)
-       return 0;
-      return compare_base_decls (x_decl, y_decl) != 0;
-    }
-
   /* The base addresses are different expressions.  If they are not accessed
      via AND, there is no conflict.  We can bring knowledge of object
      alignment into play here.  For example, on alpha, "char a, b;" can
@@ -2118,6 +2105,17 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_
          || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
     return 1;
 
+  if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
+    {
+      tree x_decl = SYMBOL_REF_DECL (x_base);
+      tree y_decl = SYMBOL_REF_DECL (y_base);
+
+      /* We can assume that no stores are made to labels.  */
+      if (!x_decl || !y_decl)
+       return 0;
+      return compare_base_decls (x_decl, y_decl) != 0;
+    }
+
   /* Differing symbols not accessed via AND never alias.  */
   if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
     return 0;
@@ -2340,11 +2338,11 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, r
       /* If both decls are the same, decide by offsets.  */
       if (cmp == 1)
         return offset_overlap_p (c, xsize, ysize);
-      /* If decls are different or we know by offsets that there is no overlap,
-        we win.  */
-      if (!cmp || !offset_overlap_p (c, xsize, ysize))
+      /* If decls are different and we know by offsets that
+        there is no overlap, we win.  */
+      if (!cmp && !offset_overlap_p (c, xsize, ysize))
        return 0;
-      /* Decls may or may not be different and offsets overlap....*/
+      /* Decls are different and offsets overlap....*/
       return -1;
     }
   else if (rtx_equal_for_memref_p (x, y))
Index: symtab.c
===================================================================
--- symtab.c    (revision 231896)
+++ symtab.c    (working copy)
@@ -1877,7 +1877,7 @@ symtab_node::nonzero_address ()
 
 /* Return 0 if symbol is known to have different address than S2,
    Return 1 if symbol is known to have same address as S2,
-   return 2 otherwise.  
+   return -1 otherwise.  
 
    If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
    and S2 is going to be accessed.  This eliminates the situations when
@@ -1941,7 +1941,7 @@ symtab_node::equal_address_to (symtab_node *s2, bo
   /* If both symbols may resolve to NULL, we can not really prove them
      different.  */
   if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ())
-    return 2;
+    return -1;
 
   /* Except for NULL, functions and variables never overlap.  */
   if (TREE_CODE (decl) != TREE_CODE (s2->decl))
@@ -1949,7 +1949,7 @@ symtab_node::equal_address_to (symtab_node *s2, bo
 
   /* If one of the symbols is unresolved alias, punt.  */
   if (rs1->alias || rs2->alias)
-    return 2;
+    return -1;
 
   /* If we have a non-interposale definition of at least one of the symbols
      and the other symbol is different, we know other unit can not interpose
@@ -1976,7 +1976,7 @@ symtab_node::equal_address_to (symtab_node *s2, bo
      We probably should be consistent and use this fact here, too, but for
      the moment return false only when we are called from the alias oracle.  */
 
-  return memory_accessed && rs1 != rs2 ? 0 : 2;
+  return memory_accessed && rs1 != rs2 ? 0 : -1;
 }
 
 /* Worker for call_for_symbol_and_aliases.  */

Reply via email to