From patchwork Mon May 7 20:16:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 157411 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 1B579B6FA9 for ; Tue, 8 May 2012 06:17:07 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1337026628; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Subject:Message-ID:User-Agent:MIME-Version:Content-Type: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=q2VS5jo+KCaIMnboPoXY obOUUVc=; b=BJgYd4u4ezCdYAusRi8+7mrw35fHR1Na94j2B8ZFpXmY0r6JY7pY Sum7azcoigHMG7I2aSpJgN2gH/TNuE+p3Rn6Y1HTym8R2B0+HmREGtPwCZzJTGwP raCACsy6QlEpt/tpH4ftIEf20KalOoH0V53rabOukyIlcHK6vGONlrA= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Subject:Message-ID:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=ii90NkoXaKhETyzmmcWFmupa3O28AUuYYXSha93kHRoLfo8zBu6EuatsovzXSY AwEWYtEfQ6X4AtpS7YFdX12fn/nj2hbIWIRQ9uX2+S0zs5uYfKYRnUvhPTITw7DK vCQ1qT6RSUF2uaLwoi8vmiUGpE3DjE21gCI7l3zFtluag=; Received: (qmail 20532 invoked by alias); 7 May 2012 20:17:03 -0000 Received: (qmail 20520 invoked by uid 22791); 7 May 2012 20:17:02 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, TW_AV, TW_UF, TW_VP, TW_VS, TW_VX, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail1-relais-roc.national.inria.fr (HELO mail1-relais-roc.national.inria.fr) (192.134.164.82) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 May 2012 20:16:48 +0000 Received: from afontenayssb-151-1-47-226.w82-121.abo.wanadoo.fr (HELO laptop-mg.local) ([82.121.94.226]) by mail1-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 07 May 2012 22:16:30 +0200 Date: Mon, 7 May 2012 22:16:24 +0200 (CEST) From: Marc Glisse To: gcc-patches@gcc.gnu.org Subject: [rtl, patch] combine concat+shuffle Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 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 Hello, this patch combines for vectors a concat and a shuffle. An example on x86 would be: __m128d f(double d){ __m128d x=_mm_setr_pd(-d,d); return _mm_shuffle_pd(x,x,1); } which was compiled as: vmovsd .LC0(%rip), %xmm1 vxorpd %xmm0, %xmm1, %xmm1 vunpcklpd %xmm0, %xmm1, %xmm0 vshufpd $1, %xmm0, %xmm0, %xmm0 and with the patch: vmovsd .LC0(%rip), %xmm1 vxorpd %xmm0, %xmm1, %xmm1 vunpcklpd %xmm1, %xmm0, %xmm0 This happens a lot in my code, for interval arithmetics, where I have a number d, build an interval (-d,d) from it, then subtract that interval from an other one, and subtraction is implemented as shufpd+addpd. The patch is quite specialized, but I guessed I could start there, and it can always be generalized later. For the testsuite, since the patch is not in a particular target, it would be better to have a generic test (in gcc.dg?), but I don't really know how to write a generic one, so would a test in gcc.target/i386 that scans the asm for shuf or perm be ok? Ah, and if I use __builtin_shuffle instead of _mm_shuffle_pd, the patch works without -mavx, but -mavx uses vpermilpd (ie a vec_select:V2DF (reg:V2DF) ...) instead of a vshufpd, so I'll probably want to handle that too later. I thought about doing a general transformation from vec_select(vec_concat(x,x),*) to vec_select(x,*) (reducing the indexes in * so they fit), but that seemed way too dangerous. Index: simplify-rtx.c =================================================================== --- simplify-rtx.c (revision 187228) +++ simplify-rtx.c (working copy) @@ -3268,10 +3268,32 @@ simplify_binary_operation_1 (enum rtx_co if (GET_MODE (vec) == mode) return vec; } + /* If we build {a,b} then permute it, build the result directly. */ + if (XVECLEN (trueop1, 0) == 2 + && CONST_INT_P (XVECEXP (trueop1, 0, 0)) + && CONST_INT_P (XVECEXP (trueop1, 0, 1)) + && GET_CODE (trueop0) == VEC_CONCAT + && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop0, 1)) + && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT + && GET_MODE (XEXP (trueop0, 0)) == mode) + { + int offset0 = INTVAL (XVECEXP (trueop1, 0, 0)) % 2; + int offset1 = INTVAL (XVECEXP (trueop1, 0, 1)) % 2; + rtx baseop = XEXP (trueop0, 0); + rtx baseop0 = XEXP (baseop , 0); + rtx baseop1 = XEXP (baseop , 1); + baseop0 = avoid_constant_pool_reference (baseop0); + baseop1 = avoid_constant_pool_reference (baseop1); + + return simplify_gen_binary (VEC_CONCAT, mode, + offset0 ? baseop1 : baseop0, + offset1 ? baseop1 : baseop0); + } + return 0; case VEC_CONCAT: { enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode ? GET_MODE (trueop0)