diff options
author | Andreas Krebbel <Andreas.Krebbel@de.ibm.com> | 2010-04-20 07:51:14 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2010-04-20 07:51:14 +0000 |
commit | 72e2cf162959f344ec2e9a7488858a18574e3db1 (patch) | |
tree | 0b18b2817bda588ead5ef8dfb825d5f7a177e15e | |
parent | 4a863f3a0b20b9b14e44e44433b6ca1d35e91691 (diff) | |
download | gcc-72e2cf162959f344ec2e9a7488858a18574e3db1.zip gcc-72e2cf162959f344ec2e9a7488858a18574e3db1.tar.gz gcc-72e2cf162959f344ec2e9a7488858a18574e3db1.tar.bz2 |
re PR target/43635 (ICE in s390_emit_call, at config/s390/s390.c:9484)
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-20 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
PR target/43635
* gcc.c-torture/compile/pr43635.c: New testcase.
From-SVN: r158540
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr43635.c | 7 |
4 files changed, 37 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd99d7be..5397101 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index c3820e5..858aac9 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 dbde635..73295fc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 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 0000000..4039fa7 --- /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) (); +} |