The following fixes forwprop using FOR_EACH_IMM_USE_STMT to iterate
over stmts and then eventually removing the active stmt, releasing
its defs. This can cause debug stmt insertion with a RHS referencing
the SSA name we iterate over, adding to its immediate use list
but also adjusting all other debug stmts refering to the released
SSA name, updating those. And those can refer to the original
iterated over variable.
In the end the destructive behavior of update_stmt is a problem
here, which unlinks all uses of a stmt and then links in the
newly computed ones instead of leaving those in place that are.
* tree-ssa-forwprop.cc (forward_propagate_addr_expr):
Avoid removing stmts inside FOR_EACH_IMM_USE_STMT.
---
gcc/tree-ssa-forwprop.cc | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
index 9a993ab04de..4bac938cf54 100644
--- a/gcc/tree-ssa-forwprop.cc
+++ b/gcc/tree-ssa-forwprop.cc
@@ -930,6 +930,7 @@ forward_propagate_addr_expr (tree name, tree rhs, bool
parent_single_use_p)
bool all = true;
bool single_use_p = parent_single_use_p && has_single_use (name);
+ auto_vec<gimple *, 4> to_remove;
FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
{
bool result;
@@ -963,12 +964,14 @@ forward_propagate_addr_expr (tree name, tree rhs, bool
parent_single_use_p)
&& TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
&& TREE_CODE (use_rhs) == SSA_NAME
&& has_zero_uses (gimple_assign_lhs (use_stmt)))
- {
- gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
- fwprop_invalidate_lattice (gimple_get_lhs (use_stmt));
- release_defs (use_stmt);
- gsi_remove (&gsi, true);
- }
+ to_remove.safe_push (use_stmt);
+ }
+ for (gimple *use : to_remove)
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (use);
+ fwprop_invalidate_lattice (gimple_get_lhs (use));
+ release_defs (use);
+ gsi_remove (&gsi, true);
}
return all && has_zero_uses (name);
--
2.51.0