aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-08-30 12:37:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-08-30 12:37:10 +0000
commitb1d5f644929182de05cf2bb940a6c417ec28f29a (patch)
treee9f0db5db8d2a0fdf340469bc42a7d577979b988
parent28428506aafe4613e4abf0b38671b4fc9c371ef9 (diff)
downloadgcc-b1d5f644929182de05cf2bb940a6c417ec28f29a.zip
gcc-b1d5f644929182de05cf2bb940a6c417ec28f29a.tar.gz
gcc-b1d5f644929182de05cf2bb940a6c417ec28f29a.tar.bz2
re PR tree-optimization/87147 (GCC miscompiles at -O3 on valid code)
2018-08-30 Richard Biener <rguenther@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. From-SVN: r263980
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr87147.c22
-rw-r--r--gcc/tree-ssa-sccvn.c39
4 files changed, 67 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0349cdc..e7a1910 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2018-08-30 Richard Biener <rguenther@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.
+
2018-08-29 Jan Hubicka <jh@suse.cz>
* lto-streamer-out.c (DFS::DFS_write_tree_body): Do not walk
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fd78dcf..75e6c67 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87147
+ * gcc.dg/torture/pr87147.c: New testcase.
+
2018-08-30 Tamar Christina <tamar.christina@arm.com>
* 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 0000000..385cfce
--- /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 39ab4b2..2bf71e5 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;