Hi,

more precisely, to a nested function that requires a static chain.  The reason 
is that the sibling call epilogue may clobber the static chain register r11.

Tested on PowerPC/Linux, OK for the mainline?


2018-09-17  Eric Botcazou  <ebotca...@adacore.com>

        * config/rs6000/rs6000.c (rs6000_function_ok_for_sibcall): Return false
        if the call takes a static chain.


2018-09-17  Eric Botcazou  <ebotca...@adacore.com>

        * gcc.dg/nested-func-11.c: New test.

-- 
Eric Botcazou
/* { dg-do run } */
/* { dg-options "-O2 -fno-omit-frame-pointer" } */

int __attribute__((noipa)) foo (int i)
{
  int a;

  void __attribute__((noipa)) nested2 (int i)
  {
    a = i;
  }

  void  __attribute__((noipa)) nested1 (int i)
  {
    int b[32];

    for (int j = 0; j < 32; j++)
      b[j] = i + j;

    nested2 (b[i]);
  }

  nested1 (i);

  return a;
}

int main (void)
{
  if (foo (4) != 8)
    __builtin_abort ();

  return 0;
}
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 264342)
+++ config/rs6000/rs6000.c	(working copy)
@@ -24332,6 +24332,10 @@ rs6000_function_ok_for_sibcall (tree dec
 {
   tree fntype;
 
+  /* The sibcall epilogue may clobber the static chain register.  */
+  if (CALL_EXPR_STATIC_CHAIN (exp))
+    return false;
+
   if (decl)
     fntype = TREE_TYPE (decl);
   else

Reply via email to