The following backports limiting match.pd recursion together with a new testcase, also applied to trunk.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. 2018-10-19 Richard Biener <rguent...@suse.de> PR middle-end/87645 Backport from mainline 2018-07-12 Richard Biener <rguent...@suse.de> * tree-ssa-sccvn.c (mprts_hook_cnt): Remove. (vn_lookup_simplify_result): Remove recursion limit applied here. (vn_nary_build_or_lookup_1): Adjust. (try_to_simplify): Likewise. * gimple-match-head.c (gimple_resimplify1): Instead apply one here. (gimple_resimplify2): Likewise. (gimple_resimplify3): Likewise. (gimple_resimplify4): Likewise. * gcc.dg/torture/pr87645.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 265312) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -1650,7 +1650,6 @@ vn_reference_lookup_or_insert_for_pieces } static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result); -static unsigned mprts_hook_cnt; /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */ @@ -1672,22 +1671,8 @@ vn_lookup_simplify_result (code_helper r ops[i] = CONSTRUCTOR_ELT (ops_[0], i)->value; } vn_nary_op_t vnresult = NULL; - tree res = vn_nary_op_lookup_pieces (length, (tree_code) rcode, - type, ops, &vnresult); - /* We can end up endlessly recursing simplifications if the lookup above - presents us with a def-use chain that mirrors the original simplification. - See PR80887 for an example. Limit successful lookup artificially - to 10 times if we are called as mprts_hook. */ - if (res - && mprts_hook - && --mprts_hook_cnt == 0) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, "Resetting mprts_hook after too many " - "invocations.\n"); - mprts_hook = NULL; - } - return res; + return vn_nary_op_lookup_pieces (length, (tree_code) rcode, + type, ops, &vnresult); } /* Return a value-number for RCODE OPS... either by looking up an existing @@ -1704,7 +1689,6 @@ vn_nary_build_or_lookup_1 (code_helper r So first simplify and lookup this expression to see if it is already available. */ mprts_hook = vn_lookup_simplify_result; - mprts_hook_cnt = 9; bool res = false; switch (TREE_CODE_LENGTH ((tree_code) rcode)) { @@ -3979,7 +3963,6 @@ try_to_simplify (gassign *stmt) /* First try constant folding based on our current lattice. */ mprts_hook = vn_lookup_simplify_result; - mprts_hook_cnt = 9; tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize); mprts_hook = NULL; if (tem Index: gcc/gimple-match-head.c =================================================================== --- gcc/gimple-match-head.c (revision 265312) +++ gcc/gimple-match-head.c (working copy) @@ -100,17 +100,34 @@ gimple_resimplify1 (gimple_seq *seq, } } + /* Limit recursion, there are cases like PR80887 and others, for + example when value-numbering presents us with unfolded expressions + that we are really not prepared to handle without eventual + oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50 + itself as available expression. */ + static unsigned depth; + if (depth > 10) + { + if (dump_file && (dump_flags & TDF_FOLDING)) + fprintf (dump_file, "Aborting expression simplification due to " + "deep recursion\n"); + return false; + } + + ++depth; code_helper res_code2; tree res_ops2[3] = {}; if (gimple_simplify (&res_code2, res_ops2, seq, valueize, *res_code, type, res_ops[0])) { + --depth; *res_code = res_code2; res_ops[0] = res_ops2[0]; res_ops[1] = res_ops2[1]; res_ops[2] = res_ops2[2]; return true; } + --depth; return false; } @@ -160,17 +177,30 @@ gimple_resimplify2 (gimple_seq *seq, canonicalized = true; } + /* Limit recursion, see gimple_resimplify1. */ + static unsigned depth; + if (depth > 10) + { + if (dump_file && (dump_flags & TDF_FOLDING)) + fprintf (dump_file, "Aborting expression simplification due to " + "deep recursion\n"); + return false; + } + + ++depth; code_helper res_code2; tree res_ops2[3] = {}; if (gimple_simplify (&res_code2, res_ops2, seq, valueize, *res_code, type, res_ops[0], res_ops[1])) { + --depth; *res_code = res_code2; res_ops[0] = res_ops2[0]; res_ops[1] = res_ops2[1]; res_ops[2] = res_ops2[2]; return true; } + --depth; return canonicalized; } @@ -219,18 +249,31 @@ gimple_resimplify3 (gimple_seq *seq, canonicalized = true; } + /* Limit recursion, see gimple_resimplify1. */ + static unsigned depth; + if (depth > 10) + { + if (dump_file && (dump_flags & TDF_FOLDING)) + fprintf (dump_file, "Aborting expression simplification due to " + "deep recursion\n"); + return false; + } + + ++depth; code_helper res_code2; tree res_ops2[3] = {}; if (gimple_simplify (&res_code2, res_ops2, seq, valueize, *res_code, type, res_ops[0], res_ops[1], res_ops[2])) { + --depth; *res_code = res_code2; res_ops[0] = res_ops2[0]; res_ops[1] = res_ops2[1]; res_ops[2] = res_ops2[2]; return true; } + --depth; return canonicalized; } Index: gcc/testsuite/gcc.dg/torture/pr87645.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr87645.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr87645.c (working copy) @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +typedef unsigned a[8]; +a b, g; +int c, d, e, f; +int h() { + unsigned i = 2; + for (; i < 8; i++) + b[i] = 0; + for (; f;) { + d = 1; + for (; d < 14; d += 3) { + e = 0; + for (; e < 8; e++) { + i = 2; + for (; i < 8; i++) + b[i] = 5 - (c - g[e] + b[i]); + } + } + } +}