aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2013-01-18 10:57:36 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2013-01-18 10:57:36 +0000
commit3aa035178c7bdfa0929bbb9f19ba0e8a9257cd1e (patch)
tree2b024acfe15d6f6f0810bffc2284f1ac1df7c6b9 /gcc
parentc664546f0e9d12d8f3249b67982e0b192e112bef (diff)
downloadgcc-3aa035178c7bdfa0929bbb9f19ba0e8a9257cd1e.zip
gcc-3aa035178c7bdfa0929bbb9f19ba0e8a9257cd1e.tar.gz
gcc-3aa035178c7bdfa0929bbb9f19ba0e8a9257cd1e.tar.bz2
re PR rtl-optimization/55547 (Alias analysis does not handle AND addresses correctly)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/alias.c46
2 files changed, 39 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e179e29..6eff629 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
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;
}