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?

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?

And perhaps more importantly, are there noreturn calls which are not
gimple_call_ctrl_altering_p?  What are they?

Thanks,

Martin

Reply via email to