The following limits the number of mprts_hook invocations from a single simplification in SCCVN to avoid endless recursion.
I thought a GIMPLE testcase is in order here and thus extended parsing to handle a_10 + -1 aka a_10 + _Literal (int) -1. I did so in a straight-forward way rather than simply do constexpr like simplification of the operand after _Literal (type) which in the end is going to be necessary for things like _Literal (v4si) { 1, 2, 3, 4 }. Well - one thing at a time. Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2017-06-19 Richard Biener <rguent...@suse.de> c/ * gimple-parser.c (c_parser_gimple_postfix_expression): Handle negated _Literals to parse _Literal (int) -1. * tree-ssa-sccvn.c (mprts_hook_cnt): New global. (vn_lookup_simplify_result): Allow only mprts_hook_cnt succesful simplified lookups, then reset mprts_hook. (vn_nary_build_or_lookup_1): Set mprts_hook_cnt to 9 before simplifying. (try_to_simplify): Likewise. * gcc.dg/tree-ssa/pr80887.c: New testcase. Index: gcc/c/gimple-parser.c =================================================================== *** gcc/c/gimple-parser.c (revision 249358) --- gcc/c/gimple-parser.c (working copy) *************** c_parser_gimple_postfix_expression (c_pa *** 850,856 **** } else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0) { ! /* _Literal '(' type-name ')' number */ c_parser_consume_token (parser); tree type = NULL_TREE; if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) --- 850,856 ---- } else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0) { ! /* _Literal '(' type-name ')' [ '-' ] constant */ c_parser_consume_token (parser); tree type = NULL_TREE; if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) *************** c_parser_gimple_postfix_expression (c_pa *** 862,876 **** c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } tree val = c_parser_gimple_postfix_expression (parser).value; if (! type || ! val || val == error_mark_node ! || TREE_CODE (val) != INTEGER_CST) { c_parser_error (parser, "invalid _Literal"); return expr; } expr.value = fold_convert (type, val); return expr; } --- 862,888 ---- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } + bool neg_p; + if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS))) + c_parser_consume_token (parser); tree val = c_parser_gimple_postfix_expression (parser).value; if (! type || ! val || val == error_mark_node ! || ! CONSTANT_CLASS_P (val)) { c_parser_error (parser, "invalid _Literal"); return expr; } + if (neg_p) + { + val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val); + if (! val) + { + c_parser_error (parser, "invalid _Literal"); + return expr; + } + } expr.value = fold_convert (type, val); return expr; } Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 249358) --- gcc/tree-ssa-sccvn.c (working copy) *************** vn_reference_lookup_or_insert_for_pieces *** 1639,1644 **** --- 1639,1645 ---- } 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. */ *************** vn_lookup_simplify_result (code_helper r *** 1648,1655 **** if (!rcode.is_tree_code ()) return NULL_TREE; vn_nary_op_t vnresult = NULL; ! return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode), ! (tree_code) rcode, type, ops, &vnresult); } /* Return a value-number for RCODE OPS... either by looking up an existing --- 1649,1670 ---- if (!rcode.is_tree_code ()) return NULL_TREE; vn_nary_op_t vnresult = NULL; ! tree res = vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode), ! (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 a value-number for RCODE OPS... either by looking up an existing *************** vn_nary_build_or_lookup_1 (code_helper r *** 1666,1671 **** --- 1681,1687 ---- 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)) { *************** try_to_simplify (gassign *stmt) *** 3896,3901 **** --- 3912,3918 ---- /* 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/testsuite/gcc.dg/tree-ssa/pr80887.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/pr80887.c (nonexistent) --- gcc/testsuite/gcc.dg/tree-ssa/pr80887.c (working copy) *************** *** 0 **** --- 1,32 ---- + /* { dg-do compile } */ + /* { dg-options "-fgimple -O" } */ + + int pos; + void __GIMPLE (startwith("fre")) + f() + { + unsigned int t2; + unsigned int t1; + int a; + unsigned int u; + int _1; + int _2; + int _3; + unsigned int _4; + int _5; + unsigned int _6; + + bb_2: + _1 = pos; + _2 = _1 + 1; + pos = _2; + _3 = pos; + _4 = (unsigned int) _3; + u_9 = _4 + 4294967295u; + a_10 = pos; + _5 = a_10 + _Literal (int) -1; + t1_11 = (unsigned int) _5; + _6 = (unsigned int) a_10; + t2_12 = _6 + 4294967294u; + return; + }