From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 125891 invoked by alias); 25 Feb 2015 15:43:10 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 125880 invoked by uid 89); 25 Feb 2015 15:43:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Wed, 25 Feb 2015 15:43:08 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 6F474AB09; Wed, 25 Feb 2015 15:43:04 +0000 (UTC) Date: Wed, 25 Feb 2015 15:49:00 -0000 From: Martin Jambor To: Eric Botcazou Cc: gcc-patches@gcc.gnu.org, Richard Biener Subject: Re: [patch] Fix ICE on unaligned record field Message-ID: <20150225154303.GE20953@virgil.suse> Mail-Followup-To: Eric Botcazou , gcc-patches@gcc.gnu.org, Richard Biener References: <3887233.jQSJCmu5YU@polaris> <20141203140207.GL8214@virgil.suse> <14069807.eYpOW1jBVs@polaris> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <14069807.eYpOW1jBVs@polaris> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes X-SW-Source: 2015-02/txt/msg01507.txt.bz2 Hi Eric and Richard, On Tue, Jan 06, 2015 at 06:07:12PM +0100, Eric Botcazou wrote: > Martin, > > > I suppose that could be done by something like the following, which I > > have tested only very mildly so far, in particular I have not double > > checked that get_inner_reference is cfun-agnostic. > > The patch introduces no regressions on x86-64/Linux and makes the testcase > (gnat.dg/specs/pack12.ads attached to the first message) pass. > > Do you plan to install it (along with the testcase)? > for various reasons I was not able to do it earlier, but today I have re-bootstrapped the following (the only change is the added testcase) on x86_64-linux and it passes OK. Should I commit it to trunk then? Thanks, Martin 2015-02-25 Martin Jambor Eric Botcazou gcc/ * tree-sra.c (ipa_sra_check_caller_data): New type. (has_caller_p): Removed. (ipa_sra_check_caller): New function. (ipa_sra_preliminary_function_checks): Use it. gcc/changelog/ * gnat.dg/specs/pack12.ads: New test. diff --git a/gcc/testsuite/gnat.dg/specs/pack12.ads b/gcc/testsuite/gnat.dg/specs/pack12.ads new file mode 100644 index 0000000..c5e962c --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/pack12.ads @@ -0,0 +1,21 @@ +-- { dg-do compile } +-- { dg-options "-O2" } + +package Pack12 is + + type Rec1 is record + B : Boolean; + N : Natural; + end record; + + type Rec2 is record + B : Boolean; + R : Rec1; + end record; + pragma Pack (Rec2); + + type Rec3 is tagged record + R : Rec2; + end record; + +end Pack12; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 023b817..a6cddaf 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -5009,13 +5009,54 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments) return cfg_changed; } -/* If NODE has a caller, return true. */ +/* Means of communication between ipa_sra_check_caller and + ipa_sra_preliminary_function_checks. */ + +struct ipa_sra_check_caller_data +{ + bool has_callers; + bool bad_arg_alignment; +}; + +/* If NODE has a caller, mark that fact in DATA which is pointer to + ipa_sra_check_caller_data. Also check all aggregate arguments in all known + calls if they are unit aligned and if not, set the appropriate flag in DATA + too. */ static bool -has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +ipa_sra_check_caller (struct cgraph_node *node, void *data) { - if (node->callers) - return true; + if (!node->callers) + return false; + + struct ipa_sra_check_caller_data *iscc; + iscc = (struct ipa_sra_check_caller_data *) data; + iscc->has_callers = true; + + for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller) + { + gimple call_stmt = cs->call_stmt; + unsigned count = gimple_call_num_args (call_stmt); + for (unsigned i = 0; i < count; i++) + { + tree arg = gimple_call_arg (call_stmt, i); + if (is_gimple_reg (arg)) + continue; + + tree offset; + HOST_WIDE_INT bitsize, bitpos; + machine_mode mode; + int unsignedp, volatilep = 0; + get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode, + &unsignedp, &volatilep, false); + if (bitpos % BITS_PER_UNIT) + { + iscc->bad_arg_alignment = true; + return true; + } + } + } + return false; } @@ -5070,14 +5111,6 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node) return false; } - if (!node->call_for_symbol_thunks_and_aliases (has_caller_p, NULL, true)) - { - if (dump_file) - fprintf (dump_file, - "Function has no callers in this compilation unit.\n"); - return false; - } - if (cfun->stdarg) { if (dump_file) @@ -5096,6 +5129,25 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node) return false; } + struct ipa_sra_check_caller_data iscc; + memset (&iscc, 0, sizeof(iscc)); + node->call_for_symbol_thunks_and_aliases (ipa_sra_check_caller, &iscc, true); + if (!iscc.has_callers) + { + if (dump_file) + fprintf (dump_file, + "Function has no callers in this compilation unit.\n"); + return false; + } + + if (iscc.bad_arg_alignment) + { + if (dump_file) + fprintf (dump_file, + "A function call has an argument with non-unit alignemnt.\n"); + return false; + } + return true; }