The xsize and ysize arguments to memrefs_conflict_p are encode such that: - 0 means the size is unknown - >0 means the size is known - <0 means that the negative of the size is a worst-case size after alignment
In other words, the sign effectively encodes a boolean; it isn't meant to be taken literally. With poly_ints these correspond to: - known_zero (...) - may_gt (..., 0) - may_lt (..., 0) respectively. 2017-10-23 Richard Sandiford <richard.sandif...@linaro.org> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> gcc/ * alias.c (addr_side_effect_eval): Take the size as a poly_int64 rather than an int. Use plus_constant. (memrefs_conflict_p): Take the sizes as poly_int64s rather than ints. Take the offset "c" as a poly_int64 rather than a HOST_WIDE_INT. Index: gcc/alias.c =================================================================== --- gcc/alias.c 2017-10-23 17:16:50.356530167 +0100 +++ gcc/alias.c 2017-10-23 17:25:47.476533124 +0100 @@ -148,7 +148,6 @@ struct GTY(()) alias_set_entry { }; static int rtx_equal_for_memref_p (const_rtx, const_rtx); -static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT); static void record_set (rtx, const_rtx, void *); static int base_alias_check (rtx, rtx, rtx, rtx, machine_mode, machine_mode); @@ -2295,9 +2294,9 @@ get_addr (rtx x) is not modified by the memory reference then ADDR is returned. */ static rtx -addr_side_effect_eval (rtx addr, int size, int n_refs) +addr_side_effect_eval (rtx addr, poly_int64 size, int n_refs) { - int offset = 0; + poly_int64 offset = 0; switch (GET_CODE (addr)) { @@ -2318,11 +2317,7 @@ addr_side_effect_eval (rtx addr, int siz return addr; } - if (offset) - addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), - gen_int_mode (offset, GET_MODE (addr))); - else - addr = XEXP (addr, 0); + addr = plus_constant (GET_MODE (addr), XEXP (addr, 0), offset); addr = canon_rtx (addr); return addr; @@ -2372,7 +2367,8 @@ offset_overlap_p (poly_int64 c, poly_int If that is fixed the TBAA hack for union type-punning can be removed. */ static int -memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c) +memrefs_conflict_p (poly_int64 xsize, rtx x, poly_int64 ysize, rtx y, + poly_int64 c) { if (GET_CODE (x) == VALUE) { @@ -2417,13 +2413,13 @@ memrefs_conflict_p (int xsize, rtx x, in else if (GET_CODE (x) == LO_SUM) x = XEXP (x, 1); else - x = addr_side_effect_eval (x, abs (xsize), 0); + x = addr_side_effect_eval (x, may_lt (xsize, 0) ? -xsize : 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, abs (ysize), 0); + y = addr_side_effect_eval (y, may_lt (ysize, 0) ? -ysize : ysize, 0); if (GET_CODE (x) == SYMBOL_REF && GET_CODE (y) == SYMBOL_REF) { @@ -2436,7 +2432,7 @@ memrefs_conflict_p (int xsize, rtx x, in through alignment adjustments (i.e., that have negative sizes), because we can't know how far they are from each other. */ - if (xsize < 0 || ysize < 0) + if (may_lt (xsize, 0) || may_lt (ysize, 0)) return -1; /* If decls are different or we know by offsets that there is no overlap, we win. */ @@ -2467,6 +2463,7 @@ memrefs_conflict_p (int xsize, rtx x, in else if (x1 == y) return memrefs_conflict_p (xsize, x0, ysize, const0_rtx, c); + poly_int64 cx1, cy1; if (GET_CODE (y) == PLUS) { /* The fact that Y is canonicalized means that this @@ -2483,22 +2480,21 @@ memrefs_conflict_p (int xsize, rtx x, in return memrefs_conflict_p (xsize, x0, ysize, y0, c); if (rtx_equal_for_memref_p (x0, y0)) return memrefs_conflict_p (xsize, x1, ysize, y1, c); - if (CONST_INT_P (x1)) + if (poly_int_rtx_p (x1, &cx1)) { - if (CONST_INT_P (y1)) + if (poly_int_rtx_p (y1, &cy1)) return memrefs_conflict_p (xsize, x0, ysize, y0, - c - INTVAL (x1) + INTVAL (y1)); + c - cx1 + cy1); else - return memrefs_conflict_p (xsize, x0, ysize, y, - c - INTVAL (x1)); + return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); } - else if (CONST_INT_P (y1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); + else if (poly_int_rtx_p (y1, &cy1)) + return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); return -1; } - else if (CONST_INT_P (x1)) - return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); + else if (poly_int_rtx_p (x1, &cx1)) + return memrefs_conflict_p (xsize, x0, ysize, y, c - cx1); } else if (GET_CODE (y) == PLUS) { @@ -2512,8 +2508,9 @@ memrefs_conflict_p (int xsize, rtx x, in if (x == y1) return memrefs_conflict_p (xsize, const0_rtx, ysize, y0, c); - if (CONST_INT_P (y1)) - return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); + poly_int64 cy1; + if (poly_int_rtx_p (y1, &cy1)) + return memrefs_conflict_p (xsize, x, ysize, y0, c + cy1); else return -1; } @@ -2537,11 +2534,11 @@ memrefs_conflict_p (int xsize, rtx x, in return offset_overlap_p (c, xsize, ysize); /* Can't properly adjust our sizes. */ - if (!CONST_INT_P (x1)) + if (!CONST_INT_P (x1) + || !can_div_trunc_p (xsize, INTVAL (x1), &xsize) + || !can_div_trunc_p (ysize, INTVAL (x1), &ysize) + || !can_div_trunc_p (c, INTVAL (x1), &c)) return -1; - xsize /= INTVAL (x1); - ysize /= INTVAL (x1); - c /= INTVAL (x1); return memrefs_conflict_p (xsize, x0, ysize, y0, c); } @@ -2562,9 +2559,9 @@ memrefs_conflict_p (int xsize, rtx x, in unsigned HOST_WIDE_INT uc = sc; if (sc < 0 && pow2_or_zerop (-uc)) { - if (xsize > 0) + if (may_gt (xsize, 0)) xsize = -xsize; - if (xsize) + if (maybe_nonzero (xsize)) xsize += sc + 1; c -= sc + 1; return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), @@ -2577,9 +2574,9 @@ memrefs_conflict_p (int xsize, rtx x, in unsigned HOST_WIDE_INT uc = sc; if (sc < 0 && pow2_or_zerop (-uc)) { - if (ysize > 0) + if (may_gt (ysize, 0)) ysize = -ysize; - if (ysize) + if (maybe_nonzero (ysize)) ysize += sc + 1; c += sc + 1; return memrefs_conflict_p (xsize, x, @@ -2589,9 +2586,10 @@ memrefs_conflict_p (int xsize, rtx x, in if (CONSTANT_P (x)) { - if (CONST_INT_P (x) && CONST_INT_P (y)) + poly_int64 cx, cy; + if (poly_int_rtx_p (x, &cx) && poly_int_rtx_p (y, &cy)) { - c += (INTVAL (y) - INTVAL (x)); + c += cy - cx; return offset_overlap_p (c, xsize, ysize); } @@ -2613,7 +2611,9 @@ memrefs_conflict_p (int xsize, rtx x, in sizes), because we can't know how far they are from each other. */ if (CONSTANT_P (y)) - return (xsize < 0 || ysize < 0 || offset_overlap_p (c, xsize, ysize)); + return (may_lt (xsize, 0) + || may_lt (ysize, 0) + || offset_overlap_p (c, xsize, ysize)); return -1; }