This fixes PR48822, an issue we ran into the past as well. The problem is that due to various reasons (mostly simplification of expressions) we might be tempted to go up the lattice (from VARYING to some constant) during value-numbering. This is of course a recipie to oscillation as can be seen in the testcase (we do fold 0 % a to zero but won't touch 0 % 0).
Thus, simply never do that. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-05-02 Richard Guenther <rguent...@suse.de> PR tree-optimization/48822 * tree-ssa-sccvn.c (set_ssa_val_to): Never go up the lattice. (process_scc): Indicate which iteration we start. * gcc.dg/torture/pr48822.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 173243) --- gcc/tree-ssa-sccvn.c (working copy) *************** print_scc (FILE *out, VEC (tree, heap) * *** 2241,2252 **** static inline bool set_ssa_val_to (tree from, tree to) { ! tree currval; ! if (from != to ! && TREE_CODE (to) == SSA_NAME ! && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to)) ! to = from; /* The only thing we allow as value numbers are VN_TOP, ssa_names and invariants. So assert that here. */ --- 2241,2266 ---- static inline bool set_ssa_val_to (tree from, tree to) { ! tree currval = SSA_VAL (from); ! if (from != to) ! { ! if (currval == from) ! { ! if (dump_file && (dump_flags & TDF_DETAILS)) ! { ! fprintf (dump_file, "Not changing value number of "); ! print_generic_expr (dump_file, from, 0); ! fprintf (dump_file, " from VARYING to "); ! print_generic_expr (dump_file, to, 0); ! fprintf (dump_file, "\n"); ! } ! return false; ! } ! else if (TREE_CODE (to) == SSA_NAME ! && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (to)) ! to = from; ! } /* The only thing we allow as value numbers are VN_TOP, ssa_names and invariants. So assert that here. */ *************** set_ssa_val_to (tree from, tree to) *** 2263,2270 **** print_generic_expr (dump_file, to, 0); } - currval = SSA_VAL (from); - if (currval != to && !operand_equal_p (currval, to, OEP_PURE_SAME)) { VN_INFO (from)->valnum = to; --- 2277,2282 ---- *************** process_scc (VEC (tree, heap) *scc) *** 3280,3285 **** --- 3292,3299 ---- { changed = false; iterations++; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Starting iteration %d\n", iterations); /* As we are value-numbering optimistically we have to clear the expression tables and the simplified expressions in each iteration until we converge. */ Index: gcc/testsuite/gcc.dg/torture/pr48822.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr48822.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr48822.c (revision 0) *************** *** 0 **** --- 1,20 ---- + /* { dg-do compile } */ + + void foo (int *, int *); + int bar () + { + int a = 0; + int b = 0; + if (b != 0) + { + int ax = a; + int bx = b; + while (bx != 0) + { + int tem = ax % bx; + ax = bx; + bx = tem; + } + } + foo (&a, &b); + }