There's interfering between the to_removed queue and other mechanisms removing stmts, in this case remove_prop_source_from_use. The following makes the to_remove queue draining more permissive.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/109327 * tree-ssa-forwprop.cc (pass_forwprop::execute): Deal with already removed stmts when draining to_remove. * gcc.dg/pr109327.c: New testcase. --- gcc/testsuite/gcc.dg/pr109327.c | 15 +++++++++++++++ gcc/tree-ssa-forwprop.cc | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr109327.c diff --git a/gcc/testsuite/gcc.dg/pr109327.c b/gcc/testsuite/gcc.dg/pr109327.c new file mode 100644 index 00000000000..827b26f148e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr109327.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fno-tree-ccp" } */ + +int a; +void b(int c) {} +int main() +{ + int d = 0, *e = &a; + if (d) { + int *f = e; + while (a) + b(e != f); + } + return 0; +} diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 5eccc7a89b5..bb0fa306312 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -4061,6 +4061,10 @@ pass_forwprop::execute (function *fun) while (!to_remove.is_empty()) { gimple *stmt = to_remove.pop (); + /* For example remove_prop_source_from_use can remove stmts queued + for removal. Deal with this gracefully. */ + if (!gimple_bb (stmt)) + continue; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Removing dead stmt "); -- 2.35.3