Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2018-09-04  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/87211
        * tree-ssa-sccvn.c (visit_phi): When value-numbering to a
        backedge value we're supposed to treat as VARYING also number
        the PHI to VARYING in case it got a different value-number already.

        * gcc.dg/torture/pr87211.c: New testcase.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 264078)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -4180,7 +4180,8 @@ 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.  This only happens when not iterating.
+     yet or if we should take it as VARYING but it has a non-VARYING
+     value 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
@@ -4190,7 +4191,8 @@ visit_phi (gimple *phi, bool *inserted,
       && TREE_CODE (backedge_val) == SSA_NAME
       && sameval == backedge_val
       && (SSA_NAME_IS_VIRTUAL_OPERAND (backedge_val)
-         || !SSA_VISITED (backedge_val)))
+         || !SSA_VISITED (backedge_val)
+         || SSA_VAL (backedge_val) != backedge_val))
     /* Note this just drops to VARYING without inserting the PHI into
        the hashes.  */
     result = PHI_RESULT (phi);
Index: gcc/testsuite/gcc.dg/torture/pr87211.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr87211.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr87211.c      (working copy)
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+int a, b;
+int i(int *);
+int *c(int *d, int *e)
+{
+  for (; b;)
+    d = e;
+  return d;
+}
+void f()
+{
+  for (;;)
+    {
+      int *g[1];
+      int h = 0;
+      for (; h < 3; h++)
+       g[0] = &a;
+      &a == g[0] || i(c((int *)g, g[0]));
+    }
+}

Reply via email to