On Tue, 28 Feb 2017, Richard Biener wrote: > > Bootstrap / regtest running on x86_64-unknown-linux-gnu. > > Richard.
The following is what I committed. Bootstrapped and tested on x86_64-unknown-linux-gnu. Richard. 2017-02-28 Richard Biener <rguent...@suse.de> PR tree-optimization/79740 * tree-ssa-sccvn.c (vn_nary_op_insert_into): Allow redundant inserts. (visit_nary_op): Insert the nary into the hashtable if we pattern-matched sth. * tree-ssa-pre.c (eliminate_insert): Robustify. * gcc.dg/torture/pr79740.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 245772) --- gcc/tree-ssa-sccvn.c (working copy) *************** vn_nary_op_insert_into (vn_nary_op_t vno *** 2820,2825 **** --- 2820,2834 ---- vno->hashcode = vn_nary_op_compute_hash (vno); slot = table->find_slot_with_hash (vno, vno->hashcode, INSERT); + /* While we do not want to insert things twice it's awkward to + avoid it in the case where visit_nary_op pattern-matches stuff + and ends up simplifying the replacement to itself. We then + get two inserts, one from visit_nary_op and one from + vn_nary_build_or_lookup. + So allow inserts with the same value number. */ + if (*slot && (*slot)->result == vno->result) + return *slot; + gcc_assert (!*slot); *slot = vno; *************** visit_nary_op (tree lhs, gassign *stmt) *** 3544,3550 **** result = vn_nary_build_or_lookup (NOP_EXPR, type, ops); if (result) ! return set_ssa_val_to (lhs, result); } else { --- 3553,3563 ---- result = vn_nary_build_or_lookup (NOP_EXPR, type, ops); if (result) ! { ! bool changed = set_ssa_val_to (lhs, result); ! vn_nary_op_insert_stmt (stmt, result); ! return changed; ! } } else { *************** visit_nary_op (tree lhs, gassign *stmt) *** 3555,3561 **** TREE_TYPE (lhs), ops); if (result) ! return set_ssa_val_to (lhs, result); } } } --- 3568,3578 ---- TREE_TYPE (lhs), ops); if (result) ! { ! bool changed = set_ssa_val_to (lhs, result); ! vn_nary_op_insert_stmt (stmt, result); ! return changed; ! } } } } Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 245772) --- gcc/tree-ssa-pre.c (working copy) *************** eliminate_push_avail (tree op) *** 4099,4106 **** static tree eliminate_insert (gimple_stmt_iterator *gsi, tree val) { ! gimple *stmt = gimple_seq_first_stmt (VN_INFO (val)->expr); ! if (!is_gimple_assign (stmt) || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)) && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF --- 4099,4110 ---- static tree eliminate_insert (gimple_stmt_iterator *gsi, tree val) { ! /* We can insert a sequence with a single assignment only. */ ! gimple_seq stmts = VN_INFO (val)->expr; ! if (!gimple_seq_singleton_p (stmts)) ! return NULL_TREE; ! gassign *stmt = dyn_cast <gassign *> (gimple_seq_first_stmt (stmts)); ! if (!stmt || (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)) && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF *************** eliminate_insert (gimple_stmt_iterator * *** 4116,4123 **** if (!leader) return NULL_TREE; - gimple_seq stmts = NULL; tree res; if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF) res = gimple_build (&stmts, BIT_FIELD_REF, TREE_TYPE (val), leader, --- 4120,4127 ---- if (!leader) return NULL_TREE; tree res; + stmts = NULL; if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF) res = gimple_build (&stmts, BIT_FIELD_REF, TREE_TYPE (val), leader, Index: gcc/testsuite/gcc.dg/torture/pr79740.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr79740.c (nonexistent) --- gcc/testsuite/gcc.dg/torture/pr79740.c (working copy) *************** *** 0 **** --- 1,19 ---- + /* { dg-do compile } */ + + int a; + short b; + short fn1(unsigned short p1) { return p1 << a; } + + int main() + { + short c; + int d = 4; + for (; b;) + { + c = d + 1; + fn1(c); + d = 0; + } + d++; + return 0; + }