From patchwork Sat Sep 10 16:47:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 114194 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 49550B721B for ; Sun, 11 Sep 2011 02:48:10 +1000 (EST) Received: (qmail 31594 invoked by alias); 10 Sep 2011 16:48:06 -0000 Received: (qmail 31573 invoked by uid 22791); 10 Sep 2011 16:48:04 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, NO_DNS_FOR_FROM, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga03.intel.com (HELO mga03.intel.com) (143.182.124.21) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 10 Sep 2011 16:47:48 +0000 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga101.ch.intel.com with ESMTP; 10 Sep 2011 09:47:47 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by AZSMGA002.ch.intel.com with ESMTP; 10 Sep 2011 09:47:46 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id D1871C1EC1; Sat, 10 Sep 2011 09:47:46 -0700 (PDT) Date: Sat, 10 Sep 2011 09:47:46 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: Kirill Yukhin Subject: RFC: PR middle-end/50074: [4.7 Regression] gcc.dg/sibcall-6.c execution test on x86_64 with -fPIC Message-ID: <20110910164746.GA12855@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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 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); +}