From patchwork Tue May 24 16:43:33 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 97180 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 E6751B6F95 for ; Wed, 25 May 2011 02:43:58 +1000 (EST) Received: (qmail 21291 invoked by alias); 24 May 2011 16:43:56 -0000 Received: (qmail 21267 invoked by uid 22791); 24 May 2011 16:43:54 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD 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; Tue, 24 May 2011 16:43:38 +0000 Received: (qmail 27234 invoked from network); 24 May 2011 16:43:37 -0000 Received: from unknown (HELO ?192.168.0.100?) (ams@127.0.0.2) by mail.codesourcery.com with ESMTPA; 24 May 2011 16:43:37 -0000 Message-ID: <4DDBE035.8050901@codesourcery.com> Date: Tue, 24 May 2011 17:43:33 +0100 From: Andrew Stubbs User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110424 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: Bernd Schmidt CC: Richard Earnshaw , gcc-patches@gcc.gnu.org Subject: Re: [patch][simplify-rtx] Fix 16-bit -> 64-bit multiply and accumulate References: <4D01018F.3020108@codesourcery.com> <1296153619.9738.16.camel@e102346-lin.cambridge.arm.com> <4D42955C.1060707@codesourcery.com> <1296223929.9738.30.camel@e102346-lin.cambridge.arm.com> <4D42DD32.7020404@codesourcery.com> <1296228038.9738.48.camel@e102346-lin.cambridge.arm.com> <4D8CC0A9.5080504@codesourcery.com> <4DA823F1.2040907@codesourcery.com> <4DBFC5D8.1090009@codesourcery.com> In-Reply-To: <4DBFC5D8.1090009@codesourcery.com> 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 03/05/11 10:07, Bernd Schmidt wrote: > I tried to fix it with the patch below, which unfortunately doesn't work > since during combine we don't see the SIGN_EXTEND operations inside the > MULT, but two shift operations instead. Maybe you can complete it from here? I've tried to make this patch go various ways, and I always find a test case that doesn't quite work. I think we're approaching it from the wrong angle. The problem is that widening multiplies are required to be defined as (mult (extend ..) (extend ..)), but when the combiner tries to build a widening multiply pattern from a regular multiply it naturally ends up as (extend (mult .. ..)). The result is that the patch Benrd posted made existing widening multiplies wider, but failed to convert regular multiplies to widening ones. I've created this new, simpler patch that converts (extend (mult a b)) into (mult (extend a) (extend b)) regardless of what 'a' and 'b' might be. (These are then simplified and superfluous extends removed, of course.) I find that this patch fixes all the testcases I have, and permitted me to add support for ARM smlalbt/smlaltb/smlaltt also (I'll post that in a separate patch). It does assume that the outer sign_extend/zero_extend indicates the inner extend types though, so I'm not sure if there's a problem there? OK? Andrew 2011-05-24 Bernd Schmidt Andrew Stubbs gcc/ * simplify-rtx.c (simplify_unary_operation_1): Create a new canonical form for widening multiplies. * doc/md.texi (Canonicalization of Instructions): Document widening multiply canonicalization. gcc/testsuite/ * gcc.target/arm/mla-2.c: New test. --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5840,6 +5840,11 @@ Equality comparisons of a group of bits (usually a single bit) with zero will be written using @code{zero_extract} rather than the equivalent @code{and} or @code{sign_extract} operations. +@cindex @code{mult}, canonicalization of +@item +@code{(sign_extend:@var{m1} (mult:@var{m2} @var{x} @var{y}))} is converted +to @code{(mult:@var{m1} (sign_extend:@var{m1} @var{x}) (sign_extend:@var{m1} @var{y}))}, and likewise for @code{zero_extract}. + @end itemize Further canonicalization rules are defined in the function --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1000,6 +1000,21 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF) return XEXP (op, 0); + /* Convert (sign_extend (mult ..)) to a canonical widening + mulitplication (mult (sign_extend ..) (sign_extend ..)). */ + if (GET_CODE (op) == MULT && GET_MODE (op) < mode) + { + rtx lhs = XEXP (op, 0); + rtx rhs = XEXP (op, 1); + enum machine_mode lhs_mode = GET_MODE (lhs); + enum machine_mode rhs_mode = GET_MODE (rhs); + return simplify_gen_binary (MULT, mode, + simplify_gen_unary (SIGN_EXTEND, mode, + lhs, lhs_mode), + simplify_gen_unary (SIGN_EXTEND, mode, + rhs, rhs_mode)); + } + /* Check for a sign extension of a subreg of a promoted variable, where the promotion is sign-extended, and the target mode is the same as the variable's promotion. */ @@ -1071,6 +1086,21 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) return rtl_hooks.gen_lowpart_no_emit (mode, op); + /* Convert (zero_extend (mult ..)) to a canonical widening + mulitplication (mult (zero_extend ..) (zero_extend ..)). */ + if (GET_CODE (op) == MULT && GET_MODE (op) < mode) + { + rtx lhs = XEXP (op, 0); + rtx rhs = XEXP (op, 1); + enum machine_mode lhs_mode = GET_MODE (lhs); + enum machine_mode rhs_mode = GET_MODE (rhs); + return simplify_gen_binary (MULT, mode, + simplify_gen_unary (ZERO_EXTEND, mode, + lhs, lhs_mode), + simplify_gen_unary (ZERO_EXTEND, mode, + rhs, rhs_mode)); + } + /* (zero_extend:M (zero_extend:N )) is (zero_extend:M ). */ if (GET_CODE (op) == ZERO_EXTEND) return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0), --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/mla-2.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=armv7-a" } */ + +long long foolong (long long x, short *a, short *b) +{ + return x + *a * *b; +} + +/* { dg-final { scan-assembler "smlalbb" } } */