1 /* Simple check that sibling calls are performed from a 2 void non-leaf-function taking one int argument calling a function which 3 is about the same as itself. 4 5 Copyright (C) 2002 Free Software Foundation Inc. 6 Contributed by Hans-Peter Nilsson <hp@bitrange.com> */ 7 8 /* { dg-do run { xfail { { cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ 9 /* -mlongcall disables sibcall patterns. */ 10 /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ 11 /* { dg-options "-O2 -foptimize-sibling-calls" } */ 12 13 /* The option -foptimize-sibling-calls is the default, but serves as 14 marker. This test is xfailed on targets without sibcall patterns 15 (except targets where the test does not work due to the return address 16 not saved on the regular stack). */ 17 18 extern void abort (void); 19 extern void exit (int); 20 21 /* Sibcalls are not supported in MIPS16 mode, which has direct calls but 22 not direct jumps. */ 23 #ifdef __mips 24 #define ATTR __attribute__((nomips16)) 25 #else 26 #define ATTR 27 #endif 28 29 static ATTR void recurser_void1 (int); 30 static ATTR void recurser_void2 (int); 31 extern void track (int); 32 main()33int main () 34 { 35 recurser_void1 (0); 36 exit (0); 37 } 38 39 /* The functions should get the same stack-frame, and best way to make it 40 reasonably sure is to make them have the same contents (regarding the 41 n tests). */ 42 43 static void __attribute__((noinline)) ATTR recurser_void1(int n)44recurser_void1 (int n) 45 { 46 if (n == 0 || n == 7 || n == 8) 47 track (n); 48 49 if (n == 10) 50 return; 51 52 recurser_void2 (n + 1); 53 } 54 55 static void __attribute__((noinline)) ATTR recurser_void2(int n)56recurser_void2 (int n) 57 { 58 if (n == 0 || n == 7 || n == 8) 59 track (n); 60 61 if (n == 10) 62 return; 63 64 recurser_void1 (n + 1); 65 } 66 67 void *trackpoint; 68 69 void __attribute__ ((noinline)) track(int n)70track (int n) 71 { 72 char stackpos[1]; 73 74 if (n == 0) 75 trackpoint = stackpos; 76 else if ((n != 7 && n != 8) || trackpoint != stackpos) 77 abort (); 78 } 79