Hi! Various places check that (ab) SSA_NAMEs that weren't referenced on a stmt before don't appear on it, but all the checking is done on the gimple tuple operands, while in this case it is added to operands of a comparison of COND_EXPR/VEC_COND_EXPR. The following patch fixes it, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2016-01-07 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/69167 * gimple-match-head.c (gimple_simplify) <case GIMPLE_TERNARY_RHS>: Don't simplify condition if the condition simplification would introduce use of SSA_NAME_OCCURS_IN_ABNORMAL_PHI SSA_NAME not previously mentioned on the insn. * gimple-fold.h (has_use_on_stmt): New prototype. * gimple-fold.c (has_use_on_stmt): No longer static. * gcc.dg/pr69167.c: New test. --- gcc/gimple-match-head.c.jj 2016-01-04 14:55:53.000000000 +0100 +++ gcc/gimple-match-head.c 2016-01-07 12:54:42.237334530 +0100 @@ -655,9 +655,23 @@ gimple_simplify (gimple *stmt, valueized = true; if (TREE_CODE_CLASS ((enum tree_code)rcode2) == tcc_comparison) - rhs1 = build2 (rcode2, TREE_TYPE (rhs1), - ops2[0], ops2[1]); - else if (rcode2 == SSA_NAME + { + if (TREE_CODE (ops2[0]) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops2[0]) + && !has_use_on_stmt (ops2[0], stmt)) + valueized = false; + if (TREE_CODE (ops2[1]) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops2[1]) + && !has_use_on_stmt (ops2[1], stmt)) + valueized = false; + if (valueized) + rhs1 = build2 (rcode2, TREE_TYPE (rhs1), + ops2[0], ops2[1]); + } + else if ((rcode2 == SSA_NAME + && (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI + (ops2[0]) + || has_use_on_stmt (ops2[0], stmt))) || rcode2 == INTEGER_CST || rcode2 == VECTOR_CST) rhs1 = ops2[0]; --- gcc/gimple-fold.h.jj 2016-01-04 14:55:53.000000000 +0100 +++ gcc/gimple-fold.h 2016-01-07 13:01:52.938315972 +0100 @@ -34,6 +34,7 @@ extern tree maybe_fold_or_comparisons (e enum tree_code, tree, tree); extern bool arith_overflowed_p (enum tree_code, const_tree, const_tree, const_tree); +extern bool has_use_on_stmt (tree, gimple *); extern tree no_follow_ssa_edges (tree); extern tree follow_single_use_edges (tree); extern tree gimple_fold_stmt_to_constant_1 (gimple *, tree (*) (tree), --- gcc/gimple-fold.c.jj 2016-01-07 11:37:36.000000000 +0100 +++ gcc/gimple-fold.c 2016-01-07 13:01:25.793695288 +0100 @@ -3270,7 +3270,7 @@ gimple_fold_call (gimple_stmt_iterator * /* Return true whether NAME has a use on STMT. */ -static bool +bool has_use_on_stmt (tree name, gimple *stmt) { imm_use_iterator iter; --- gcc/testsuite/gcc.dg/pr69167.c.jj 2016-01-07 12:58:40.706002201 +0100 +++ gcc/testsuite/gcc.dg/pr69167.c 2016-01-07 12:58:22.000000000 +0100 @@ -0,0 +1,21 @@ +/* PR tree-optimization/69167 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int sigsetjmp (char *); +void foo (); +void bar (void (*) (int *)); +extern char t[]; + +void +baz (int *x) +{ + int *a = x; + foo (); + x = 0; + if (sigsetjmp (t)) + while (1) + bar (a ? baz : 0); + if (x) + foo (); +} Jakub