From 72e2cf162959f344ec2e9a7488858a18574e3db1 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Tue, 20 Apr 2010 07:51:14 +0000 Subject: [PATCH] re PR target/43635 (ICE in s390_emit_call, at config/s390/s390.c:9484) 2010-04-20 Andreas Krebbel 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 PR target/43635 * gcc.c-torture/compile/pr43635.c: New testcase. From-SVN: r158540 --- gcc/ChangeLog | 6 +++++ gcc/config/s390/s390.c | 24 +++++++++++++++---- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.c-torture/compile/pr43635.c | 7 ++++++ 4 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr43635.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd99d7bea83b..5397101de3f8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-04-20 Andreas Krebbel + + 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 PR rtl-optimization/43520 diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index c3820e580123..858aac9f0849 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dbde6351fac0..73295fcd1a32 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-04-20 Andreas Krebbel + + PR target/43635 + * gcc.c-torture/compile/pr43635.c: New testcase. + 2010-04-19 Jakub Jelinek PR fortran/43339 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr43635.c b/gcc/testsuite/gcc.c-torture/compile/pr43635.c new file mode 100644 index 000000000000..4039fa7a569d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr43635.c @@ -0,0 +1,7 @@ +extern void d (void); + +void (*foo (void)) (float) +{ + void (*(*x) (void)) (float) = d; + return (*x) (); +} -- 2.47.2