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)); +}
