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) ();
+ }