Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard.
2015-11-10 Richard Biener <rguent...@suse.de> PR tree-optimization/68240 * tree-ssa-sccvn.c (cond_stmts_equal_p): Handle commutative compares properly. (visit_phi): For PHIs with just a single executable edge take its value directly. (expressions_equal_p): Handle VN_TOP properly. * gcc.dg/torture/pr68240.c: New testcase. Index: gcc/testsuite/gcc.dg/torture/pr68240.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr68240.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr68240.c (working copy) *************** *** 0 **** --- 1,12 ---- + /* { dg-do compile } */ + + int a, b, f; + + void + fn1 () + { + int c = 1, d, e = 1; + a = 1; + for (; f;) + b = (c && (d = (e && a))); + } Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 230020) --- gcc/tree-ssa-sccvn.c (working copy) *************** cond_stmts_equal_p (gcond *cond1, gcond *** 2760,2770 **** else return false; ! if (! expressions_equal_p (vn_valueize (lhs1), vn_valueize (lhs2)) ! || ! expressions_equal_p (vn_valueize (rhs1), vn_valueize (rhs2))) ! return false; ! ! return true; } /* Compare two phi entries for equality, ignoring VN_TOP arguments. */ --- 2806,2820 ---- else return false; ! lhs1 = vn_valueize (lhs1); ! rhs1 = vn_valueize (rhs1); ! lhs2 = vn_valueize (lhs2); ! rhs2 = vn_valueize (rhs2); ! return ((expressions_equal_p (lhs1, lhs2) ! && expressions_equal_p (rhs1, rhs2)) ! || (commutative_tree_code (code1) ! && expressions_equal_p (lhs1, rhs2) ! && expressions_equal_p (rhs1, lhs2))); } /* Compare two phi entries for equality, ignoring VN_TOP arguments. */ *************** visit_phi (gimple *phi) *** 3379,3384 **** --- 3428,3434 ---- tree result; tree sameval = VN_TOP; bool allsame = true; + unsigned n_executable = 0; /* TODO: We could check for this in init_sccvn, and replace this with a gcc_assert. */ *************** visit_phi (gimple *phi) *** 3394,3399 **** --- 3444,3450 ---- { tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); + ++n_executable; if (TREE_CODE (def) == SSA_NAME) def = SSA_VAL (def); if (def == VN_TOP) *************** visit_phi (gimple *phi) *** 3408,3416 **** } /* If none of the edges was executable or all incoming values are ! undefined keep the value-number at VN_TOP. */ ! if (sameval == VN_TOP) ! return set_ssa_val_to (PHI_RESULT (phi), VN_TOP); /* First see if it is equivalent to a phi node in this block. We prefer this as it allows IV elimination - see PRs 66502 and 67167. */ --- 3459,3469 ---- } /* If none of the edges was executable or all incoming values are ! undefined keep the value-number at VN_TOP. If only a single edge ! is exectuable use its value. */ ! if (sameval == VN_TOP ! || n_executable == 1) ! return set_ssa_val_to (PHI_RESULT (phi), sameval); /* First see if it is equivalent to a phi node in this block. We prefer this as it allows IV elimination - see PRs 66502 and 67167. */ *************** expressions_equal_p (tree e1, tree e2) *** 4610,4615 **** --- 4663,4672 ---- if (e1 == e2) return true; + /* If either one is VN_TOP consider them equal. */ + if (e1 == VN_TOP || e2 == VN_TOP) + return true; + /* If only one of them is null, they cannot be equal. */ if (!e1 || !e2) return false;