diff mbox series

PR116080: Fix test suite checks for musttail

Message ID 20240729181142.1618467-1-ak@linux.intel.com
State New
Headers show
Series PR116080: Fix test suite checks for musttail | expand

Commit Message

Andi Kleen July 29, 2024, 6:11 p.m. UTC
From: Andi Kleen <ak@gcc.gnu.org>

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       |  4 ++--
 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, 37 insertions(+), 19 deletions(-)

Comments

Andi Kleen Aug. 2, 2024, 9:12 p.m. UTC | #1
Andi Kleen <ak@linux.intel.com> writes:

> From: Andi Kleen <ak@gcc.gnu.org>
>
> 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.

---

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
Thomas Schwinge Aug. 7, 2024, 8:58 a.m. UTC | #2
Hi Andi!

On 2024-08-02T14:12:59-0700, Andi Kleen <ak@linux.intel.com> wrote:
> Andi Kleen <ak@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
Andi Kleen Aug. 7, 2024, 3:18 p.m. UTC | #3
> > 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.

Thanks Thomas.

> 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.)

I believe that's because these test cases are handled by the GIMPLE level
tail call handling in tree-tailcall (which avoids any target
restrictions), while the TCL test checks for the generic case using 
an extern (so hits target restrictions).

While this could probably be distinguished in the test case probing
I don't think it's worth it. Some of this is just for the frontend,
which is architecture independent enough.

-Andi
Andi Kleen Aug. 12, 2024, 4:19 p.m. UTC | #4
Andi Kleen <ak@linux.intel.com> writes:

I wanted to ping this patch. It fixes test suite noise on various
targets.

https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html


> From: Andi Kleen <ak@gcc.gnu.org>
>
> 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       |  4 ++--
>  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, 37 insertions(+), 19 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..49430b1263a5 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,7 +8,7 @@ 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))
> 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
Andi Kleen Aug. 25, 2024, 5:15 p.m. UTC | #5
Andi Kleen <ak@linux.intel.com> writes:

PING^2 for https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html

This fixes some musttail related test suite failures that cause noise on
various targets.

> Andi Kleen <ak@linux.intel.com> writes:
>
> I wanted to ping this patch. It fixes test suite noise on various
> targets.
>
> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html
>
>
>> From: Andi Kleen <ak@gcc.gnu.org>
>>
>> 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       |  4 ++--
>>  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, 37 insertions(+), 19 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..49430b1263a5 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,7 +8,7 @@ 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))
>> 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
Andi Kleen Sept. 2, 2024, 11:23 p.m. UTC | #6
Andi Kleen <ak@linux.intel.com> writes:

PING^3

> Andi Kleen <ak@linux.intel.com> writes:
>
> PING^2 for https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html
>
> This fixes some musttail related test suite failures that cause noise on
> various targets.
>
>> Andi Kleen <ak@linux.intel.com> writes:
>>
>> I wanted to ping this patch. It fixes test suite noise on various
>> targets.
>>
>> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html
>>
>>
>>> From: Andi Kleen <ak@gcc.gnu.org>
>>>
>>> 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       |  4 ++--
>>>  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, 37 insertions(+), 19 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..49430b1263a5 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,7 +8,7 @@ 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))
>>> 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
Mike Stump Sept. 3, 2024, 7:41 p.m. UTC | #7
On Sep 2, 2024, at 4:23 PM, Andi Kleen <ak@linux.intel.com> wrote:
> 
> Andi Kleen <ak@linux.intel.com> writes:
> 
> PING^3

Ok.

>> Andi Kleen <ak@linux.intel.com> writes:
>> 
>> PING^2 for https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html
>> 
>> This fixes some musttail related test suite failures that cause noise on
>> various targets.
>> 
>>> Andi Kleen <ak@linux.intel.com> writes:
>>> 
>>> I wanted to ping this patch. It fixes test suite noise on various
>>> targets.
>>> 
>>> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658602.html
>>> 
>>> 
>>>> From: Andi Kleen <ak@gcc.gnu.org>
>>>> 
>>>> 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       |  4 ++--
>>>> 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, 37 insertions(+), 19 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..49430b1263a5 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,7 +8,7 @@ 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))
>>>> 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
diff mbox series

Patch

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..49430b1263a5 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,7 +8,7 @@  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))
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