OSDN Git Service

2010-04-20 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 07:51:14 +0000 (07:51 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 01:06:46 +0000 (10:06 +0900)
PR target/43635
* config/s390/s390.c (s390_emit_call): Turn direct into indirect
calls for -fpic -m31 if they have been sibcall optimized.

2010-04-20  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

PR target/43635
* gcc.c-torture/compile/pr43635.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158540 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/testsuite/ChangeLog

index bd99d7b..5397101 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-20  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       PR target/43635
+       * config/s390/s390.c (s390_emit_call): Turn direct into indirect
+       calls for -fpic -m31 if they have been sibcall optimized.
+
 2010-04-19  James E. Wilson  <wilson@codesourcery.com>
 
        PR rtl-optimization/43520
index c3820e5..858aac9 100644 (file)
@@ -9539,11 +9539,25 @@ s390_emit_call (rtx addr_location, rtx tls_call, rtx result_reg,
          replace the symbol itself with the PLT stub.  */
       if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
         {
-         addr_location = gen_rtx_UNSPEC (Pmode,
-                                         gen_rtvec (1, addr_location),
-                                         UNSPEC_PLT);
-         addr_location = gen_rtx_CONST (Pmode, addr_location);
-         plt_call = true;
+         if (retaddr_reg != NULL_RTX)
+           {
+             addr_location = gen_rtx_UNSPEC (Pmode,
+                                             gen_rtvec (1, addr_location),
+                                             UNSPEC_PLT);
+             addr_location = gen_rtx_CONST (Pmode, addr_location);
+             plt_call = true;
+           }
+         else
+           /* For -fpic code the PLT entries might use r12 which is
+              call-saved.  Therefore we cannot do a sibcall when
+              calling directly using a symbol ref.  When reaching
+              this point we decided (in s390_function_ok_for_sibcall)
+              to do a sibcall for a function pointer but one of the
+              optimizers was able to get rid of the function pointer
+              by propagating the symbol ref into the call.  This
+              optimization is illegal for S/390 so we turn the direct
+              call into a indirect call again.  */
+           addr_location = force_reg (Pmode, addr_location);
         }
 
       /* Unless we can use the bras(l) insn, force the
index dbde635..73295fc 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-20  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       PR target/43635
+       * gcc.c-torture/compile/pr43635.c: New testcase.
+
 2010-04-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/43339