aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-09-04 10:55:46 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-09-04 10:55:46 +0000
commitc2c51a3e358294b5ddfa522fa4d973c3360699b4 (patch)
tree6f6ecfbfcc692b9233cf702e2437761aa05a4fb8
parent727c8c82e14021cad992443bb32693293a55e33d (diff)
downloadgcc-c2c51a3e358294b5ddfa522fa4d973c3360699b4.zip
gcc-c2c51a3e358294b5ddfa522fa4d973c3360699b4.tar.gz
gcc-c2c51a3e358294b5ddfa522fa4d973c3360699b4.tar.bz2
re PR tree-optimization/87176 (wrong code at -Os and above on x86-64-linux-gnu)
2018-09-04 Richard Biener <rguenther@suse.de> PR tree-optimization/87176 * tree-ssa-sccvn.c (visit_phi): Remove redundant allsame variable. When value-numbering a virtual PHI node make sure to not value-number to the backedge value. * gcc.dg/torture/pr87176.c: New testcase. * gcc.dg/torture/ssa-fre-1.c: Likewise. From-SVN: r264077
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr87176.c28
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-1.c16
-rw-r--r--gcc/tree-ssa-sccvn.c31
5 files changed, 78 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3b1981c..cfd6b25 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-09-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87176
+ * tree-ssa-sccvn.c (visit_phi): Remove redundant allsame
+ variable. When value-numbering a virtual PHI node make sure
+ to not value-number to the backedge value.
+
2018-09-04 Jonathan Wakely <jwakely@redhat.com>
* doc/extend.texi (Long Long, Hex Floats): Document support for
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 436b4ab..8602ff4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2018-09-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/87176
+ * gcc.dg/torture/pr87176.c: New testcase.
+ * gcc.dg/torture/ssa-fre-1.c: Likewise.
+
2018-09-03 Jerry DeLisle <jvdelisle@gcc.gnu.org>
* gfortran.dg/modulo_check: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr87176.c b/gcc/testsuite/gcc.dg/torture/pr87176.c
new file mode 100644
index 0000000..6295779
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr87176.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+int a, b, c;
+
+int main ()
+{
+ int d = a = 0;
+ while (1)
+ {
+ a = a ^ 6;
+ if (!a)
+ break;
+ if (d)
+ goto L;
+ d = a;
+ for (b = 0; b < 2; b++)
+ {
+ const int *f[3] = { &c };
+ const int **g[] = { &f[2] };
+ int h = ~d;
+ if (d)
+ L:
+ if (h > 1)
+ continue;
+ }
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-1.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-1.c
new file mode 100644
index 0000000..1597122
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-1.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fstrict-aliasing -fdump-tree-fre1" } */
+
+float f;
+int foo(int *p, int *q)
+{
+ *p = 0;
+ if (*p)
+ *q = 1;
+ else
+ f = 8.0f;
+ return *p;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 34c193b..8d68b6b 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -4110,11 +4110,11 @@ 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 backedge_val = NULL_TREE;
+ bool seen_non_backedge = false;
tree sameval_base = NULL_TREE;
poly_int64 soff, doff;
unsigned n_executable = 0;
- bool allsame = true;
edge_iterator ei;
edge e;
@@ -4139,11 +4139,13 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
++n_executable;
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 (e->flags & EDGE_DFS_BACK)
+ backedge_val = def;
}
+ if (!(e->flags & EDGE_DFS_BACK))
+ seen_non_backedge = true;
if (def == VN_TOP)
;
/* Ignore undefined defs for sameval but record one. */
@@ -4172,16 +4174,25 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
&& known_eq (soff, doff))
continue;
}
- allsame = false;
+ sameval = NULL_TREE;
break;
}
}
/* 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))
+ yet drop to VARYING. This only happens when not iterating.
+ If we value-number a virtual operand never value-number to the
+ value from the backedge as that confuses the alias-walking code.
+ See gcc.dg/torture/pr87176.c. If the value is the same on a
+ non-backedge everything is OK though. */
+ if (backedge_val
+ && !seen_non_backedge
+ && TREE_CODE (backedge_val) == SSA_NAME
+ && sameval == backedge_val
+ && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val)
+ || !SSA_VISITED (backedge_val)))
+ /* Note this just drops to VARYING without inserting the PHI into
+ the hashes. */
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. */
@@ -4212,7 +4223,7 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
/* If all values are the same use that, unless we've seen undefined
values as well and the value isn't constant.
CCP/copyprop have the same restriction to not remove uninit warnings. */
- else if (allsame
+ else if (sameval
&& (! seen_undef || is_gimple_min_invariant (sameval)))
result = sameval;
else