From patchwork Tue Apr 29 13:50:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evgeny Stupachenko X-Patchwork-Id: 343842 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 558911400B5 for ; Tue, 29 Apr 2014 23:50:16 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; q=dns; s=default; b=kULTzYFsdlwA1zDtLTwFEW7CmOizjTO8TB4yPO5IMjt 6hbvBCaDKT2cKqtGloofvoAcV/AMor23KEUukL2uMJ2APhSsX+e/9YR+wZ5sQdyk l9cgdOgng4RBKbX15hDzxnnUQrUIDBsSRtXWcWJJ014rcT7wpKqdP5cnwOWWGiRI = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; s=default; bh=gOWjtxdMtObjCw5C1mSTlSFuUrw=; b=bQDO01EUQrZnXuf17 HB7vVhVyt9ZtMe3l4Q1IQsNe/cwdHQA3Ps1DRJ2iA6j/Oj8gJ8t1HCF7ruiskq+d F1TTYRaVJkBeTPoBn87wT4Mkw6Z1ucqfFyIIUP/NNhORGRflXDtRzkyj54AWR80u 6f6B/iMW9igVP5Bf6KE9OUC2+M= Received: (qmail 29237 invoked by alias); 29 Apr 2014 13:50:07 -0000 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 Received: (qmail 29227 invoked by uid 89); 29 Apr 2014 13:50:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ob0-f176.google.com Received: from mail-ob0-f176.google.com (HELO mail-ob0-f176.google.com) (209.85.214.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 29 Apr 2014 13:50:05 +0000 Received: by mail-ob0-f176.google.com with SMTP id wp4so245469obc.21 for ; Tue, 29 Apr 2014 06:50:03 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.60.231.134 with SMTP id tg6mr939560oec.84.1398779403736; Tue, 29 Apr 2014 06:50:03 -0700 (PDT) Received: by 10.76.170.39 with HTTP; Tue, 29 Apr 2014 06:50:03 -0700 (PDT) Date: Tue, 29 Apr 2014 17:50:03 +0400 Message-ID: Subject: [PATCH 2/2, x86] Add palignr support for AVX2. From: Evgeny Stupachenko To: GCC Patches , Richard Biener , Uros Bizjak Cc: "H.J. Lu" , Richard Henderson X-IsSubscribed: yes Hi, The patch adds use of palignr instruction, when we have one operand permutation like: {5 6 7 0 1 2 3 4}: Treating this as {5 6 7 8 9 a b c} on 2 operands, and therefore palignr on 5. Bootstrap and make check passed. Is it ok? Evgeny 2014-04-29 Evgeny Stupachenko * config/i386/i386.c (expand_vec_perm_palignr_one_operand): New. Enables PALIGNR on one operand permutation. * config/i386/i386.c (expand_vec_perm_1): Try PALIGNR on one operand. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 002d295..8950cf7 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -42807,6 +42807,97 @@ expand_vec_perm_pshufb (struct expand_vec_perm_d *d) return true; } +/* A subroutine of ix86_expand_vec_perm_1. Try to use just palignr + instruction for one operand permutation. This is better than pshufb + as does not require to pass big constant and faster on some x86 + architectures. */ + +static bool +expand_vec_perm_palignr_one_operand (struct expand_vec_perm_d *d) +{ + unsigned i, nelt = d->nelt; + unsigned min; + unsigned in_order_length, in_order_length_max; + rtx shift, shift1, target, tmp; + + /* PALIGNR of 2 128-bits registers takes only 1 instrucion. + Requires SSSE3. */ + if (GET_MODE_SIZE (d->vmode) == 16) + { + if(!TARGET_SSSE3) + return false; + } + /* PALIGNR of 2 256-bits registers on AVX2 costs only 2 instructions: + PERM and PALIGNR. It is more profitable than 2 PSHUFB and PERM. */ + else if (GET_MODE_SIZE (d->vmode) == 32) + { + if(!TARGET_AVX2) + return false; + } + else + return false; + + if (d->one_operand_p != true) + return false; + + /* For an in order permutation with one operand like: {5 6 7 0 1 2 3 4} + PALIGNR is better than PSHUFB. Check for an order in permutation. */ + in_order_length = 0; + in_order_length_max = 0; + if (d->one_operand_p == true) + for (i = 0; i < 2 * nelt; ++i) + { + if ((d->perm[(i + 1) & (nelt - 1)] - + d->perm[i & (nelt - 1)]) != 1) + { + if (in_order_length > in_order_length_max) + in_order_length_max = in_order_length; + in_order_length = 0; + } + else + in_order_length++; + } + + /* If not an ordered permutation then try something else. */ + if (in_order_length_max != nelt - 1) + return false; + + min = d->perm[0]; + + shift = GEN_INT (min * GET_MODE_BITSIZE (GET_MODE_INNER (d->vmode))); + shift1 = GEN_INT ((min - nelt / 2) * + GET_MODE_BITSIZE (GET_MODE_INNER (d->vmode))); + + if (GET_MODE_SIZE (d->vmode) != 32) + { + target = gen_reg_rtx (TImode); + emit_insn (gen_ssse3_palignrti (target, gen_lowpart (TImode, d->op1), + gen_lowpart (TImode, d->op0), shift)); + } + else + { + target = gen_reg_rtx (V2TImode); + tmp = gen_reg_rtx (V4DImode); + emit_insn (gen_avx2_permv2ti (tmp, + gen_lowpart (V4DImode, d->op0), + gen_lowpart (V4DImode, d->op1), + GEN_INT (33))); + if (min < nelt / 2) + emit_insn (gen_avx2_palignrv2ti (target, + gen_lowpart (V2TImode, tmp), + gen_lowpart (V2TImode, d->op0), + shift)); + else + emit_insn (gen_avx2_palignrv2ti (target, + gen_lowpart (V2TImode, d->op1), + gen_lowpart (V2TImode, tmp), + shift1)); + } + emit_move_insn (d->target, gen_lowpart (d->vmode, target)); + + return true; +} + static bool expand_vec_perm_vpshufb2_vpermq (struct expand_vec_perm_d *d); /* A subroutine of ix86_expand_vec_perm_builtin_1. Try to instantiate D @@ -42943,6 +43034,10 @@ expand_vec_perm_1 (struct expand_vec_perm_d *d) if (expand_vec_perm_vpermil (d)) return true; + /* Try palignr on one operand. */ + if (expand_vec_perm_palignr_one_operand (d)) + return true; + /* Try the SSSE3 pshufb or XOP vpperm or AVX2 vperm2i128, vpshufb, vpermd, vpermps or vpermq variable permutation. */ if (expand_vec_perm_pshufb (d))