From patchwork Thu Jul 14 14:34:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 104686 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 5034FB6F18 for ; Fri, 15 Jul 2011 00:34:42 +1000 (EST) Received: (qmail 7426 invoked by alias); 14 Jul 2011 14:34:40 -0000 Received: (qmail 7411 invoked by uid 22791); 14 Jul 2011 14:34:39 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_TM X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 14 Jul 2011 14:34:23 +0000 Received: (qmail 10879 invoked from network); 14 Jul 2011 14:34:22 -0000 Received: from unknown (HELO ?192.168.0.100?) (ams@127.0.0.2) by mail.codesourcery.com with ESMTPA; 14 Jul 2011 14:34:22 -0000 Message-ID: <4E1EFE6A.7070300@codesourcery.com> Date: Thu, 14 Jul 2011 15:34:18 +0100 From: Andrew Stubbs User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20110627 Thunderbird/5.0 MIME-Version: 1.0 To: Richard Guenther CC: gcc-patches@gcc.gnu.org, patches@linaro.org Subject: Re: [PATCH (6/7)] More widening multiply-and-accumulate pattern matching References: <4E034EF2.3070503@codesourcery.com> <4E0350EF.4090500@codesourcery.com> <4E09F38D.8000606@codesourcery.com> <4E11CEDF.6060004@codesourcery.com> In-Reply-To: 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 On 07/07/11 11:13, Richard Guenther wrote: >> This updates the context changed by my update to patch 3. >> > >> > The content of this patch has not changed. > Ok. I know this patch was already approved, but I discovered a bug in this patch that missed optimizing the case where the input to multiply did not come from an assign statement (this can happen when the value comes from a function parameter). This patch fixes that case, and updates the context changed by my updates earlier in the patch series. OK? Andrew 2011-07-14 Andrew Stubbs gcc/ * tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument 'type'. Use 'type' from caller, not inferred from 'rhs'. Don't reject non-conversion statements. Do return lhs in this case. (is_widening_mult_p): Add new argument 'type'. Use 'type' from caller, not inferred from 'stmt'. Pass type to is_widening_mult_rhs_p. (convert_mult_to_widen): Pass type to is_widening_mult_p. (convert_plusminus_to_widen): Likewise. gcc/testsuite/ * gcc.target/arm/wmul-8.c: New file. --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/wmul-8.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv7-a" } */ + +long long +foo (long long a, int *b, int *c) +{ + return a + *b * *c; +} + +/* { dg-final { scan-assembler "smlal" } } */ --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1965,7 +1965,8 @@ struct gimple_opt_pass pass_optimize_bswap = } }; -/* Return true if RHS is a suitable operand for a widening multiplication. +/* Return true if RHS is a suitable operand for a widening multiplication, + assuming a target type of TYPE. There are two cases: - RHS makes some value at least twice as wide. Store that value @@ -1975,32 +1976,43 @@ struct gimple_opt_pass pass_optimize_bswap = but leave *TYPE_OUT untouched. */ static bool -is_widening_mult_rhs_p (tree rhs, tree *type_out, tree *new_rhs_out) +is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out, + tree *new_rhs_out) { gimple stmt; - tree type, type1, rhs1; + tree type1, rhs1; enum tree_code rhs_code; if (TREE_CODE (rhs) == SSA_NAME) { - type = TREE_TYPE (rhs); stmt = SSA_NAME_DEF_STMT (rhs); if (!is_gimple_assign (stmt)) - return false; - - rhs_code = gimple_assign_rhs_code (stmt); - if (TREE_CODE (type) == INTEGER_TYPE - ? !CONVERT_EXPR_CODE_P (rhs_code) - : rhs_code != FIXED_CONVERT_EXPR) - return false; + { + rhs1 = NULL; + type1 = TREE_TYPE (rhs); + } + else + { + rhs1 = gimple_assign_rhs1 (stmt); + type1 = TREE_TYPE (rhs1); + } - rhs1 = gimple_assign_rhs1 (stmt); - type1 = TREE_TYPE (rhs1); if (TREE_CODE (type1) != TREE_CODE (type) || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type)) return false; - *new_rhs_out = rhs1; + if (rhs1) + { + rhs_code = gimple_assign_rhs_code (stmt); + if (TREE_CODE (type) == INTEGER_TYPE + ? !CONVERT_EXPR_CODE_P (rhs_code) + : rhs_code != FIXED_CONVERT_EXPR) + *new_rhs_out = rhs; + else + *new_rhs_out = rhs1; + } + else + *new_rhs_out = rhs; *type_out = type1; return true; } @@ -2015,28 +2027,27 @@ is_widening_mult_rhs_p (tree rhs, tree *type_out, tree *new_rhs_out) return false; } -/* Return true if STMT performs a widening multiplication. If so, - store the unwidened types of the operands in *TYPE1_OUT and *TYPE2_OUT - respectively. Also fill *RHS1_OUT and *RHS2_OUT such that converting - those operands to types *TYPE1_OUT and *TYPE2_OUT would give the - operands of the multiplication. */ +/* Return true if STMT performs a widening multiplication, assuming the + output type is TYPE. If so, store the unwidened types of the operands + in *TYPE1_OUT and *TYPE2_OUT respectively. Also fill *RHS1_OUT and + *RHS2_OUT such that converting those operands to types *TYPE1_OUT + and *TYPE2_OUT would give the operands of the multiplication. */ static bool -is_widening_mult_p (gimple stmt, +is_widening_mult_p (tree type, gimple stmt, tree *type1_out, tree *rhs1_out, tree *type2_out, tree *rhs2_out) { - tree type; - - type = TREE_TYPE (gimple_assign_lhs (stmt)); if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != FIXED_POINT_TYPE) return false; - if (!is_widening_mult_rhs_p (gimple_assign_rhs1 (stmt), type1_out, rhs1_out)) + if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out, + rhs1_out)) return false; - if (!is_widening_mult_rhs_p (gimple_assign_rhs2 (stmt), type2_out, rhs2_out)) + if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out, + rhs2_out)) return false; if (*type1_out == NULL) @@ -2088,7 +2099,7 @@ convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi) if (TREE_CODE (type) != INTEGER_TYPE) return false; - if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2)) + if (!is_widening_mult_p (type, stmt, &type1, &rhs1, &type2, &rhs2)) return false; to_mode = TYPE_MODE (type); @@ -2254,7 +2265,7 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, if (code == PLUS_EXPR && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR)) { - if (!is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1, + if (!is_widening_mult_p (type, rhs1_stmt, &type1, &mult_rhs1, &type2, &mult_rhs2)) return false; add_rhs = rhs2; @@ -2262,7 +2273,7 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, } else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR) { - if (!is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1, + if (!is_widening_mult_p (type, rhs2_stmt, &type1, &mult_rhs1, &type2, &mult_rhs2)) return false; add_rhs = rhs1;