(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
sibcall-10.c
       1  /* Simple check that sibling calls are performed from a
       2     void non-leaf-function taking no arguments 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 { { amdgcn*-*-* cris-*-* csky-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* nvptx*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
       9  /* -mlongcall disables sibcall patterns.  */
      10  /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */
      11  /* -msave-restore disables sibcall patterns.  */
      12  /* { dg-skip-if "" { riscv*-*-* } { "-msave-restore" } { "" } } */
      13  /* { dg-options "-O2 -foptimize-sibling-calls" } */
      14  
      15  /* The option -foptimize-sibling-calls is the default, but serves as
      16     marker.  This test is xfailed on targets without sibcall patterns
      17     (except targets where the test does not work due to the return address
      18     not saved on the regular stack).  */
      19  
      20  extern void abort (void);
      21  extern void exit (int);
      22  
      23  /* Sibcalls are not supported in MIPS16 mode, which has direct calls but
      24     not direct jumps.  */
      25  #ifdef __mips
      26  #define ATTR __attribute__((nomips16))
      27  #else
      28  #define ATTR
      29  #endif
      30  
      31  static ATTR void recurser_void1 (void);
      32  static ATTR void recurser_void2 (void);
      33  extern void track (void);
      34  static volatile int v;
      35  
      36  int n = 0;
      37  int main ()
      38  {
      39    recurser_void1 ();
      40    if (v != 5)
      41      abort ();
      42    exit (0);
      43  }
      44  
      45  /* The functions should get the same stack-frame, and best way to make it
      46     reasonably sure is to make them have the same contents (regarding the
      47     n tests).  */
      48  
      49  static void __attribute__((noipa)) ATTR
      50  recurser_void1 (void)
      51  {
      52    if (n == 0 || n == 7 || n == 8)
      53      track ();
      54  
      55    if (n == 10)
      56      return;
      57    n++;
      58    recurser_void2 ();
      59  }
      60  
      61  static void __attribute__((noipa)) ATTR
      62  recurser_void2 (void)
      63  {
      64    if (n == 0 || n == 7 || n == 8)
      65      track ();
      66  
      67    if (n == 10)
      68      return;
      69    n++;
      70    v++;
      71    recurser_void1 ();
      72  }
      73  
      74  void *trackpoint;
      75  
      76  void __attribute__ ((noipa))
      77  track ()
      78  {
      79    char stackpos[1];
      80  
      81    if (n == 0)
      82      trackpoint = stackpos;
      83    else if ((n != 7 && n != 8) || trackpoint != stackpos)
      84      abort ();
      85  }