Commit 3aa03517 by Alexandre Oliva Committed by Alexandre Oliva

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
parent c664546f
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> 2013-01-18 Bernd Schmidt <bernds@codesourcery.com>
PR rtl-optimization/52573 PR rtl-optimization/52573
......
...@@ -1904,6 +1904,20 @@ addr_side_effect_eval (rtx addr, int size, int n_refs) ...@@ -1904,6 +1904,20 @@ addr_side_effect_eval (rtx addr, int size, int n_refs)
return addr; 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 /* Return one if X and Y (memory addresses) reference the
same location in memory or if the references overlap. same location in memory or if the references overlap.
Return zero if they do not overlap, else return 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) ...@@ -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) else if (GET_CODE (x) == LO_SUM)
x = XEXP (x, 1); x = XEXP (x, 1);
else else
x = addr_side_effect_eval (x, xsize, 0); x = addr_side_effect_eval (x, abs (xsize), 0);
if (GET_CODE (y) == HIGH) if (GET_CODE (y) == HIGH)
y = XEXP (y, 0); y = XEXP (y, 0);
else if (GET_CODE (y) == LO_SUM) else if (GET_CODE (y) == LO_SUM)
y = XEXP (y, 1); y = XEXP (y, 1);
else 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 (rtx_equal_for_memref_p (x, y))
{ {
if (xsize <= 0 || ysize <= 0) return offset_overlap_p (c, xsize, ysize);
return 1;
if (c >= 0 && xsize > c)
return 1;
if (c < 0 && ysize+c > 0)
return 1;
return 0;
} }
/* This code used to check for conflicts involving stack references and /* 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) ...@@ -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)); x0 = canon_rtx (XEXP (x, 0));
y0 = canon_rtx (XEXP (y, 0)); y0 = canon_rtx (XEXP (y, 0));
if (rtx_equal_for_memref_p (x0, y0)) if (rtx_equal_for_memref_p (x0, y0))
return (xsize == 0 || ysize == 0 return offset_overlap_p (c, xsize, ysize);
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
/* Can't properly adjust our sizes. */ /* Can't properly adjust our sizes. */
if (!CONST_INT_P (x1)) if (!CONST_INT_P (x1))
...@@ -2093,7 +2100,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) ...@@ -2093,7 +2100,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
{ {
if (xsize > 0) if (xsize > 0)
xsize = -xsize; xsize = -xsize;
xsize += sc + 1; if (xsize)
xsize += sc + 1;
c -= sc + 1; c -= sc + 1;
return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)),
ysize, y, c); ysize, y, c);
...@@ -2107,7 +2115,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) ...@@ -2107,7 +2115,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
{ {
if (ysize > 0) if (ysize > 0)
ysize = -ysize; ysize = -ysize;
ysize += sc + 1; if (ysize)
ysize += sc + 1;
c += sc + 1; c += sc + 1;
return memrefs_conflict_p (xsize, x, return memrefs_conflict_p (xsize, x,
ysize, canon_rtx (XEXP (y, 0)), c); 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) ...@@ -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)) if (CONST_INT_P (x) && CONST_INT_P (y))
{ {
c += (INTVAL (y) - INTVAL (x)); c += (INTVAL (y) - INTVAL (x));
return (xsize <= 0 || ysize <= 0 return offset_overlap_p (c, xsize, ysize);
|| (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
} }
if (GET_CODE (x) == CONST) if (GET_CODE (x) == CONST)
...@@ -2136,10 +2144,12 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) ...@@ -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, return memrefs_conflict_p (xsize, x, ysize,
canon_rtx (XEXP (y, 0)), c); 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)) if (CONSTANT_P (y))
return (xsize <= 0 || ysize <= 0 return (xsize < 0 || ysize < 0 || offset_overlap_p (c, xsize, ysize));
|| (rtx_equal_for_memref_p (x, y)
&& ((c >= 0 && xsize > c) || (c < 0 && ysize+c > 0))));
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment