diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-03-31 08:05:47 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-03-31 08:05:47 +0200 |
commit | 005f12bf67e60ada0757470be80fe69799a83ebc (patch) | |
tree | fed7ca22248ee3191aed93f460ee299ae4d40758 /gcc/cselib.c | |
parent | 62a767024c694e9ab52b142689180979213e9684 (diff) | |
download | gcc-005f12bf67e60ada0757470be80fe69799a83ebc.zip gcc-005f12bf67e60ada0757470be80fe69799a83ebc.tar.gz gcc-005f12bf67e60ada0757470be80fe69799a83ebc.tar.bz2 |
re PR debug/80025 (ICE w/ -O2 (-O3, -Ofast) -g -ftracer (infinite recursion in rtx_equal_for_cselib_1))
PR debug/80025
* cselib.h (rtx_equal_for_cselib_1): Add depth argument.
(rtx_equal_for_cselib_p): Pass 0 to it.
* cselib.c (cselib_hasher::equal): Likewise.
(rtx_equal_for_cselib_1): Add depth argument. If depth
is 128, don't look up VALUE locs and punt. Increment
depth in recursive calls when walking VALUE locs.
* gcc.dg/torture/pr80025.c: New test.
From-SVN: r246606
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index a621f0d..74c25ac 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -125,7 +125,7 @@ cselib_hasher::equal (const cselib_val *v, const key *x_arg) /* We don't guarantee that distinct rtx's have different hash values, so we need to do a comparison. */ for (l = v->locs; l; l = l->next) - if (rtx_equal_for_cselib_1 (l->loc, x, memmode)) + if (rtx_equal_for_cselib_1 (l->loc, x, memmode, 0)) { promote_debug_loc (l); return true; @@ -834,7 +834,7 @@ autoinc_split (rtx x, rtx *off, machine_mode memmode) addresses, MEMMODE should be VOIDmode. */ int -rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) +rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth) { enum rtx_code code; const char *fmt; @@ -867,6 +867,9 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) if (GET_CODE (y) == VALUE) return e == canonical_cselib_val (CSELIB_VAL_PTR (y)); + if (depth == 128) + return 0; + for (l = e->locs; l; l = l->next) { rtx t = l->loc; @@ -876,7 +879,7 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) list. */ if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE) continue; - else if (rtx_equal_for_cselib_1 (t, y, memmode)) + else if (rtx_equal_for_cselib_1 (t, y, memmode, depth + 1)) return 1; } @@ -887,13 +890,16 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) cselib_val *e = canonical_cselib_val (CSELIB_VAL_PTR (y)); struct elt_loc_list *l; + if (depth == 128) + return 0; + for (l = e->locs; l; l = l->next) { rtx t = l->loc; if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE) continue; - else if (rtx_equal_for_cselib_1 (x, t, memmode)) + else if (rtx_equal_for_cselib_1 (x, t, memmode, depth + 1)) return 1; } @@ -914,12 +920,12 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) if (!xoff != !yoff) return 0; - if (xoff && !rtx_equal_for_cselib_1 (xoff, yoff, memmode)) + if (xoff && !rtx_equal_for_cselib_1 (xoff, yoff, memmode, depth)) return 0; /* Don't recurse if nothing changed. */ if (x != xorig || y != yorig) - return rtx_equal_for_cselib_1 (x, y, memmode); + return rtx_equal_for_cselib_1 (x, y, memmode, depth); return 0; } @@ -953,7 +959,8 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) case MEM: /* We have to compare any autoinc operations in the addresses using this MEM's mode. */ - return rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 0), GET_MODE (x)); + return rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 0), GET_MODE (x), + depth); default: break; @@ -988,17 +995,20 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) /* And the corresponding elements must match. */ for (j = 0; j < XVECLEN (x, i); j++) if (! rtx_equal_for_cselib_1 (XVECEXP (x, i, j), - XVECEXP (y, i, j), memmode)) + XVECEXP (y, i, j), memmode, depth)) return 0; break; case 'e': if (i == 1 && targetm.commutative_p (x, UNKNOWN) - && rtx_equal_for_cselib_1 (XEXP (x, 1), XEXP (y, 0), memmode) - && rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 1), memmode)) + && rtx_equal_for_cselib_1 (XEXP (x, 1), XEXP (y, 0), memmode, + depth) + && rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 1), memmode, + depth)) return 1; - if (! rtx_equal_for_cselib_1 (XEXP (x, i), XEXP (y, i), memmode)) + if (! rtx_equal_for_cselib_1 (XEXP (x, i), XEXP (y, i), memmode, + depth)) return 0; break; |