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