From: Richard Biener Date: Tue, 4 Sep 2018 10:55:46 +0000 (+0000) Subject: re PR tree-optimization/87176 (wrong code at -Os and above on x86-64-linux-gnu) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c2c51a3e358294b5ddfa522fa4d973c3360699b4;p=gcc.git re PR tree-optimization/87176 (wrong code at -Os and above on x86-64-linux-gnu) 2018-09-04 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3b1981c5e45..cfd6b2500c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-09-04 Richard Biener + + 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 * doc/extend.texi (Long Long, Hex Floats): Document support for diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 436b4ab8544..8602ff4988a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-09-04 Richard Biener + + PR tree-optimization/87176 + * gcc.dg/torture/pr87176.c: New testcase. + * gcc.dg/torture/ssa-fre-1.c: Likewise. + 2018-09-03 Jerry DeLisle * 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 00000000000..6295779b139 --- /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 00000000000..15971223e01 --- /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 34c193b58f5..8d68b6bac59 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