re PR rtl-optimization/55547 (Alias analysis does not handle AND addresses correctly)
authorAlexandre Oliva <aoliva@redhat.com>
Fri, 18 Jan 2013 10:57:36 +0000 (10:57 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Fri, 18 Jan 2013 10:57:36 +0000 (10:57 +0000)
PR rtl-optimization/55547
PR rtl-optimization/53827
PR debug/53671
PR debug/49888
* alias.c (offset_overlap_p): New, factored out of...
(memrefs_conflict_p): ... this.  Use absolute sizes.  Retain
the conservative special case for symbolic constants.  Don't
adjust zero sizes on alignment.

From-SVN: r195289

gcc/ChangeLog
gcc/alias.c

index e179e2929e9c3968c63f453db41b417b72838ae3..6eff629fe0b6aa637d15766673e13a0d5ea9c06d 100644 (file)
@@ -1,3 +1,14 @@
+2013-01-18  Alexandre Oliva <aoliva@redhat.com>
+
+       PR rtl-optimization/55547
+       PR rtl-optimization/53827
+       PR debug/53671
+       PR debug/49888
+       * alias.c (offset_overlap_p): New, factored out of...
+       (memrefs_conflict_p): ... this.  Use absolute sizes.  Retain
+       the conservative special case for symbolic constants.  Don't
+       adjust zero sizes on alignment.
+
 2013-01-18  Bernd Schmidt  <bernds@codesourcery.com>
 
        PR rtl-optimization/52573
index 9a386dde3820d0a23a745749e4d66c7374f65368..f3cd014f089d09a39374b5b982d9a3b0059311bc 100644 (file)
@@ -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;
     }