diff mbox

[middle-end] : Fix PR68999, gfortran.fortran-torture/execute/save_1.f90 execution failure on alpha

Message ID CAFULd4ZV3vADYR_Y3GeuQ5LJBbPbGSo2UP9E7voyQVSVfDFUaw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Dec. 29, 2015, 9:31 a.m. UTC
On Wed, Dec 23, 2015 at 7:30 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On December 23, 2015 5:58:07 PM GMT+01:00, Uros Bizjak <ubizjak@gmail.com> wrote:
>>On Wed, Dec 23, 2015 at 2:39 PM, Richard Biener
>><richard.guenther@gmail.com> wrote:
>>> On December 23, 2015 10:39:17 AM GMT+01:00, Uros Bizjak
>><ubizjak@gmail.com> wrote:
>>>>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!
>>>
>>> Comparing offsets of different decls does not make sense.
>>
>>Uh, yes, some more eyeballing was needed, but you are right.
>>
>>Is there a way to detect aliasing in case AND addresses are involved?
>>
>>Probably we need something like in base_alias_check, where:
>
> Yeah, and in that case just give up.

As mentioned in [1], in attached v2 patch, we return "unknown" from
memrefs_conflict_p when realigned decls are processed:

@@ -2339,6 +2337,12 @@ 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);
+      /* Assume a potential overlap for symbolic addresses that went
+        through alignment adjustments (i.e., that have negative
+        sizes), because we can't know how far they are from each
+        other.  */
+      if (xsize < 0 || ysize < 0)
+       return -1;
       /* If decls are different or we know by offsets that there is no overlap,
         we win.  */
       if (!cmp || !offset_overlap_p (c, xsize, ysize))

This is the same approach as it is done at the end of memrefs_conflict_p.

We still need early return for AND addresses in base_alias_check, though.

2015-12-29  Uros Bizjak  <ubizjak@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 -1 for different decls that went through
    alignment adjustments.
    (base_alias_check): Move check for addresses with alignment ANDs
    before the call for compare_base_decls.

Patch was bootstrapped and regression tested on x86_64-linux-gnu
{,-m32} and alpha-linux-gnu native [2].

OK for mainline?

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

Uros.
diff mbox

Patch

Index: alias.c
===================================================================
--- alias.c	(revision 231971)
+++ alias.c	(working copy)
@@ -2046,8 +2046,6 @@  compare_base_decls (tree base1, tree base2)
 
   ret = symtab_node::get_create (base1)->equal_address_to
 		 (symtab_node::get_create (base2), true);
-  if (ret == 2)
-    return -1;
   return ret;
 }
 
@@ -2088,17 +2086,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
@@ -2117,6 +2104,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;
@@ -2339,6 +2337,12 @@  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);
+      /* Assume a potential overlap for symbolic addresses that went
+	 through alignment adjustments (i.e., that have negative
+	 sizes), because we can't know how far they are from each
+	 other.  */
+      if (xsize < 0 || ysize < 0)
+	return -1;
       /* If decls are different or we know by offsets that there is no overlap,
 	 we win.  */
       if (!cmp || !offset_overlap_p (c, xsize, ysize))
Index: symtab.c
===================================================================
--- symtab.c	(revision 231971)
+++ 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.  */