-/* { 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))
-/* { 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
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
struct box { char field[256]; int i; };
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { struct_musttail && { c || c++11 } } } } */
extern int foo2 (int x, ...);
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
struct box { char field[64]; int i; };
-/* { 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() {}
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
float f1(void);
-/* { dg-do compile { target { tail_call } } } */
+/* { dg-do compile { target { musttail } } } */
/* { dg-options "-std=gnu++11" } */
/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
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))
-/* { dg-do compile { target { tail_call } } } */
+/* { dg-do compile { target { musttail } } } */
/* { dg-options "-std=gnu++11" } */
/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
-/* { 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*-*-* } } */
-/* { dg-do compile { target { tail_call } } } */
+/* { dg-do compile { target { musttail } } } */
/* { dg-options "-std=gnu++11" } */
/* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
} {-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