On Mon, Jan 20, 2025 at 6:01 AM Andrew Pinski <quic_apin...@quicinc.com> wrote: > > While fixing PR target/117665, I had noticed that fold_marked_statements > would not purge the abnormal edges which could not be taken any more due > to folding a call (devirtualization or simplification of a [target] builtin). > Devirutalization could also cause a call that used to be able to have an > abornal edge become one not needing one too so this was needed for GCC 15. > > Bootstrapped and tested on x86_64-linux-gnu
OK. Thanks, Richard. > PR tree-optimization/118077 > PR tree-optimization/117668 > > gcc/ChangeLog: > > * tree-inline.cc (fold_marked_statements): Purge abnormal edges > as needed. > > gcc/testsuite/ChangeLog: > > * g++.dg/opt/devirt6.C: New test. > > Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> > --- > gcc/testsuite/g++.dg/opt/devirt6.C | 23 +++++++++++++++++++++++ > gcc/tree-inline.cc | 22 ++++++++++++++++++++-- > 2 files changed, 43 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/opt/devirt6.C > > diff --git a/gcc/testsuite/g++.dg/opt/devirt6.C > b/gcc/testsuite/g++.dg/opt/devirt6.C > new file mode 100644 > index 00000000000..5caf9da7891 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/opt/devirt6.C > @@ -0,0 +1,23 @@ > +// { dg-do compile { target c++11 } } > +// { dg-options "-O3" } > + > +// PR tree-optimization/118077 > + > +// This used to ICE because the devirtualization call > +// of bb inside f1 (which was inlined into f2) became > +// a direct call to c1::bb but the abnormal edge > +// was not removed even though bb was const. > + > +int f() __attribute__((returns_twice)); > +struct c1 { > + virtual int bb(void) const { return 0; } > + bool f1(int a) > + { > + return a && !bb(); > + } > +}; > +struct c2 final : c1 { void f2(int); }; > +void c2::f2(int a) { > + if (!f1(a)) > + f(); > +} > diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc > index 11278e5c483..5b3539009a3 100644 > --- a/gcc/tree-inline.cc > +++ b/gcc/tree-inline.cc > @@ -5430,6 +5430,7 @@ static void > fold_marked_statements (int first, hash_set<gimple *> *statements) > { > auto_bitmap to_purge; > + auto_bitmap to_purge_abnormal; > > auto_vec<edge, 20> stack (n_basic_blocks_for_fn (cfun) + 2); > auto_sbitmap visited (last_basic_block_for_fn (cfun)); > @@ -5456,8 +5457,16 @@ fold_marked_statements (int first, hash_set<gimple *> > *statements) > continue; > > gimple *old_stmt = gsi_stmt (gsi); > - tree old_decl = (is_gimple_call (old_stmt) > - ? gimple_call_fndecl (old_stmt) : 0); > + bool can_make_abnormal_goto = false; > + tree old_decl = NULL_TREE; > + > + if (is_gimple_call (old_stmt)) > + { > + old_decl = gimple_call_fndecl (old_stmt); > + if (stmt_can_make_abnormal_goto (old_stmt)) > + can_make_abnormal_goto = true; > + } > + > if (old_decl && fndecl_built_in_p (old_decl)) > { > /* Folding builtins can create multiple instructions, > @@ -5473,6 +5482,8 @@ fold_marked_statements (int first, hash_set<gimple *> > *statements) > { > cgraph_update_edges_for_call_stmt (old_stmt, > old_decl, NULL); > + if (can_make_abnormal_goto) > + bitmap_set_bit (to_purge_abnormal, dest->index); > break; > } > if (gsi_end_p (i2)) > @@ -5501,6 +5512,9 @@ fold_marked_statements (int first, hash_set<gimple *> > *statements) > if (maybe_clean_or_replace_eh_stmt (old_stmt, > new_stmt)) > bitmap_set_bit (to_purge, dest->index); > + if (can_make_abnormal_goto > + && !stmt_can_make_abnormal_goto (new_stmt)) > + bitmap_set_bit (to_purge_abnormal, dest->index); > break; > } > gsi_next (&i2); > @@ -5521,6 +5535,9 @@ fold_marked_statements (int first, hash_set<gimple *> > *statements) > > if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) > bitmap_set_bit (to_purge, dest->index); > + if (can_make_abnormal_goto > + && !stmt_can_make_abnormal_goto (new_stmt)) > + bitmap_set_bit (to_purge_abnormal, dest->index); > } > } > > @@ -5542,6 +5559,7 @@ fold_marked_statements (int first, hash_set<gimple *> > *statements) > } > > gimple_purge_all_dead_eh_edges (to_purge); > + gimple_purge_all_dead_abnormal_call_edges (to_purge_abnormal); > } > > /* Expand calls to inline functions in the body of FN. */ > -- > 2.43.0 >