This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: PR middle-end/50074: [4.7 Regression] gcc.dg/sibcall-6.c execution test on x86_64 with -fPIC


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]