diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2013-01-18 10:57:36 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2013-01-18 10:57:36 +0000 |
commit | 3aa035178c7bdfa0929bbb9f19ba0e8a9257cd1e (patch) | |
tree | 2b024acfe15d6f6f0810bffc2284f1ac1df7c6b9 /gcc | |
parent | c664546f0e9d12d8f3249b67982e0b192e112bef (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/alias.c | 46 |
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; } |