https://gcc.gnu.org/g:9f6e172f7402f1a020b6e3fd3f611f4dfa81af95

commit r17-1366-g9f6e172f7402f1a020b6e3fd3f611f4dfa81af95
Author: Richard Sandiford <[email protected]>
Date:   Fri Jun 5 09:18:34 2026 +0100

    backprop: Calculate transitive closures of replacements [PR125599]
    
    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.
    
    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.

Diff:
---
 gcc/gimple-ssa-backprop.cc              | 15 +++++++++++++++
 gcc/testsuite/g++.dg/torture/pr125599.C | 19 +++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/gcc/gimple-ssa-backprop.cc b/gcc/gimple-ssa-backprop.cc
index 5d7295c9d8ed..f32f18f1014a 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 000000000000..63ca61a3384b
--- /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));
+}

Reply via email to