diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 142ea93c657..1dca2cfb196 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-03-31 Jakub Jelinek + + 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. + 2017-03-31 Bernd Edlinger * gcov.c (md5sum_to_hex): Fix output of MD5 hex bytes. diff --git a/gcc/cselib.c b/gcc/cselib.c index a621f0da956..74c25ac1f97 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; diff --git a/gcc/cselib.h b/gcc/cselib.h index 1a8d7f25e3f..dd949196b7d 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -82,7 +82,7 @@ extern void cselib_finish (void); extern void cselib_process_insn (rtx_insn *); extern bool fp_setter_insn (rtx_insn *); extern machine_mode cselib_reg_set_mode (const_rtx); -extern int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode); +extern int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode, int); extern int references_value_p (const_rtx, int); extern rtx cselib_expand_value_rtx (rtx, bitmap, int); typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *); @@ -134,7 +134,7 @@ rtx_equal_for_cselib_p (rtx x, rtx y) if (x == y) return 1; - return rtx_equal_for_cselib_1 (x, y, VOIDmode); + return rtx_equal_for_cselib_1 (x, y, VOIDmode, 0); } #endif /* GCC_CSELIB_H */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9d15a151937..1b30193e01b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-31 Jakub Jelinek + + PR debug/80025 + * gcc.dg/torture/pr80025.c: New test. + 2017-03-30 Matthew Fortune * gcc.target/mips/pr52125.c: Add -msym32. diff --git a/gcc/testsuite/gcc.dg/torture/pr80025.c b/gcc/testsuite/gcc.dg/torture/pr80025.c new file mode 100644 index 00000000000..e53eaad6199 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr80025.c @@ -0,0 +1,24 @@ +/* PR debug/80025 */ +/* { dg-do compile } */ +/* { dg-options "-g -ftracer -w" } */ + +int a; +long int b, c; + +long int +foo (void) +{ +} + +void +bar (int x, short int y, unsigned short int z) +{ +} + +int +baz (void) +{ + a -= b; + b = !foo (); + bar (b ^= (c ^ 1) ? (c ^ 1) : foo (), (__INTPTR_TYPE__) &bar, a); +}