From patchwork Tue Jun 28 15:30:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 2361 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 319E624067 for ; Tue, 28 Jun 2011 15:30:34 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id CDBF5A18430 for ; Tue, 28 Jun 2011 15:30:33 +0000 (UTC) Received: by qwb8 with SMTP id 8so227468qwb.11 for ; Tue, 28 Jun 2011 08:30:33 -0700 (PDT) Received: by 10.224.64.213 with SMTP id f21mr543171qai.159.1309275033156; Tue, 28 Jun 2011 08:30:33 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.48.135 with SMTP id r7cs11657qcf; Tue, 28 Jun 2011 08:30:32 -0700 (PDT) Received: by 10.227.205.202 with SMTP id fr10mr6571037wbb.60.1309275028202; Tue, 28 Jun 2011 08:30:28 -0700 (PDT) Received: from mail-wy0-f178.google.com (mail-wy0-f178.google.com [74.125.82.178]) by mx.google.com with ESMTPS id fq6si718095wbb.15.2011.06.28.08.30.26 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 28 Jun 2011 08:30:27 -0700 (PDT) Received-SPF: pass (google.com: domain of andrew.stubbs@gmail.com designates 74.125.82.178 as permitted sender) client-ip=74.125.82.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of andrew.stubbs@gmail.com designates 74.125.82.178 as permitted sender) smtp.mail=andrew.stubbs@gmail.com; dkim=pass (test mode) header.i=@gmail.com Received: by wyf19 with SMTP id 19so273076wyf.37 for ; Tue, 28 Jun 2011 08:30:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type; bh=RQoPHEqU1/Xnb08OwTEDCqgZqyWQwrJ0GDNU/tX02oE=; b=ei9u9e9/skLlC4XmflPDRDSaql27e/VCAn3+Egf+7j76flvmBwM6epfKfk8mCAyIZT a3+ws6lcY5HI1UqqGcYEqRjC+nWJ5JvJfZNcsCJ9h3G62PHORf0UqVC5JoyjgQhqPJgS tJONr/+C/Tut/E41beJ+/VR98iG0lPBTyoOTo= Received: by 10.227.32.84 with SMTP id b20mr6641238wbd.105.1309275026596; Tue, 28 Jun 2011 08:30:26 -0700 (PDT) Received: from [192.168.0.100] (cpc2-hawk4-0-0-cust828.aztw.cable.virginmedia.com [82.32.123.61]) by mx.google.com with ESMTPS id et5sm240370wbb.16.2011.06.28.08.30.23 (version=SSLv3 cipher=OTHER); Tue, 28 Jun 2011 08:30:25 -0700 (PDT) Message-ID: <4E09F38D.8000606@codesourcery.com> Date: Tue, 28 Jun 2011 16:30:21 +0100 From: Andrew Stubbs User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110516 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org CC: patches@linaro.org Subject: Re: [PATCH (6/7)] More widening multiply-and-accumulate pattern matching References: <4E034EF2.3070503@codesourcery.com> <4E0350EF.4090500@codesourcery.com> In-Reply-To: <4E0350EF.4090500@codesourcery.com> On 23/06/11 15:42, Andrew Stubbs wrote: > This patch fixes the case where widening multiply-and-accumulate were > not recognised because the multiplication itself is not actually widening. > > This can happen when you have "DI + SI * SI" - the multiplication will > be done in SImode as a non-widening multiply, and it's only the final > accumulate step that is widening. > > This was not recognised for two reasons: > > 1. is_widening_mult_p inferred the output type from the multiply > statement, which in not useful in this case. > > 2. The inputs to the multiply instruction may not have been converted at > all (because they're not being widened), so the pattern match failed. > > The patch fixes these issues by making the output type explicit, and by > permitting unconverted inputs (the types are still checked, so this is > safe). > > OK? This update fixes Janis' testsuite issue. Andrew 2011-06-28 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 @@ -1963,7 +1963,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 @@ -1973,32 +1974,32 @@ 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 = 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; + 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 = gimple_assign_lhs (stmt); + else + *new_rhs_out = rhs1; *type_out = type1; return true; } @@ -2013,28 +2014,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) @@ -2084,7 +2084,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); @@ -2193,14 +2193,14 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, if (code == PLUS_EXPR && rhs1_code == 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; } else if (rhs2_code == 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;