This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFC: PR middle-end/50074: [4.7 Regression] gcc.dg/sibcall-6.c execution test on x86_64 with -fPIC
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Kirill Yukhin <kirill dot yukhin at intel dot com>
- Date: Sat, 10 Sep 2011 09:47:46 -0700
- Subject: RFC: PR middle-end/50074: [4.7 Regression] gcc.dg/sibcall-6.c execution test on x86_64 with -fPIC
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
The fix for
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49519
is too conservative. It disables some sibcall optimizations. This
patch changes to check register address only when called from
store_one_arg. Any comments?
Thanks.
H.J.
---
gcc/
2011-09-10 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/49719
PR middle-end/50074
* calls.c (mem_overlaps_already_clobbered_arg_p): Add an argument
and check if address is stored in register only when needed.
(load_register_parameters): Pass false
mem_overlaps_already_clobbered_arg_p.
(check_sibcall_argument_overlap_1): Likewise.
(store_one_arg): Pass true to mem_overlaps_already_clobbered_arg_p.
gcc/testsuite/
2011-09-10 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/50074
* gcc.dg/sibcall-9.c: New.
diff --git a/gcc/calls.c b/gcc/calls.c
index a6e96e4..dabc8b0 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1578,7 +1578,9 @@ rtx_for_function_call (tree fndecl, tree addr)
sibcall. */
static bool
-mem_overlaps_already_clobbered_arg_p (rtx addr, unsigned HOST_WIDE_INT size)
+mem_overlaps_already_clobbered_arg_p (rtx addr,
+ unsigned HOST_WIDE_INT size,
+ bool check_addr_reg)
{
HOST_WIDE_INT i;
@@ -1595,7 +1597,7 @@ mem_overlaps_already_clobbered_arg_p (rtx addr, unsigned HOST_WIDE_INT size)
return true;
/* If the address comes in a register, we have no idea of its origin so
give up and conservatively return true. */
- else if (REG_P(addr))
+ else if (check_addr_reg && REG_P(addr))
return true;
else
return false;
@@ -1716,7 +1718,8 @@ load_register_parameters (struct arg_data *args, int num_actuals,
if (is_sibcall
&& (size == 0
|| mem_overlaps_already_clobbered_arg_p
- (XEXP (args[i].value, 0), size)))
+ (XEXP (args[i].value, 0), size,
+ false)))
*sibcall_failure = 1;
/* Handle a BLKmode that needs shifting. */
@@ -1843,7 +1846,8 @@ check_sibcall_argument_overlap_1 (rtx x)
if (code == MEM)
return mem_overlaps_already_clobbered_arg_p (XEXP (x, 0),
- GET_MODE_SIZE (GET_MODE (x)));
+ GET_MODE_SIZE (GET_MODE (x)),
+ false);
/* Scan all subexpressions. */
fmt = GET_RTX_FORMAT (code);
@@ -4256,7 +4260,8 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
if ((flags & ECF_SIBCALL)
&& MEM_P (arg->value)
&& mem_overlaps_already_clobbered_arg_p (XEXP (arg->value, 0),
- arg->locate.size.constant))
+ arg->locate.size.constant,
+ true))
sibcall_failure = 1;
/* Don't allow anything left on stack from computation
diff --git a/gcc/testsuite/gcc.dg/sibcall-9.c b/gcc/testsuite/gcc.dg/sibcall-9.c
new file mode 100644
index 0000000..a6299af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sibcall-9.c
@@ -0,0 +1,38 @@
+/* { dg-do run { target { { i?86-*-* x86_64-*-* s390*-*-* } && fpic } } } */
+/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && ia32 } { "*" } { "" } } */
+/* { dg-options "-O2 -foptimize-sibling-calls -fno-ipa-cp -fPIC" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int foo (int);
+int bar (int);
+
+int (*ptr) (int);
+int *f_addr;
+
+int
+main ()
+{
+ ptr = bar;
+ foo (7);
+ exit (0);
+}
+
+int __attribute__ ((noinline))
+bar (b)
+ int b;
+{
+ if (f_addr == (int*) __builtin_return_address (0))
+ return b;
+ else
+ abort ();
+}
+
+int __attribute__ ((noinline))
+foo (f)
+ int f;
+{
+ f_addr = (int*) __builtin_return_address (0);
+ return (*ptr)(f);
+}