From 3aa035178c7bdfa0929bbb9f19ba0e8a9257cd1e Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 18 Jan 2013 10:57:36 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++++++++++ gcc/alias.c | 46 ++++++++++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e179e2929e9..6eff629fe0b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2013-01-18 Alexandre Oliva + + 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 PR rtl-optimization/52573 diff --git a/gcc/alias.c b/gcc/alias.c index 9a386dde382..f3cd014f089 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; } -- 2.30.2