From 94852c8ec4eef2ad17846c714e469ea000127dec Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 10 Nov 2015 10:14:02 +0000 Subject: [PATCH] re PR tree-optimization/68240 (compilation hangs on valid code at -O1 and above on x86_64-linux-gnu) 2015-11-10 Richard Biener 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. From-SVN: r230095 --- gcc/ChangeLog | 9 +++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/torture/pr68240.c | 12 +++++++++++ gcc/tree-ssa-sccvn.c | 28 ++++++++++++++++++-------- 4 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr68240.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9db12db3a75..3bc856546c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-11-10 Richard Biener + + 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. + 2015-11-10 Richard Biener * tree-vect-data-refs.c (vect_slp_analyze_node_dependences): diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bbaf9a347c8..f2a7d3f6f96 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-10 Richard Biener + + PR tree-optimization/68240 + * gcc.dg/torture/pr68240.c: New testcase. + 2015-11-10 Richard Biener PR tree-optimization/56118 diff --git a/gcc/testsuite/gcc.dg/torture/pr68240.c b/gcc/testsuite/gcc.dg/torture/pr68240.c new file mode 100644 index 00000000000..b6d97902300 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68240.c @@ -0,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))); +} diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 9585f905438..2ac382842d3 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2760,11 +2760,15 @@ cond_stmts_equal_p (gcond *cond1, gcond *cond2, bool *inverted_p) 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; + 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. */ @@ -3379,6 +3383,7 @@ visit_phi (gimple *phi) 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. */ @@ -3394,6 +3399,7 @@ visit_phi (gimple *phi) { 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) @@ -3408,9 +3414,11 @@ visit_phi (gimple *phi) } /* 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); + 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. */ @@ -4610,6 +4618,10 @@ expressions_equal_p (tree e1, tree e2) 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; -- 2.30.2