On Thu, 30 Aug 2018, Richard Biener wrote: > > The following fixes an issue I introduced late with some re-org > introducing BB_EXCUTABLE ... > > O1-bootstrap and regtest running on x86_64-unknown-linux-gnu.
The following is what I applied. O1-bootstrapped and tested on x86_64-unknown-linux-gnu. Richard. 2018-08-30 Richard Biener <rguent...@suse.de> PR tree-optimization/87147 * tree-ssa-sccvn.c (SSA_VISITED): New function. (visit_phi): When the degenerate result is from the backedge and we didn't visit its definition yet drop to VARYING. (do_rpo_vn): Properly mark blocks with incoming backedges as executable. * gcc.dg/torture/pr87147.c: New testcase. Index: gcc/tree-ssa-sccvn.c =================================================================== --- gcc/tree-ssa-sccvn.c (revision 263972) +++ gcc/tree-ssa-sccvn.c (working copy) @@ -462,6 +462,15 @@ SSA_VAL (tree x) return tem && tem->visited ? tem->valnum : x; } +/* Return whether X was visited. */ + +inline bool +SSA_VISITED (tree x) +{ + vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x)); + return tem && tem->visited; +} + /* Return the SSA value of the VUSE x, supporting released VDEFs during elimination which will value-number the VDEF to the associated VUSE (but not substitute in the whole lattice). */ @@ -4100,6 +4109,7 @@ static bool visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) { tree result, sameval = VN_TOP, seen_undef = NULL_TREE; + tree backedge_name = NULL_TREE; tree sameval_base = NULL_TREE; poly_int64 soff, doff; unsigned n_executable = 0; @@ -4126,9 +4136,13 @@ visit_phi (gimple *phi, bool *inserted, tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); ++n_executable; - if (TREE_CODE (def) == SSA_NAME - && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))) - def = SSA_VAL (def); + if (TREE_CODE (def) == SSA_NAME) + { + if (e->flags & EDGE_DFS_BACK) + backedge_name = def; + if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)) + def = SSA_VAL (def); + } if (def == VN_TOP) ; /* Ignore undefined defs for sameval but record one. */ @@ -4162,10 +4176,15 @@ visit_phi (gimple *phi, bool *inserted, } } - + /* If the value we want to use is the backedge and that wasn't visited + yet drop to VARYING. */ + if (backedge_name + && sameval == backedge_name + && !SSA_VISITED (backedge_name)) + result = PHI_RESULT (phi); /* If none of the edges was executable keep the value-number at VN_TOP, if only a single edge is exectuable use its value. */ - if (n_executable <= 1) + else if (n_executable <= 1) result = seen_undef ? seen_undef : sameval; /* If we saw only undefined values and VN_TOP use one of the undefined values. */ @@ -6298,6 +6317,7 @@ do_rpo_vn (function *fn, edge entry, bit { basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]); rpo_state[i].visited = 0; + bb->flags &= ~BB_EXECUTABLE; bool has_backedges = false; edge e; edge_iterator ei; @@ -6306,12 +6326,17 @@ do_rpo_vn (function *fn, edge entry, bit if (e->flags & EDGE_DFS_BACK) has_backedges = true; if (! iterate && (e->flags & EDGE_DFS_BACK)) - e->flags |= EDGE_EXECUTABLE; + { + e->flags |= EDGE_EXECUTABLE; + /* ??? Strictly speaking we only need to unconditionally + process a block when it is in an irreducible region, + thus when it may be reachable via the backedge only. */ + bb->flags |= BB_EXECUTABLE; + } else e->flags &= ~EDGE_EXECUTABLE; } rpo_state[i].iterate = iterate && has_backedges; - bb->flags &= ~BB_EXECUTABLE; } entry->flags |= EDGE_EXECUTABLE; entry->dest->flags |= BB_EXECUTABLE; Index: gcc/testsuite/gcc.dg/torture/pr87147.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr87147.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr87147.c (working copy) @@ -0,0 +1,22 @@ +/* { dg-do run } */ + +short a; +long b; +int c, d, g; +char e, h; +long f[] = {0}; +int main() +{ + int i = 1; + for (; a <= 3; a++) { + c = 0; + for (; c <= 2; c++) { + b = 0; + for (; b <= 3; b++) { + h = i && f[d]; + e = g && i; + i = 0; + } + } + } +}