This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR55547] fix alias regression on alpha on misaligned symbols (was: Re: do you have time to review this alpha P1 patch?)


On Jan 15, 2013, Richard Henderson <rth@redhat.com> wrote:

> On 01/15/2013 08:24 AM, Aldy Hernandez wrote:
>> Ok, it's really an alias.c bug, but it is Alpha, and aoliva has already
>> provided an unreviewed patch...

>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55547

> The patch in #C4 is ok.

Thanks, I'm checking it in (first patch below), but reviewing the logic
that uses negative sizes, I found a number of places that should use the
absolute value, and others in which being conservative about negative
sizes is unnecessary (e.g., when dealing with CONST_INT addresses).
That was implemented and regstrapped on x86_64-linux-gnu.  Uros, would
you give the second patch a spin on alpha to make sure it doesn't
regress?  Ok to install it?

Restore negative sizes for AND alignment

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): Set sizes to negative after
	AND adjustments.
---

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


diff --git a/gcc/alias.c b/gcc/alias.c
index df328ec..9a386dd 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -2080,14 +2080,20 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
 
   /* Deal with alignment ANDs by adjusting offset and size so as to
      cover the maximum range, without taking any previously known
-     alignment into account.  */
+     alignment into account.  Make a size negative after such an
+     adjustments, so that, if we end up with e.g. two SYMBOL_REFs, we
+     assume a potential overlap, because they may end up in contiguous
+     memory locations and the stricter-alignment access may span over
+     part of both.  */
   if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1)))
     {
       HOST_WIDE_INT sc = INTVAL (XEXP (x, 1));
       unsigned HOST_WIDE_INT uc = sc;
-      if (xsize > 0 && sc < 0 && -uc == (uc & -uc))
+      if (sc < 0 && -uc == (uc & -uc))
 	{
-	  xsize -= sc + 1;
+	  if (xsize > 0)
+	    xsize = -xsize;
+	  xsize += sc + 1;
 	  c -= sc + 1;
 	  return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
 				     ysize, y, c);
@@ -2097,9 +2103,11 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
     {
       HOST_WIDE_INT sc = INTVAL (XEXP (y, 1));
       unsigned HOST_WIDE_INT uc = sc;
-      if (ysize > 0 && sc < 0 && -uc == (uc & -uc))
+      if (sc < 0 && -uc == (uc & -uc))
 	{
-	  ysize -= sc + 1;
+	  if (ysize > 0)
+	    ysize = -ysize;
+	  ysize += sc + 1;
 	  c += sc + 1;
 	  return memrefs_conflict_p (xsize, x,
 				     ysize, canon_rtx (XEXP (y, 0)), c);
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 |   21 ++++++++++++---------
 1 files changed, 12 insertions(+), 9 deletions(-)


diff --git a/gcc/alias.c b/gcc/alias.c
index 9a386dd..d51ba09 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1976,21 +1976,21 @@ 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)
+      if (xsize == 0 || ysize == 0)
 	return 1;
-      if (c >= 0 && xsize > c)
+      if (c >= 0 && abs (xsize) - c > 0)
 	return 1;
-      if (c < 0 && ysize+c > 0)
+      if (c < 0 && abs (ysize) + c > 0)
 	return 1;
       return 0;
     }
@@ -2063,7 +2063,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
 	  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));
+		    || (c >= 0 && abs (xsize) - c > 0)
+		    || (c < 0 && abs (ysize) + c > 0));
 
 	  /* Can't properly adjust our sizes.  */
 	  if (!CONST_INT_P (x1))
@@ -2119,8 +2120,9 @@ 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 (xsize == 0 || ysize == 0
+		  || (c >= 0 && abs (xsize) - c > 0)
+		  || (c < 0 && abs (ysize) + c > 0));
 	}
 
       if (GET_CODE (x) == CONST)
@@ -2139,7 +2141,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
       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))));
+		    && ((c >= 0 && abs (xsize) - c > 0)
+			|| (c < 0 && abs (ysize) + c > 0))));
 
       return -1;
     }

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist      Red Hat Brazil Compiler Engineer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]