Hi! The following testcase ICEs because SSA_NAME IMM links are broken. I've tracked it to DOM's optimize_stmt, a GIMPLE_COND in there is changed, marked as modified, then in optimize_stmt if (gimple_modified_p (stmt) || modified_p) { tree val = NULL;
update_stmt_if_modified (stmt); and a few lines later changed again: if (gimple_code (stmt) == GIMPLE_COND) { if (integer_zerop (val)) gimple_cond_make_false (as_a <gcond *> (stmt)); else if (integer_onep (val)) gimple_cond_make_true (as_a <gcond *> (stmt)); without update_stmt. As this is a function which update_stmt_if_modified a few lines before, I think it is fine to update_stmt it immediately. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-09-13 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/77454 * tree-ssa-dom.c (optimize_stmt): Call update_stmt after changing GIMPLE_COND. Formatting fix. * gcc.dg/pr77454.c: New test. --- gcc/tree-ssa-dom.c.jj 2016-07-22 15:55:30.000000000 +0200 +++ gcc/tree-ssa-dom.c 2016-09-09 12:29:28.006188533 +0200 @@ -1927,8 +1927,9 @@ optimize_stmt (basic_block bb, gimple_st if (gimple_code (stmt) == GIMPLE_COND) val = fold_binary_loc (gimple_location (stmt), - gimple_cond_code (stmt), boolean_type_node, - gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); + gimple_cond_code (stmt), boolean_type_node, + gimple_cond_lhs (stmt), + gimple_cond_rhs (stmt)); else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) val = gimple_switch_index (swtch_stmt); @@ -1946,6 +1947,8 @@ optimize_stmt (basic_block bb, gimple_st gimple_cond_make_true (as_a <gcond *> (stmt)); else gcc_unreachable (); + + update_stmt (stmt); } /* Further simplifications may be possible. */ --- gcc/testsuite/gcc.dg/pr77454.c.jj 2016-09-09 12:34:47.540537483 +0200 +++ gcc/testsuite/gcc.dg/pr77454.c 2016-09-09 12:32:47.000000000 +0200 @@ -0,0 +1,28 @@ +/* PR tree-optimization/77454 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +foo (unsigned char x, char y) +{ + while (x != 0) + { + unsigned char *a = &x; + int b; + + if (y != 0) + a = (unsigned char *) &y; + else if (y + 1 != 0) + a = (unsigned char *) &y; + for (x = 0; x < 1; ++x) + b = 0; + for (y = 0; y < 3; ++y) + { + y = !!y; + if (y != 0) + x = y; + } + if ((b != 0 ? -1 : *a) < (y = b)) + b = 1; + } +} Jakub