On Jan 15, 2013, Richard Henderson <r...@redhat.com> wrote: > On 01/15/2013 08:24 AM, Aldy Hernandez wrote: >> Ok, it's really an alias.c bug, but it is Alpha, and aoliva has already >> provided an unreviewed patch...
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55547 > The patch in #C4 is ok. Thanks, I'm checking it in (first patch below), but reviewing the logic that uses negative sizes, I found a number of places that should use the absolute value, and others in which being conservative about negative sizes is unnecessary (e.g., when dealing with CONST_INT addresses). That was implemented and regstrapped on x86_64-linux-gnu. Uros, would you give the second patch a spin on alpha to make sure it doesn't regress? Ok to install it?
Restore negative sizes for AND alignment From: Alexandre Oliva <aol...@redhat.com> for gcc/ChangeLog PR rtl-optimization/55547 PR rtl-optimization/53827 PR debug/53671 PR debug/49888 * alias.c (memrefs_conflict_p): Set sizes to negative after AND adjustments. --- gcc/alias.c | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-) diff --git a/gcc/alias.c b/gcc/alias.c index df328ec..9a386dd 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -2080,14 +2080,20 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) /* Deal with alignment ANDs by adjusting offset and size so as to cover the maximum range, without taking any previously known - alignment into account. */ + alignment into account. Make a size negative after such an + adjustments, so that, if we end up with e.g. two SYMBOL_REFs, we + assume a potential overlap, because they may end up in contiguous + memory locations and the stricter-alignment access may span over + part of both. */ if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))) { HOST_WIDE_INT sc = INTVAL (XEXP (x, 1)); unsigned HOST_WIDE_INT uc = sc; - if (xsize > 0 && sc < 0 && -uc == (uc & -uc)) + if (sc < 0 && -uc == (uc & -uc)) { - xsize -= sc + 1; + if (xsize > 0) + xsize = -xsize; + xsize += sc + 1; c -= sc + 1; return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c); @@ -2097,9 +2103,11 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) { HOST_WIDE_INT sc = INTVAL (XEXP (y, 1)); unsigned HOST_WIDE_INT uc = sc; - if (ysize > 0 && sc < 0 && -uc == (uc & -uc)) + if (sc < 0 && -uc == (uc & -uc)) { - ysize -= sc + 1; + if (ysize > 0) + ysize = -ysize; + ysize += sc + 1; c += sc + 1; return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c);
Be conservative about negative sizes on symbols, use abs elsewhere From: Alexandre Oliva <aol...@redhat.com> for gcc/ChangeLog PR rtl-optimization/55547 PR rtl-optimization/53827 PR debug/53671 PR debug/49888 * alias.c (memrefs_conflict_p): Use abs of sizes all over, retaining the conservative special case for symbolic constants. --- gcc/alias.c | 21 ++++++++++++--------- 1 files changed, 12 insertions(+), 9 deletions(-) diff --git a/gcc/alias.c b/gcc/alias.c index 9a386dd..d51ba09 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1976,21 +1976,21 @@ 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) + if (xsize == 0 || ysize == 0) return 1; - if (c >= 0 && xsize > c) + if (c >= 0 && abs (xsize) - c > 0) return 1; - if (c < 0 && ysize+c > 0) + if (c < 0 && abs (ysize) + c > 0) return 1; return 0; } @@ -2063,7 +2063,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) 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)); + || (c >= 0 && abs (xsize) - c > 0) + || (c < 0 && abs (ysize) + c > 0)); /* Can't properly adjust our sizes. */ if (!CONST_INT_P (x1)) @@ -2119,8 +2120,9 @@ 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 (xsize == 0 || ysize == 0 + || (c >= 0 && abs (xsize) - c > 0) + || (c < 0 && abs (ysize) + c > 0)); } if (GET_CODE (x) == CONST) @@ -2139,7 +2141,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) 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)))); + && ((c >= 0 && abs (xsize) - c > 0) + || (c < 0 && abs (ysize) + c > 0)))); return -1; }
-- Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer