From b1d5f644929182de05cf2bb940a6c417ec28f29a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 30 Aug 2018 12:37:10 +0000 Subject: [PATCH] re PR tree-optimization/87147 (GCC miscompiles at -O3 on valid code) 2018-08-30 Richard Biener 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. From-SVN: r263980 --- gcc/ChangeLog | 8 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/torture/pr87147.c | 22 +++++++++++++++ gcc/tree-ssa-sccvn.c | 39 +++++++++++++++++++++----- 4 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr87147.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0349cdc919d..e7a1910ee6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-08-30 Richard Biener + + 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. + 2018-08-29 Jan Hubicka * lto-streamer-out.c (DFS::DFS_write_tree_body): Do not walk diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd78dcf0892..75e6c675563 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-08-30 Richard Biener + + PR tree-optimization/87147 + * gcc.dg/torture/pr87147.c: New testcase. + 2018-08-30 Tamar Christina * gcc.target/aarch64/large_struct_copy_2.c: New. diff --git a/gcc/testsuite/gcc.dg/torture/pr87147.c b/gcc/testsuite/gcc.dg/torture/pr87147.c new file mode 100644 index 00000000000..385cfce7201 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr87147.c @@ -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; + } + } + } +} diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 39ab4b25285..2bf71e5b15b 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -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, bool backedges_varying_p) 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, bool backedges_varying_p) } } - + /* 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, bitmap exit_bbs, { 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, bitmap exit_bbs, 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; -- 2.30.2