From patchwork Thu May 19 14:38:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 624087 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3r9YbM6tqGz9ssM for ; Fri, 20 May 2016 00:38:39 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=PO0yc8qy; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; q=dns; s=default; b=cWWoqdUfbdjfy0AEAJyiCXwTV0k8xH hYdeMC8pJJvhHTXVcSz8RKKD9o4CzES91TTLsgeAoWIA2+IYROCCMIxUCpjD+jZd DSonwZgb3zJ2v4FQTPwy4vbMwtb7GCXVt64WN52odGOzQ2v1M+TTcAErakSR9+hD GN2eEc3iJ0WHQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; s=default; bh=77ZoSoHDPFco7zDl5Jh3Wd7Qxjc=; b=PO0y c8qyQMULD4vl7sT7cXsIYe0oieLYC5JYObCG8vBDfOqFwes1lyM804EIkjWV29/0 Nv1z6+kABewJ/BQU5GKVVBUtLYosqxMMocPD0IL3ahecaDG/vueNLg7irCK+7zgV IeXL09B94+1qHe3FE6FoU/EyCgISWn/NHai4rCM= Received: (qmail 49249 invoked by alias); 19 May 2016 14:38:30 -0000 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 Received: (qmail 49236 invoked by uid 89); 19 May 2016 14:38:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=SSA_NAME_VAR, ssa_name_var, gimple_code, 16527 X-HELO: mx2.suse.de Received: from mx2.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; Thu, 19 May 2016 14:38:19 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 7222AAB5D for ; Thu, 19 May 2016 14:38:15 +0000 (UTC) Date: Thu, 19 May 2016 16:38:15 +0200 From: Martin Jambor To: GCC Patches Subject: Re: [PR 70646] Store size to inlining predicate conditions Message-ID: <20160519143815.GH2959@virgil.suse.cz> Mail-Followup-To: GCC Patches References: <20160511154532.GF5580@virgil.suse.cz> <8402b16805536e57e9c06ee1fe1992c0@suse.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <8402b16805536e57e9c06ee1fe1992c0@suse.de> User-Agent: Mutt/1.6.0 (2016-04-01) X-IsSubscribed: yes Hi, On Wed, May 18, 2016 at 12:19:11PM +0200, jh wrote: > Dne 2016-05-11 17:45, Martin Jambor napsal: > > Hi, > > > > > > 2016-04-20 Martin Jambor > > > > PR ipa/70646 > > * ipa-inline.h (condition): New field size. > > * ipa-inline-analysis.c (add_condition): New parameter SIZE, use it > > for comaprison and store it into the new condition. > > (evaluate_conditions_for_known_args): Use condition size to check > > access sizes for all but CHANGED conditions. > > (unmodified_parm_1): New parameter size_p, store access size into it. > > (unmodified_parm): Likewise. > > (unmodified_parm_or_parm_agg_item): Likewise. > > (eliminated_by_inlining_prob): Pass NULL to unmodified_parm as size_p. > > (set_cond_stmt_execution_predicate): Extract access sizes and store > > them to conditions. > > (set_switch_stmt_execution_predicate): Likewise. > > (will_be_nonconstant_expr_predicate): Likewise. > > (will_be_nonconstant_predicate): Likewise. > > (inline_read_section): Stream condition size. > > (inline_write_summary): Likewise. > > This is OK for mainline and branches week later. You will need to bump up > the LTO stream > revision. Just one question: Thanks, I have committed the patch to trunk and added hunks bumping the minor LTO versions to the patches for release versions. > > Thanks, > Honza > > > > - if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)), > > - TYPE_SIZE (TREE_TYPE (val)), 0)) > > + if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size) > > Will it work for variable sized types and/or types whose size will not fit > in SHWI? Can these happen here or they are ruled out earlier in alaysis? > At this point, val needs to be na ipa_invariant, which implies fixed and small size. The patch I posted applies as-is to the gcc-6 branch but I had to do some manual backporting for the gcc-5 and gcc-4_9 branches. In the latter, I had to change the prototype of ipa_load_from_parm_agg to also return size of the load. For the reference, the 4.9 patch is below. I have bootstrapped and tested the different alternatives for all branches and will start committing them now. Thanks a lot, Martin 2016-05-18 Martin Jambor PR ipa/70646 * ipa-inline.h (condition): New field size. * ipa-inline-analysis.c (add_condition): New parameter SIZE, use it for comaprison and store it into the new condition. (evaluate_conditions_for_known_args): Use condition size to check access sizes for all but CHANGED conditions. (unmodified_parm_1): New parameter size_p, store access size into it. (unmodified_parm): Likewise. (unmodified_parm_or_parm_agg_item): Likewise. (eliminated_by_inlining_prob): Pass NULL to unmodified_parm as size_p. (set_cond_stmt_execution_predicate): Extract access sizes and store them to conditions. (set_switch_stmt_execution_predicate): Likewise. (will_be_nonconstant_expr_predicate): Likewise. (will_be_nonconstant_predicate): Likewise. (inline_read_section): Stream condition size. (inline_write_summary): Likewise. * lto-streamer.h (LTO_minor_version): Bump. * ipa-prop.c (ipa_load_from_parm_agg): Added size_p parameter, pass it to ipa_load_from_parm_agg_1. * ipa-prop.h (ipa_load_from_parm_agg): Update declaration. testsuite/ * gcc.dg/ipa/pr70646.c: New test. --- gcc/ipa-inline-analysis.c | 125 ++++++++++++++++++++++--------------- gcc/ipa-inline.h | 2 + gcc/ipa-prop.c | 4 +- gcc/ipa-prop.h | 2 +- gcc/lto-streamer.h | 2 +- gcc/testsuite/gcc.dg/ipa/pr70646.c | 40 ++++++++++++ 6 files changed, 122 insertions(+), 53 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr70646.c diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 9e71f43..47a3810 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -233,13 +233,14 @@ struct agg_position_info bool by_ref; }; -/* Add condition to condition list CONDS. AGGPOS describes whether the used - oprand is loaded from an aggregate and where in the aggregate it is. It can - be NULL, which means this not a load from an aggregate. */ +/* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL + correspond to fields of condition structure. AGGPOS describes whether the + used operand is loaded from an aggregate and where in the aggregate it is. + It can be NULL, which means this not a load from an aggregate. */ static struct predicate add_condition (struct inline_summary *summary, int operand_num, - struct agg_position_info *aggpos, + HOST_WIDE_INT size, struct agg_position_info *aggpos, enum tree_code code, tree val) { int i; @@ -265,6 +266,7 @@ add_condition (struct inline_summary *summary, int operand_num, for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++) { if (c->operand_num == operand_num + && c->size == size && c->code == code && c->val == val && c->agg_contents == agg_contents @@ -281,6 +283,7 @@ add_condition (struct inline_summary *summary, int operand_num, new_cond.agg_contents = agg_contents; new_cond.by_ref = by_ref; new_cond.offset = offset; + new_cond.size = size; vec_safe_push (summary->conds, new_cond); return single_cond_predicate (i + predicate_first_dynamic_condition); } @@ -859,21 +862,25 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, clause |= 1 << (i + predicate_first_dynamic_condition); continue; } - if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) + if (c->code == CHANGED) continue; - if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)), - TYPE_SIZE (TREE_TYPE (val)), 0)) + if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size) { - val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); + clause |= 1 << (i + predicate_first_dynamic_condition); + continue; + } + if (c->code == IS_NOT_CONSTANT) + continue; - res = val - ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) - : NULL; + val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); + res = val + ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) + : NULL; + + if (res && integer_zerop (res)) + continue; - if (res && integer_zerop (res)) - continue; - } clause |= 1 << (i + predicate_first_dynamic_condition); } return clause; @@ -1495,16 +1502,21 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED, } /* If OP refers to value of function parameter, return the corresponding - parameter. */ + parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the + PARM_DECL) will be stored to *SIZE_P in that case too. */ static tree -unmodified_parm_1 (gimple stmt, tree op) +unmodified_parm_1 (gimple stmt, tree op, HOST_WIDE_INT *size_p) { /* SSA_NAME referring to parm default def? */ if (TREE_CODE (op) == SSA_NAME && SSA_NAME_IS_DEFAULT_DEF (op) && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL) - return SSA_NAME_VAR (op); + { + if (size_p) + *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op))); + return SSA_NAME_VAR (op); + } /* Non-SSA parm reference? */ if (TREE_CODE (op) == PARM_DECL) { @@ -1515,18 +1527,24 @@ unmodified_parm_1 (gimple stmt, tree op) walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified, NULL); if (!modified) - return op; + { + if (size_p) + *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op))); + return op; + } } return NULL_TREE; } /* If OP refers to value of function parameter, return the corresponding - parameter. Also traverse chains of SSA register assignments. */ + parameter. Also traverse chains of SSA register assignments. If non-NULL, + the size of the memory load (or the SSA_NAME of the PARM_DECL) will be + stored to *SIZE_P in that case too. */ static tree -unmodified_parm (gimple stmt, tree op) +unmodified_parm (gimple stmt, tree op, HOST_WIDE_INT *size_p) { - tree res = unmodified_parm_1 (stmt, op); + tree res = unmodified_parm_1 (stmt, op, size_p); if (res) return res; @@ -1534,23 +1552,25 @@ unmodified_parm (gimple stmt, tree op) && !SSA_NAME_IS_DEFAULT_DEF (op) && gimple_assign_single_p (SSA_NAME_DEF_STMT (op))) return unmodified_parm (SSA_NAME_DEF_STMT (op), - gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op))); + gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)), + size_p); return NULL_TREE; } /* If OP refers to a value of a function parameter or value loaded from an aggregate passed to a parameter (either by value or reference), return TRUE - and store the number of the parameter to *INDEX_P and information whether - and how it has been loaded from an aggregate into *AGGPOS. INFO describes - the function parameters, STMT is the statement in which OP is used or - loaded. */ + and store the number of the parameter to *INDEX_P, the access size into + *SIZE_P, and information whether and how it has been loaded from an + aggregate into *AGGPOS. INFO describes the function parameters, STMT is the + statement in which OP is used or loaded. */ static bool unmodified_parm_or_parm_agg_item (struct ipa_node_params *info, gimple stmt, tree op, int *index_p, + HOST_WIDE_INT *size_p, struct agg_position_info *aggpos) { - tree res = unmodified_parm_1 (stmt, op); + tree res = unmodified_parm_1 (stmt, op, size_p); gcc_checking_assert (aggpos); if (res) @@ -1572,12 +1592,12 @@ unmodified_parm_or_parm_agg_item (struct ipa_node_params *info, op = gimple_assign_rhs1 (stmt); if (!REFERENCE_CLASS_P (op)) return unmodified_parm_or_parm_agg_item (info, stmt, op, index_p, - aggpos); + size_p, aggpos); } aggpos->agg_contents = true; return ipa_load_from_parm_agg (info, stmt, op, index_p, &aggpos->offset, - &aggpos->by_ref); + size_p, &aggpos->by_ref); } /* See if statement might disappear after inlining. @@ -1629,7 +1649,7 @@ eliminated_by_inlining_prob (gimple stmt) inner_lhs = lhs; /* Reads of parameter are expected to be free. */ - if (unmodified_parm (stmt, inner_rhs)) + if (unmodified_parm (stmt, inner_rhs, NULL)) rhs_free = true; /* Match expressions of form &this->field. Those will most likely combine with something upstream after inlining. */ @@ -1639,7 +1659,7 @@ eliminated_by_inlining_prob (gimple stmt) if (TREE_CODE (op) == PARM_DECL) rhs_free = true; else if (TREE_CODE (op) == MEM_REF - && unmodified_parm (stmt, TREE_OPERAND (op, 0))) + && unmodified_parm (stmt, TREE_OPERAND (op, 0), NULL)) rhs_free = true; } @@ -1652,7 +1672,7 @@ eliminated_by_inlining_prob (gimple stmt) /* Reads of parameters passed by reference expected to be free (i.e. optimized out after inlining). */ if (TREE_CODE (inner_rhs) == MEM_REF - && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0))) + && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0), NULL)) rhs_free = true; /* Copying parameter passed by reference into gimple register is @@ -1693,7 +1713,7 @@ eliminated_by_inlining_prob (gimple stmt) if (TREE_CODE (inner_lhs) == PARM_DECL || TREE_CODE (inner_lhs) == RESULT_DECL || (TREE_CODE (inner_lhs) == MEM_REF - && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0)) + && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0), NULL) || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0)) && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND @@ -1723,6 +1743,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, { gimple last; tree op; + HOST_WIDE_INT size; int index; struct agg_position_info aggpos; enum tree_code code, inverted_code; @@ -1740,7 +1761,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, /* TODO: handle conditionals like var = op0 < 4; if (var != 0). */ - if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos)) + if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &size, &aggpos)) { code = gimple_cond_code (last); inverted_code @@ -1756,7 +1777,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, unordered one. Be sure it is not confused with NON_CONSTANT. */ if (this_code != ERROR_MARK) { - struct predicate p = add_condition (summary, index, &aggpos, + struct predicate p = add_condition (summary, index, size, &aggpos, this_code, gimple_cond_rhs (last)); e->aux = pool_alloc (edge_predicate_pool); @@ -1786,11 +1807,11 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info, return; op2 = gimple_call_arg (set_stmt, 0); if (!unmodified_parm_or_parm_agg_item - (info, set_stmt, op2, &index, &aggpos)) + (info, set_stmt, op2, &index, &size, &aggpos)) return; FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE) { - struct predicate p = add_condition (summary, index, &aggpos, + struct predicate p = add_condition (summary, index, size, &aggpos, IS_NOT_CONSTANT, NULL_TREE); e->aux = pool_alloc (edge_predicate_pool); *(struct predicate *) e->aux = p; @@ -1809,6 +1830,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, gimple last; tree op; int index; + HOST_WIDE_INT size; struct agg_position_info aggpos; edge e; edge_iterator ei; @@ -1819,7 +1841,7 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, if (!last || gimple_code (last) != GIMPLE_SWITCH) return; op = gimple_switch_index (last); - if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos)) + if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &size, &aggpos)) return; FOR_EACH_EDGE (e, ei, bb->succs) @@ -1844,12 +1866,12 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info, if (!min && !max) p = true_predicate (); else if (!max) - p = add_condition (summary, index, &aggpos, EQ_EXPR, min); + p = add_condition (summary, index, size, &aggpos, EQ_EXPR, min); else { struct predicate p1, p2; - p1 = add_condition (summary, index, &aggpos, GE_EXPR, min); - p2 = add_condition (summary, index, &aggpos, LE_EXPR, max); + p1 = add_condition (summary, index, size, &aggpos, GE_EXPR, min); + p2 = add_condition (summary, index, size, &aggpos, LE_EXPR, max); p = and_predicates (summary->conds, &p1, &p2); } *(struct predicate *) e->aux @@ -1949,13 +1971,14 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info, { tree parm; int index; + HOST_WIDE_INT size; while (UNARY_CLASS_P (expr)) expr = TREE_OPERAND (expr, 0); - parm = unmodified_parm (NULL, expr); + parm = unmodified_parm (NULL, expr, &size); if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0) - return add_condition (summary, index, NULL, CHANGED, NULL_TREE); + return add_condition (summary, index, size, NULL, CHANGED, NULL_TREE); if (is_gimple_min_invariant (expr)) return false_predicate (); if (TREE_CODE (expr) == SSA_NAME) @@ -2016,6 +2039,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, struct predicate op_non_const; bool is_load; int base_index; + HOST_WIDE_INT size; struct agg_position_info aggpos; /* What statments might be optimized away @@ -2039,7 +2063,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, tree op; gcc_assert (gimple_assign_single_p (stmt)); op = gimple_assign_rhs1 (stmt); - if (!unmodified_parm_or_parm_agg_item (info, stmt, op, &base_index, + if (!unmodified_parm_or_parm_agg_item (info, stmt, op, &base_index, &size, &aggpos)) return p; } @@ -2050,7 +2074,7 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, adding conditionals. */ FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) { - tree parm = unmodified_parm (stmt, use); + tree parm = unmodified_parm (stmt, use, NULL); /* For arguments we can build a condition. */ if (parm && ipa_get_param_decl_index (info, parm) >= 0) continue; @@ -2065,18 +2089,18 @@ will_be_nonconstant_predicate (struct ipa_node_params *info, if (is_load) op_non_const = - add_condition (summary, base_index, &aggpos, CHANGED, NULL); + add_condition (summary, base_index, size, &aggpos, CHANGED, NULL); else op_non_const = false_predicate (); FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) { - tree parm = unmodified_parm (stmt, use); + tree parm = unmodified_parm (stmt, use, &size); int index; if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0) { if (index != base_index) - p = add_condition (summary, index, NULL, CHANGED, NULL_TREE); + p = add_condition (summary, index, size, NULL, CHANGED, NULL_TREE); else continue; } @@ -3300,7 +3324,8 @@ remap_predicate (struct inline_summary *info, ap.by_ref = c->by_ref; cond_predicate = add_condition (info, operand_map[c->operand_num], - &ap, c->code, c->val); + c->size, &ap, c->code, + c->val); } } /* Fixed conditions remains same, construct single @@ -4119,6 +4144,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, { struct condition c; c.operand_num = streamer_read_uhwi (&ib); + c.size = streamer_read_uhwi (&ib); c.code = (enum tree_code) streamer_read_uhwi (&ib); c.val = stream_read_tree (&ib, data_in); bp = streamer_read_bitpack (&ib); @@ -4280,6 +4306,7 @@ inline_write_summary (void) for (i = 0; vec_safe_iterate (info->conds, i, &c); i++) { streamer_write_uhwi (ob, c->operand_num); + streamer_write_uhwi (ob, c->size); streamer_write_uhwi (ob, c->code); stream_write_tree (ob, c->val, true); bp = bitpack_create (ob->main_stream); diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h index 7860dec..110ed4f 100644 --- a/gcc/ipa-inline.h +++ b/gcc/ipa-inline.h @@ -32,6 +32,8 @@ struct GTY(()) condition /* If agg_contents is set, this is the offset from which the used data was loaded. */ HOST_WIDE_INT offset; + /* Size of the access reading the data (or the PARM_DECL SSA_NAME). */ + HOST_WIDE_INT size; tree val; int operand_num; ENUM_BITFIELD(tree_code) code : 16; diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index c3890f7..4840dda 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -971,10 +971,10 @@ ipa_load_from_parm_agg_1 (vec descriptors, bool ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt, tree op, int *index_p, HOST_WIDE_INT *offset_p, - bool *by_ref_p) + HOST_WIDE_INT *size_p, bool *by_ref_p) { return ipa_load_from_parm_agg_1 (info->descriptors, NULL, stmt, op, index_p, - offset_p, NULL, by_ref_p); + offset_p, size_p, by_ref_p); } /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 70185b2..5b3e8cd 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -594,7 +594,7 @@ void ipa_analyze_node (struct cgraph_node *); tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT, bool); bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *, - HOST_WIDE_INT *, bool *); + HOST_WIDE_INT *, HOST_WIDE_INT *, bool *); /* Debugging interface. */ void ipa_print_node_params (FILE *, struct cgraph_node *node); diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 51b1903..62a5fe0 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -141,7 +141,7 @@ along with GCC; see the file COPYING3. If not see #define LTO_SECTION_NAME_PREFIX ".gnu.lto_" #define LTO_major_version 3 -#define LTO_minor_version 0 +#define LTO_minor_version 1 typedef unsigned char lto_decl_flags_t; diff --git a/gcc/testsuite/gcc.dg/ipa/pr70646.c b/gcc/testsuite/gcc.dg/ipa/pr70646.c new file mode 100644 index 0000000..f85816e --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr70646.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#pragma GCC optimize("no-unit-at-a-time") + +typedef unsigned char u8; +typedef unsigned long long u64; + +static inline __attribute__((always_inline)) u64 __swab64p(const u64 *p) +{ + return (__builtin_constant_p((u64)(*p)) ? ((u64)( (((u64)(*p) & (u64)0x00000000000000ffULL) << 56) | (((u64)(*p) & (u64)0x000000000000ff00ULL) << 40) | (((u64)(*p) & (u64)0x0000000000ff0000ULL) << 24) | (((u64)(*p) & (u64)0x00000000ff000000ULL) << 8) | (((u64)(*p) & (u64)0x000000ff00000000ULL) >> 8) | (((u64)(*p) & (u64)0x0000ff0000000000ULL) >> 24) | (((u64)(*p) & (u64)0x00ff000000000000ULL) >> 40) | (((u64)(*p) & (u64)0xff00000000000000ULL) >> 56))) : __builtin_bswap64(*p)); +} + +static inline u64 wwn_to_u64(void *wwn) +{ + return __swab64p(wwn); +} + +void __attribute__((noinline,noclone)) broken(u64* shost) +{ + u8 node_name[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + *shost = wwn_to_u64(node_name); +} + +void __attribute__((noinline,noclone)) dummy(void) +{ + __builtin_abort(); +} + +int main(int argc, char* argv[]) +{ + u64 v; + + broken(&v); + + if(v != (u64)-1) + __builtin_abort(); + + return 0; +}