On Tue, 28 Jan 2025, Martin Jambor wrote: > Hi, > > On Tue, Jan 28 2025, Richard Biener wrote: > > On Mon, 27 Jan 2025, Martin Jambor wrote: > > > >> Hi, > >> > >> Zhendong Su and Michal Jireš found out that our gimple DSE pass can, > >> under fairly specific conditions, remove a noreturn call which then > >> leaves behind a "normal" BB with no successor edges which following > >> passes do not expect. This patch simply tells the pass to leave such > >> calls alone even when they otherwise appear to be dead. > >> > >> Interestingly, our CFG verifier does not report this. I'll put on my > >> todo list to add a test for it in the next stage 1. > >> > >> Bootstrapped and tested on x86_64-linux, OK for master? > >> > >> Thanks, > >> > >> Martin > >> > >> > >> gcc/ChangeLog: > >> > >> 2025-01-27 Martin Jambor <mjam...@suse.cz> > >> > >> PR tree-optimization/117892 > >> * tree-ssa-dse.cc (dse_optimize_call): Leave noreturn calls alone. > >> > >> gcc/testsuite/ChangeLog: > >> > >> 2025-01-27 Martin Jambor <mjam...@suse.cz> > >> > >> PR tree-optimization/117892 > >> * gcc.dg/tree-ssa/pr117892.c: New test. > >> * gcc.dg/tree-ssa/pr118517.c: Likewise. > >> > >> co-authored-by: Michal Jireš <mji...@suse.cz> > >> --- > >> gcc/testsuite/gcc.dg/tree-ssa/pr117892.c | 17 +++++++++++++++++ > >> gcc/testsuite/gcc.dg/tree-ssa/pr118517.c | 11 +++++++++++ > >> gcc/tree-ssa-dse.cc | 5 +++-- > >> 3 files changed, 31 insertions(+), 2 deletions(-) > >> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr117892.c > >> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr118517.c > >> > >> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr117892.c > >> b/gcc/testsuite/gcc.dg/tree-ssa/pr117892.c > >> new file mode 100644 > >> index 00000000000..d9b9c15095f > >> --- /dev/null > >> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr117892.c > >> @@ -0,0 +1,17 @@ > >> +/* { dg-do compile } */ > >> +/* { dg-options "-O1" } */ > >> + > >> + > >> +volatile int a; > >> +void b(int *c) { > >> + int *d = 0; > >> + *c = 0; > >> + *d = 0; > >> + __builtin_abort(); > >> +} > >> +int main() { > >> + int f; > >> + if (a) > >> + b(&f); > >> + return 0; > >> +} > >> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr118517.c > >> b/gcc/testsuite/gcc.dg/tree-ssa/pr118517.c > >> new file mode 100644 > >> index 00000000000..3a34f6788a9 > >> --- /dev/null > >> +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr118517.c > >> @@ -0,0 +1,11 @@ > >> +/* { dg-do compile } */ > >> +/* { dg-options "-O1 -fno-ipa-pure-const" } */ > >> + > >> +void __attribute__((noreturn)) bar(void) { > >> + __builtin_unreachable (); > >> +} > >> + > >> +int p; > >> +void foo() { > >> + if (p) bar(); > >> +} > >> diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc > >> index 753d7ef148b..492080a7eb0 100644 > >> --- a/gcc/tree-ssa-dse.cc > >> +++ b/gcc/tree-ssa-dse.cc > >> @@ -1396,8 +1396,9 @@ dse_optimize_call (gimple_stmt_iterator *gsi, > >> sbitmap live_bytes) > >> if (!node) > >> return false; > >> > >> - if (stmt_could_throw_p (cfun, stmt) > >> - && !cfun->can_delete_dead_exceptions) > >> + if ((stmt_could_throw_p (cfun, stmt) > >> + && !cfun->can_delete_dead_exceptions) > >> + || gimple_call_noreturn_p (stmt)) > > > > Please use the same test as is used in tree-ssa-dce.cc: > > > > /* Never elide a noreturn call we pruned control-flow for. */ > > if ((gimple_call_flags (call) & ECF_NORETURN) > > && gimple_call_ctrl_altering_p (call)) > > { > > mark_stmt_necessary (call, true); > > return; > > } > > OK, but just to make sure I understand: You do want me to leave the > !cfun->can_delete_dead_exceptions check there, right, so the condition > would become: > > if ((stmt_could_throw_p (cfun, stmt) > && !cfun->can_delete_dead_exceptions) > || (gimple_call_flags (call) & ECF_NORETURN) > && gimple_call_ctrl_altering_p (call)) > > > Right?
Yes, of course. > On x86_64 at least we do not have a testcase that would exercise the > can_delete_dead_exceptions part of the condition - not even an Ada > testcase - so it is not easy to think about it for me. > > And I also cannot stop wondering: Is explicitely checking for the > ECF_NORETURN bit really better than gimple_call_noreturn_p which does > exactly the same thing? No, my point was the .. > And perhaps more importantly, are there noreturn calls which are not > gimple_call_ctrl_altering_p? What are they? .. gimple_call_ctrl_altering_p flag check. Only ECF_NORETURN calls that have this set end a basic-block. Others we can freely delete without ICEing. That said, we should try to reduce subtle differences in "same" code, thus my comment. Richard. > Thanks, > > Martin > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)