My fixing of store-sinking exposed an issue that relying on SSA update to fixup virtual operands isn't a good idea if we incrementally walk through all sinking candidates. Fixed by manually updating virtual SSA form which is easy in this case.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-03-16 Richard Guenther <rguent...@suse.de> PR tree-optimization/48146 * tree-ssa-sink.c (sink_code_in_bb): Manually update virtual operands avoiding the need for renaming. * gcc.dg/torture/pr48146.c: New testcase. Index: gcc/tree-ssa-sink.c =================================================================== *** gcc/tree-ssa-sink.c (revision 171039) --- gcc/tree-ssa-sink.c (working copy) *************** sink_code_in_bb (basic_block bb) *** 505,516 **** bb->index, (gsi_bb (togsi))->index); } ! /* Prepare for VOP update. */ if (gimple_vdef (stmt)) { ! unlink_stmt_vdef (stmt); ! gimple_set_vdef (stmt, gimple_vop (cfun)); ! mark_sym_for_renaming (gimple_vop (cfun)); } /* If this is the end of the basic block, we need to insert at the end --- 505,522 ---- bb->index, (gsi_bb (togsi))->index); } ! /* Update virtual operands of statements in the path we ! do not sink to. */ if (gimple_vdef (stmt)) { ! imm_use_iterator iter; ! use_operand_p use_p; ! gimple vuse_stmt; ! ! FOR_EACH_IMM_USE_STMT (vuse_stmt, iter, gimple_vdef (stmt)) ! if (gimple_code (vuse_stmt) != GIMPLE_PHI) ! FOR_EACH_IMM_USE_ON_STMT (use_p, iter) ! SET_USE (use_p, gimple_vuse (stmt)); } /* If this is the end of the basic block, we need to insert at the end Index: gcc/testsuite/gcc.dg/torture/pr48146.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr48146.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr48146.c (revision 0) *************** *** 0 **** --- 1,35 ---- + /* { dg-do compile } */ + + static unsigned char + safe_sub_func_int_s_s (int si1, unsigned char si2) + { + return si1 ^ si2 & -si2 ^ si2 ? : si1 - si2; + } + + int g_2[10] = { + 0x90AC204EL + }; + + volatile unsigned char g_39; + + unsigned char + func_67 (unsigned short p_68) + { + unsigned char l_92; + unsigned char l_74; + int *l = &g_2[6]; + lbl_90:*l ^= 1; + if (p_68) + goto lbl_93; + for (l_74 = 0;; l_74 = safe_sub_func_int_s_s (l_74, 1)) + { + if (l_74) + goto lbl_90; + lbl_93:l_92 ^= 0 != &g_39; + if (0) + { + } + else + *l = 1; + } + }