Hi Andi! On 2024-08-02T14:12:59-0700, Andi Kleen <a...@linux.intel.com> wrote: > Andi Kleen <a...@linux.intel.com> writes: >> This is a new attempt to fix PR116080. The previous try was reverted >> because it just broke a bunch of tests, hiding the problem. > > The previous version still had one failure on powerpc because > of a template call that needs a dg-error check for external_tail_call. > I fixed that now in the below version. > > Okay for trunk? I would like to check that one in to avoid the noise > in the regression reports.
I've tested this version in a few trees. ('-Wc++-compat' are the C test cases, '-std=c++YY' the C++ ones.) For x86_64 GNU/Linux, '-m32' testing, this does resolve the previous FAILs: [-FAIL:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -std=c++11[-(test for excess errors)-] [-FAIL:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -std=c++17[-(test for excess errors)-] [-FAIL:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -std=c++26[-(test for excess errors)-] [-FAIL:-]{+UNSUPPORTED:+} g++.dg/musttail6.C[-(test for excess errors)-] ..., but also "regresses" (PASS -> UNSUPPORTED): [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -Wc++-compat[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -Wc++-compat (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -Wc++-compat[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -std=c++11 (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -std=c++11[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -std=c++17 (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -std=c++17[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -std=c++26 (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -std=c++26[-(test for excess errors)-] That's because of effective-target 'struct_musttail' for '-m32' reporting: struct_musttail1494739.cc: In function 'foo bar()': struct_musttail1494739.cc:5:88: error: cannot tail-call: return value used after call (I'm just mentioning the latter "regressions" in case those are unexpected.) For powerpc64le GNU/Linux, this does resolve the previous FAIL: PASS: g++.dg/musttail10.C (test for errors, line 11) {+PASS: g++.dg/musttail10.C (test for errors, line 15)+} PASS: g++.dg/musttail10.C (test for errors, line 20) PASS: g++.dg/musttail10.C (test for errors, line 24) PASS: g++.dg/musttail10.C (test for errors, line 7) [-FAIL:-]{+PASS:+} g++.dg/musttail10.C (test for excess errors) ..., but similarly "regresses" (PASS -> UNSUPPORTED): [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -Wc++-compat[-(test for excess errors)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -std=c++11[-(test for excess errors)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -std=c++17[-(test for excess errors)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail12.c -std=c++26[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -Wc++-compat (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -Wc++-compat[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -std=c++11 (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -std=c++11[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -std=c++17 (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -std=c++17[-(test for excess errors)-] [-PASS: c-c++-common/musttail3.c -std=c++26 (test for errors, line 26)-] [-PASS:-]{+UNSUPPORTED:+} c-c++-common/musttail3.c -std=c++26[-(test for excess errors)-] Here, that's because of effective-target 'struct_musttail' reporting: struct_musttail485321.cc: In function 'foo bar()': struct_musttail485321.cc:5:88: error: cannot tail-call: target is not able to optimize the call into a sibling call (Again, I'm just mentioning the latter "regressions" in case those are unexpected.) So: looks good, all FAILs resolved (in these GCC configurations). Grüße Thomas > This is a new attempt to fix PR116080. The previous try was reverted > because it just broke a bunch of tests, hiding the problem. > > - musttail behaves differently than tailcall at -O0. Some of the test > run at -O0, so add separate effective target tests for musttail. > - New effective target tests need to use unique file names > to make dejagnu caching work > - Change the tests to use new targets > - Add a external_musttail test to check for target's ability > to do tail calls between translation units. This covers some powerpc > ABIs. > > gcc/testsuite/ChangeLog: > > PR testsuite/116080 > * c-c++-common/musttail1.c: Use musttail target. > * c-c++-common/musttail12.c: Use struct_musttail target. > * c-c++-common/musttail2.c: Use musttail target. > * c-c++-common/musttail3.c: Likewise. > * c-c++-common/musttail4.c: Likewise. > * c-c++-common/musttail7.c: Likewise. > * c-c++-common/musttail8.c: Likewise. > * g++.dg/musttail10.C: Likewise. Replace powerpc checks with > external_musttail. > * g++.dg/musttail11.C: Use musttail target. > * g++.dg/musttail6.C: Use musttail target. Replace powerpc > checks with external_musttail. > * g++.dg/musttail9.C: Use musttail target. > * lib/target-supports.exp: Add musttail, struct_musttail, > external_musttail targets. Remove optimization for musttail. > Use unique file names for musttail. > --- > gcc/testsuite/c-c++-common/musttail1.c | 2 +- > gcc/testsuite/c-c++-common/musttail12.c | 2 +- > gcc/testsuite/c-c++-common/musttail2.c | 2 +- > gcc/testsuite/c-c++-common/musttail3.c | 2 +- > gcc/testsuite/c-c++-common/musttail4.c | 2 +- > gcc/testsuite/c-c++-common/musttail7.c | 2 +- > gcc/testsuite/c-c++-common/musttail8.c | 2 +- > gcc/testsuite/g++.dg/musttail10.C | 6 ++--- > gcc/testsuite/g++.dg/musttail11.C | 2 +- > gcc/testsuite/g++.dg/musttail6.C | 4 ++-- > gcc/testsuite/g++.dg/musttail9.C | 2 +- > gcc/testsuite/lib/target-supports.exp | 30 ++++++++++++++++++++----- > 12 files changed, 38 insertions(+), 20 deletions(-) > > diff --git a/gcc/testsuite/c-c++-common/musttail1.c > b/gcc/testsuite/c-c++-common/musttail1.c > index 74efcc2a0bc6..51549672e02a 100644 > --- a/gcc/testsuite/c-c++-common/musttail1.c > +++ b/gcc/testsuite/c-c++-common/musttail1.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { musttail && { c || c++11 } } } } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > int __attribute__((noinline,noclone,noipa)) > diff --git a/gcc/testsuite/c-c++-common/musttail12.c > b/gcc/testsuite/c-c++-common/musttail12.c > index 4140bcd00950..475afc5af3f3 100644 > --- a/gcc/testsuite/c-c++-common/musttail12.c > +++ b/gcc/testsuite/c-c++-common/musttail12.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { struct_tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { struct_musttail && { c || c++11 } } } } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > struct str > diff --git a/gcc/testsuite/c-c++-common/musttail2.c > b/gcc/testsuite/c-c++-common/musttail2.c > index 86f2c3d77404..1970c4edd670 100644 > --- a/gcc/testsuite/c-c++-common/musttail2.c > +++ b/gcc/testsuite/c-c++-common/musttail2.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { musttail && { c || c++11 } } } } */ > > struct box { char field[256]; int i; }; > > diff --git a/gcc/testsuite/c-c++-common/musttail3.c > b/gcc/testsuite/c-c++-common/musttail3.c > index ea9589c59ef2..7499fd6460b4 100644 > --- a/gcc/testsuite/c-c++-common/musttail3.c > +++ b/gcc/testsuite/c-c++-common/musttail3.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { struct_musttail && { c || c++11 } } } } */ > > extern int foo2 (int x, ...); > > diff --git a/gcc/testsuite/c-c++-common/musttail4.c > b/gcc/testsuite/c-c++-common/musttail4.c > index 23f4b5e1cd68..bd6effa4b931 100644 > --- a/gcc/testsuite/c-c++-common/musttail4.c > +++ b/gcc/testsuite/c-c++-common/musttail4.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { musttail && { c || c++11 } } } } */ > > struct box { char field[64]; int i; }; > > diff --git a/gcc/testsuite/c-c++-common/musttail7.c > b/gcc/testsuite/c-c++-common/musttail7.c > index c753a3fe9b2a..d17cb71256d7 100644 > --- a/gcc/testsuite/c-c++-common/musttail7.c > +++ b/gcc/testsuite/c-c++-common/musttail7.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { musttail && { c || c++11 } } } } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > void __attribute__((noipa)) f() {} > diff --git a/gcc/testsuite/c-c++-common/musttail8.c > b/gcc/testsuite/c-c++-common/musttail8.c > index 9fa10e0b54c4..50ca1ac0dd48 100644 > --- a/gcc/testsuite/c-c++-common/musttail8.c > +++ b/gcc/testsuite/c-c++-common/musttail8.c > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call && { c || c++11 } } } } */ > +/* { dg-do compile { target { musttail && { c || c++11 } } } } */ > > float f1(void); > > diff --git a/gcc/testsuite/g++.dg/musttail10.C > b/gcc/testsuite/g++.dg/musttail10.C > index ff7fcc7d8755..a43d8a6fde7e 100644 > --- a/gcc/testsuite/g++.dg/musttail10.C > +++ b/gcc/testsuite/g++.dg/musttail10.C > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call } } } */ > +/* { dg-do compile { target { musttail } } } */ > /* { dg-options "-std=gnu++11" } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > @@ -8,11 +8,11 @@ double g() { [[gnu::musttail]] return f<int>(); } /* { > dg-error "cannot tail-cal > > template <class T> > __attribute__((noinline, noclone, noipa)) > -T g1() { [[gnu::musttail]] return f<T>(); } /* { dg-error "target is not > able" "" { target powerpc*-*-* } } */ > +T g1() { [[gnu::musttail]] return f<T>(); } /* { dg-error "target is not > able" "" { target { ! external_musttail } } } */ > > template <class T> > __attribute__((noinline, noclone, noipa)) > -T g2() { [[gnu::musttail]] return f<T>(); } > +T g2() { [[gnu::musttail]] return f<T>(); } /* { dg-error "target is not > able" "" { target { ! external_musttail } } } */ > > template <class T> > __attribute__((noinline, noclone, noipa)) > diff --git a/gcc/testsuite/g++.dg/musttail11.C > b/gcc/testsuite/g++.dg/musttail11.C > index 1779e3287a93..dca87247d504 100644 > --- a/gcc/testsuite/g++.dg/musttail11.C > +++ b/gcc/testsuite/g++.dg/musttail11.C > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call } } } */ > +/* { dg-do compile { target { musttail } } } */ > /* { dg-options "-std=gnu++11" } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > diff --git a/gcc/testsuite/g++.dg/musttail6.C > b/gcc/testsuite/g++.dg/musttail6.C > index 5c6f69407ddb..5dcf302139ae 100644 > --- a/gcc/testsuite/g++.dg/musttail6.C > +++ b/gcc/testsuite/g++.dg/musttail6.C > @@ -1,6 +1,6 @@ > -/* { dg-do compile { target { struct_tail_call } } } */ > +/* { dg-do compile { target { struct_musttail } } } */ > +/* { dg-require-effective-target external_musttail } */ > /* A lot of architectures will not build this due to PR115606 and PR115607 */ > -/* { dg-skip-if "powerpc does not support sibcall to templates" { > powerpc*-*-* } } */ > /* { dg-options "-std=gnu++11" } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > diff --git a/gcc/testsuite/g++.dg/musttail9.C > b/gcc/testsuite/g++.dg/musttail9.C > index fb0262e751be..85937dcdcd31 100644 > --- a/gcc/testsuite/g++.dg/musttail9.C > +++ b/gcc/testsuite/g++.dg/musttail9.C > @@ -1,4 +1,4 @@ > -/* { dg-do compile { target { tail_call } } } */ > +/* { dg-do compile { target { musttail } } } */ > /* { dg-options "-std=gnu++11" } */ > /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */ > > diff --git a/gcc/testsuite/lib/target-supports.exp > b/gcc/testsuite/lib/target-supports.exp > index d368251ef9a4..10b2969f747a 100644 > --- a/gcc/testsuite/lib/target-supports.exp > +++ b/gcc/testsuite/lib/target-supports.exp > @@ -12744,16 +12744,34 @@ proc check_effective_target_tail_call { } { > } {-O2 -fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed > dump. > } > > -# Return 1 if the target can perform tail-call optimizations for structures > +# Return 1 if the target can perform musttail optimizations of the > +# most trivial type. This is separate from tail_call because musttail > +# is supported at -O0. > +proc check_effective_target_musttail { } { > + return [check_no_messages_and_pattern musttail ",SIBCALL" rtl-expand { > + __attribute__((__noipa__)) void foo (void) { } > + __attribute__((__noipa__)) void bar (void) { [[gnu::musttail]] return > foo(); } > + } {-fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed > dump. > +} > + > +# Return 1 if the target can perform musttail for externals > +proc check_effective_target_external_musttail { } { > + return [check_no_messages_and_pattern external_musttail ",SIBCALL" > rtl-expand { > + extern __attribute__((__noipa__)) void foo (void); > + __attribute__((__noipa__)) void bar (void) { [[gnu::musttail]] return > foo(); } > + } {-fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed > dump. > +} > + > +# Return 1 if the target can perform musttail optimizations for structures > # checking with C++ because the C++ compiler has less tail call ability > # due to PR115606 on some targets > -proc check_effective_target_struct_tail_call { } { > - return [check_no_messages_and_pattern tail_call ",SIBCALL" rtl-expand { > +proc check_effective_target_struct_musttail { } { > + return [check_no_messages_and_pattern struct_musttail ",SIBCALL" > rtl-expand { > // C++ > struct foo { int a, b; }; > - __attribute__((__noipa__)) struct foo foo (void) { return {}; } > - __attribute__((__noipa__)) struct foo bar (void) { return foo(); } > - } {-O2 -fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed > dump. > + extern __attribute__((__noipa__)) struct foo foo (void); > + __attribute__((__noipa__)) struct foo bar (void) { [[gnu::musttail]] > return foo(); } > + } {-fdump-rtl-expand-all}] ;# The "SIBCALL" note requires a detailed > dump. > } > > # Return 1 if the target's calling sequence or its ABI > -- > 2.45.2