File s390-31bit-sibcall-fix of Package gcc43

Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** s390_emit_call (rtx addr_location, rtx t
*** 9387,9397 ****
           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;
          }
  
        /* Unless we can use the bras(l) insn, force the
--- 9387,9411 ----
           replace the symbol itself with the PLT stub.  */
        if (flag_pic && !SYMBOL_REF_LOCAL_P (addr_location))
          {
! 	  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: gcc/testsuite/gcc.c-torture/compile/pr43635.c
===================================================================
*** /dev/null
--- gcc/testsuite/gcc.c-torture/compile/pr43635.c
***************
*** 0 ****
--- 1,7 ----
+ extern void d (void);
+ 
+ void (*foo (void)) (float)
+ {
+   void (*(*x) (void)) (float) = d;
+   return (*x) ();
+ }
openSUSE Build Service is sponsored by