From patchwork Mon Jul 4 14:29:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 2439 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 3B65C23F53 for ; Mon, 4 Jul 2011 14:29:41 +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 DF088A182CF for ; Mon, 4 Jul 2011 14:29:40 +0000 (UTC) Received: by qwb8 with SMTP id 8so3567284qwb.11 for ; Mon, 04 Jul 2011 07:29:40 -0700 (PDT) Received: by 10.229.54.12 with SMTP id o12mr1069810qcg.80.1309789780354; Mon, 04 Jul 2011 07:29:40 -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 r7cs29504qcf; Mon, 4 Jul 2011 07:29:39 -0700 (PDT) Received: by 10.236.79.226 with SMTP id i62mr7178678yhe.282.1309789779495; Mon, 04 Jul 2011 07:29:39 -0700 (PDT) Received: from mail.codesourcery.com (mail.codesourcery.com [38.113.113.100]) by mx.google.com with ESMTPS id s2si19055166icx.14.2011.07.04.07.29.38 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 04 Jul 2011 07:29:39 -0700 (PDT) Received-SPF: pass (google.com: domain of ams@codesourcery.com designates 38.113.113.100 as permitted sender) client-ip=38.113.113.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ams@codesourcery.com designates 38.113.113.100 as permitted sender) smtp.mail=ams@codesourcery.com Received: (qmail 27613 invoked from network); 4 Jul 2011 14:29:37 -0000 Received: from unknown (HELO ?192.168.0.100?) (ams@127.0.0.2) by mail.codesourcery.com with ESMTPA; 4 Jul 2011 14:29:37 -0000 Message-ID: <4E11CE4F.1020102@codesourcery.com> Date: Mon, 04 Jul 2011 15:29:35 +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 CC: gcc-patches@gcc.gnu.org, patches@linaro.org Subject: Re: [PATCH (5/7)] Widening multiplies for mis-matched mode inputs References: <4E034EF2.3070503@codesourcery.com> <4E0350B7.7080802@codesourcery.com> <4E09EE62.9070900@codesourcery.com> In-Reply-To: <4E09EE62.9070900@codesourcery.com> On 28/06/11 16:08, Andrew Stubbs wrote: > On 23/06/11 15:41, Andrew Stubbs wrote: >> This patch removes the restriction that the inputs to a widening >> multiply must be of the same mode. >> >> It does this by extending the smaller of the two inputs to match the >> larger; therefore, it remains the case that subsequent code (in the >> expand pass, for example) can rely on the type of rhs1 being the input >> type of the operation, and the gimple verification code is still valid. >> >> OK? > > This update fixes the testcase issue Janis highlighted. And this one updates the context changed by my update to patch 3. The content of the patch has not changed. Andrew 2011-06-28 Andrew Stubbs gcc/ * tree-ssa-math-opts.c (is_widening_mult_p): Remove FIXME. Ensure the the larger type is the first operand. (convert_mult_to_widen): Insert cast if type2 is smaller than type1. (convert_plusminus_to_widen): Likewise. gcc/testsuite/ * gcc.target/arm/wmul-7.c: New file. --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/wmul-7.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv7-a" } */ + +unsigned long long +foo (unsigned long long a, unsigned char *b, unsigned short *c) +{ + return a + *b * *c; +} + +/* { dg-final { scan-assembler "umlal" } } */ --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -2051,9 +2051,17 @@ is_widening_mult_p (gimple stmt, *type2_out = *type1_out; } - /* FIXME: remove this restriction. */ - if (TYPE_PRECISION (*type1_out) != TYPE_PRECISION (*type2_out)) - return false; + /* Ensure that the larger of the two operands comes first. */ + if (TYPE_PRECISION (*type1_out) < TYPE_PRECISION (*type2_out)) + { + tree tmp; + tmp = *type1_out; + *type1_out = *type2_out; + *type2_out = tmp; + tmp = *rhs1_out; + *rhs1_out = *rhs2_out; + *rhs2_out = tmp; + } return true; } @@ -2069,6 +2077,7 @@ convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi) enum insn_code handler; enum machine_mode to_mode, from_mode; optab op; + int cast1 = false, cast2 = false; lhs = gimple_assign_lhs (stmt); type = TREE_TYPE (lhs); @@ -2107,16 +2116,26 @@ convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi) return false; type1 = type2 = lang_hooks.types.type_for_mode (from_mode, 0); - - rhs1 = build_and_insert_cast (gsi, gimple_location (stmt), - create_tmp_var (type1, NULL), rhs1, type1); - rhs2 = build_and_insert_cast (gsi, gimple_location (stmt), - create_tmp_var (type2, NULL), rhs2, type2); + cast1 = cast2 = true; } else return false; } + if (TYPE_MODE (type2) != from_mode) + { + type2 = lang_hooks.types.type_for_mode (from_mode, + TYPE_UNSIGNED (type2)); + cast2 = true; + } + + if (cast1) + rhs1 = build_and_insert_cast (gsi, gimple_location (stmt), + create_tmp_var (type1, NULL), rhs1, type1); + if (cast2) + rhs2 = build_and_insert_cast (gsi, gimple_location (stmt), + create_tmp_var (type2, NULL), rhs2, type2); + gimple_assign_set_rhs1 (stmt, fold_convert (type1, rhs1)); gimple_assign_set_rhs2 (stmt, fold_convert (type2, rhs2)); gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR); @@ -2215,6 +2234,7 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, optab this_optab; enum tree_code wmult_code; enum insn_code handler; + int cast1 = false, cast2 = false; lhs = gimple_assign_lhs (stmt); type = TREE_TYPE (lhs); @@ -2302,17 +2322,28 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (TYPE_MODE (type))) { type1 = type2 = lang_hooks.types.type_for_mode (mode, 0); - mult_rhs1 = build_and_insert_cast (gsi, gimple_location (stmt), - create_tmp_var (type1, NULL), - mult_rhs1, type1); - mult_rhs2 = build_and_insert_cast (gsi, gimple_location (stmt), - create_tmp_var (type2, NULL), - mult_rhs2, type2); + cast1 = cast2 = true; } else return false; } + if (TYPE_MODE (type2) != TYPE_MODE (type1)) + { + type2 = lang_hooks.types.type_for_mode (TYPE_MODE (type1), + TYPE_UNSIGNED (type2)); + cast2 = true; + } + + if (cast1) + mult_rhs1 = build_and_insert_cast (gsi, gimple_location (stmt), + create_tmp_var (type1, NULL), + mult_rhs1, type1); + if (cast2) + mult_rhs2 = build_and_insert_cast (gsi, gimple_location (stmt), + create_tmp_var (type2, NULL), + mult_rhs2, type2); + /* Verify that the convertions between the mult and the add doesn't do anything unexpected. */ if (!valid_types_for_madd_p (type1, type2, mult_rhs))