aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2010-04-20 07:51:14 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2010-04-20 07:51:14 +0000
commit72e2cf162959f344ec2e9a7488858a18574e3db1 (patch)
tree0b18b2817bda588ead5ef8dfb825d5f7a177e15e /gcc
parent4a863f3a0b20b9b14e44e44433b6ca1d35e91691 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/s390/s390.c24
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr43635.c7
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) ();
+}