This PR had the equivalent of:

L1:
  x = PHI(1, z)
  y = -x
  ...
L2:
  z = PHI(x, y)

where z could be simplified to:

  z = PHI(x, x)

i.e. to x.  Changing z triggered a need to replace x with a new SSA name,
but z was left being replaced with x, rather than x's replacement.

Since the replacement values are (of course) restricted to using
dominating definitions, a single RPO pass is enough to calculate the
transitive closure of replacement values.

Bootstrapped & regression-tested on aarch64-linux-gnu, powerpc64le-linux-gnu
and x86_64-linux-gnu.  OK to install?

Richard


gcc/
        PR tree-optimization/125599
        * gimple-ssa-backprop.cc (backprop::execute): Calculate the
        transitive closure of replacement values.

gcc/testsuite/
        PR tree-optimization/125599
        * g++.dg/torture/pr125599.C: New test.
---
 gcc/gimple-ssa-backprop.cc              | 15 +++++++++++++++
 gcc/testsuite/g++.dg/torture/pr125599.C | 19 +++++++++++++++++++
 2 files changed, 34 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr125599.C

diff --git a/gcc/gimple-ssa-backprop.cc b/gcc/gimple-ssa-backprop.cc
index 5d7295c9d8e..f32f18f1014 100644
--- a/gcc/gimple-ssa-backprop.cc
+++ b/gcc/gimple-ssa-backprop.cc
@@ -1107,6 +1107,21 @@ backprop::execute ()
       propagate_change (v);
     }
 
+  /* Now that we have a complete set of values that need to change,
+     calculate the transitive closure of replacement values.  */
+  bool changed = false;
+  for (unsigned int i = m_vars.length (); i-- > 0;)
+    if (var_info *v = m_vars[i])
+      if (v->var != v->new_value)
+       if (var_info *newv = lookup_operand (v->new_value))
+         {
+           gcc_assert (newv->index > i);
+           if (!changed && dump_file && (dump_flags & TDF_DETAILS))
+             fprintf (dump_file, "\n");
+           set_new_value (v, newv->new_value);
+           changed = true;
+         }
+
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "\n");
 
diff --git a/gcc/testsuite/g++.dg/torture/pr125599.C 
b/gcc/testsuite/g++.dg/torture/pr125599.C
new file mode 100644
index 00000000000..63ca61a3384
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr125599.C
@@ -0,0 +1,19 @@
+/* { dg-additional-options "-w" } */
+
+double tetallnormal_A[1][4];
+struct tetgenmesh {
+  bool lu_decmp(double[][4], int *, double *, int);
+  void tetallnormal();
+};
+int lu_decmp_n;
+bool tetgenmesh::lu_decmp(double[][4], int *, double *d, int) {
+  double biggest, pivotindex, k;
+  *d = 1.0;
+  for (; lu_decmp_n; k++)
+    if (biggest == pivotindex != k)
+      *d = -*d;
+}
+void tetgenmesh::tetallnormal() {
+  double D;
+  int indx[](lu_decmp(tetallnormal_A, indx, &D, 0));
+}
-- 
2.54.0

Reply via email to