This avoids endless cycling when a PHI node with unchanged backedge
value (the PHI result appearing there) is subject to CSE since doing
that effectively alters the hash entry.  The way to avoid this is
to ignore such edges when processing the PHI node.

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

2021-03-22  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/99694
        * tree-ssa-sccvn.c (visit_phi): Ignore edges with the
        PHI result.

        * gcc.dg/torture/pr99694.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr99694.c | 27 ++++++++++++++++++++++++++
 gcc/tree-ssa-sccvn.c                   |  2 ++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr99694.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr99694.c 
b/gcc/testsuite/gcc.dg/torture/pr99694.c
new file mode 100644
index 00000000000..df316961673
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr99694.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-w" } */
+
+#include <stdint.h>
+
+int a, b, c;
+void d() {
+  uint16_t e;
+  int32_t *f;
+  int32_t *g;
+  if (a) {
+    int32_t *k;
+    for (;; *k += 1) {
+      int32_t **i = &f;
+      int32_t **l = &g;
+      for (e = 6; e; e++) {
+        g = k = f;
+      j:
+        **l = 0;
+      }
+      *i = c;
+    }
+  }
+  uint16_t i = &e;
+  b = i / 0;
+  goto j;
+}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 99759a8744a..1c0500ce61e 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -5199,6 +5199,8 @@ visit_phi (gimple *phi, bool *inserted, bool 
backedges_varying_p)
       {
        tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
 
+       if (def == PHI_RESULT (phi))
+         continue;
        ++n_executable;
        if (TREE_CODE (def) == SSA_NAME)
          {
-- 
2.26.2

Reply via email to