Patchwork [PR55547] fix alias regression on alpha on misaligned symbols

login
register
mail settings
Submitter Alexandre Oliva
Date Jan. 17, 2013, 4:16 a.m.
Message ID <orlibs4f6y.fsf@livre.localdomain>
Download mbox | patch
Permalink /patch/213139/
State New
Headers show

Comments

Alexandre Oliva - Jan. 17, 2013, 4:16 a.m.
On Jan 16, 2013, Richard Henderson <rth@redhat.com> wrote:

> I notice that these expressions (including the first hunk that uses
> ifs) are now all the same. It would seem extremely prudent to pull
> this out to a function so that they stay the same.

Here's a revised patch that makes that change, making the overlap
computation clearer (to me) while at that.  The other fix was to avoid
adjusting zero sizes at alignment expressions, lest they'd lose the
special meaning.

Regstrapping on x86_64-linux-gnu and i686-linux-gnu.  Ok to install?
Richard Henderson - Jan. 17, 2013, 5:07 p.m.
On 2013-01-16 20:16, Alexandre Oliva wrote:
> Be conservative about negative sizes on symbols, use abs elsewhere
>
> From: Alexandre Oliva<aoliva@redhat.com>
>
> for  gcc/ChangeLog
>
> 	PR rtl-optimization/55547
> 	PR rtl-optimization/53827
> 	PR debug/53671
> 	PR debug/49888
> 	* alias.c (memrefs_conflict_p): Use abs of sizes all over,
> 	retaining the conservative special case for symbolic
> 	constants.

Ok.


r!~

Patch

Be conservative about negative sizes on symbols, use abs elsewhere

From: Alexandre Oliva <aoliva@redhat.com>

for  gcc/ChangeLog

	PR rtl-optimization/55547
	PR rtl-optimization/53827
	PR debug/53671
	PR debug/49888
	* alias.c (memrefs_conflict_p): Use abs of sizes all over,
	retaining the conservative special case for symbolic
	constants.
---

 gcc/alias.c |   46 ++++++++++++++++++++++++++++------------------
 1 files changed, 28 insertions(+), 18 deletions(-)


diff --git a/gcc/alias.c b/gcc/alias.c
index 9a386dd..f3cd014 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1904,6 +1904,20 @@  addr_side_effect_eval (rtx addr, int size, int n_refs)
   return addr;
 }
 
+/* Return TRUE if an object X sized at XSIZE bytes and another object
+   Y sized at YSIZE bytes, starting C bytes after X, may overlap.  If
+   any of the sizes is zero, assume an overlap, otherwise use the
+   absolute value of the sizes as the actual sizes.  */
+
+static inline bool
+offset_overlap_p (HOST_WIDE_INT c, int xsize, int ysize)
+{
+  return (xsize == 0 || ysize == 0
+	  || (c >= 0
+	      ? (abs (xsize) > c)
+	      : (abs (ysize) > -c)));
+}
+
 /* Return one if X and Y (memory addresses) reference the
    same location in memory or if the references overlap.
    Return zero if they do not overlap, else return
@@ -1976,23 +1990,17 @@  memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
   else if (GET_CODE (x) == LO_SUM)
     x = XEXP (x, 1);
   else
-    x = addr_side_effect_eval (x, xsize, 0);
+    x = addr_side_effect_eval (x, abs (xsize), 0);
   if (GET_CODE (y) == HIGH)
     y = XEXP (y, 0);
   else if (GET_CODE (y) == LO_SUM)
     y = XEXP (y, 1);
   else
-    y = addr_side_effect_eval (y, ysize, 0);
+    y = addr_side_effect_eval (y, abs (ysize), 0);
 
   if (rtx_equal_for_memref_p (x, y))
     {
-      if (xsize <= 0 || ysize <= 0)
-	return 1;
-      if (c >= 0 && xsize > c)
-	return 1;
-      if (c < 0 && ysize+c > 0)
-	return 1;
-      return 0;
+      return offset_overlap_p (c, xsize, ysize);
     }
 
   /* This code used to check for conflicts involving stack references and
@@ -2062,8 +2070,7 @@  memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
 	  x0 = canon_rtx (XEXP (x, 0));
 	  y0 = canon_rtx (XEXP (y, 0));
 	  if (rtx_equal_for_memref_p (x0, y0))
-	    return (xsize == 0 || ysize == 0
-		    || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
+	    return offset_overlap_p (c, xsize, ysize);
 
 	  /* Can't properly adjust our sizes.  */
 	  if (!CONST_INT_P (x1))
@@ -2093,7 +2100,8 @@  memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
 	{
 	  if (xsize > 0)
 	    xsize = -xsize;
-	  xsize += sc + 1;
+	  if (xsize)
+	    xsize += sc + 1;
 	  c -= sc + 1;
 	  return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
 				     ysize, y, c);
@@ -2107,7 +2115,8 @@  memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
 	{
 	  if (ysize > 0)
 	    ysize = -ysize;
-	  ysize += sc + 1;
+	  if (ysize)
+	    ysize += sc + 1;
 	  c += sc + 1;
 	  return memrefs_conflict_p (xsize, x,
 				     ysize, canon_rtx (XEXP (y, 0)), c);
@@ -2119,8 +2128,7 @@  memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
       if (CONST_INT_P (x) && CONST_INT_P (y))
 	{
 	  c += (INTVAL (y) - INTVAL (x));
-	  return (xsize <= 0 || ysize <= 0
-		  || (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
+	  return offset_overlap_p (c, xsize, ysize);
 	}
 
       if (GET_CODE (x) == CONST)
@@ -2136,10 +2144,12 @@  memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
 	return memrefs_conflict_p (xsize, x, ysize,
 				   canon_rtx (XEXP (y, 0)), c);
 
+      /* 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 (CONSTANT_P (y))
-	return (xsize <= 0 || ysize <= 0
-		|| (rtx_equal_for_memref_p (x, y)
-		    && ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
+	return (xsize < 0 || ysize < 0 || offset_overlap_p (c, xsize, ysize));
 
       return -1;
     }