From patchwork Fri Dec 10 15:12:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Sayle X-Patchwork-Id: 48787 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4E270385780A for ; Fri, 10 Dec 2021 15:12:26 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from server.nextmovesoftware.com (server.nextmovesoftware.com [162.254.253.69]) by sourceware.org (Postfix) with ESMTPS id 838433858022 for ; Fri, 10 Dec 2021 15:12:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 838433858022 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nextmovesoftware.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nextmovesoftware.com; s=default; h=Content-Type:MIME-Version:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=x8YggS8BWKTAT5/0pzCXKiS4YaKWsemSIl7SBvJxY88=; b=n2AOUgda2En+Sa7wQED9RKGRag LYEl5kfhAnH6V/iU57sNYcblyVHPmwSKf17SwKs7mjruydXxjJsi2IDcAz7TBkYuzoVpW6qNcIdyP /iFX1pYsUJboHSrAnSysIhyXkRsZ2Xqu1iMYXBdB2jiErlUs9l/CesGr/P60hqggNs8t30+2dus+G pnF7ERUuAVW7rmDoihiFbLk9+qLfhy31o9a+R5Ts2iE1ZZgMl5FkGENAU6lFkJ3ECRmA9kGLgfIgh cT2uWe0w109FZ8xmdSCZq6XD7miyCvr7WXygPZkHQ9icPp7PgUPfbdaZABHL1N7nF1o0tDIFZgQZR gTwp06Ww==; Received: from [185.62.158.67] (port=60577 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1mvhZ9-0001y8-V1 for gcc-patches@gcc.gnu.org; Fri, 10 Dec 2021 10:12:08 -0500 From: "Roger Sayle" To: "'GCC Patches'" Subject: [PATCH] mips: Improved RTL representation of wsbh/dsbh/dshd Date: Fri, 10 Dec 2021 15:12:06 -0000 Message-ID: <003a01d7edd8$4c4b2170$e4e16450$@nextmovesoftware.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: Adft12dXcLNrbQnzSw2sY/8gbSUJfw== Content-Language: en-gb X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.nextmovesoftware.com X-AntiAbuse: Original Domain - gcc.gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - nextmovesoftware.com X-Get-Message-Sender-Via: server.nextmovesoftware.com: authenticated_id: roger@nextmovesoftware.com X-Authenticated-Sender: server.nextmovesoftware.com: roger@nextmovesoftware.com X-Source: X-Source-Args: X-Source-Dir: X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This patch to the mips backend updates the representations used internally for MIPS' wsbh, dsbh and dshd instructions. These were previously described using an UNSPEC rtx, which prevents simplification at the RTL level. In addition to now being able to eliminate rotate instructions before/after wsbh, allowing a wsbh to be emitted without a backend builtin, these new representations also allow dsbh and dshd to be synthesized from standard C/C++ vector idioms. This patch has been tested by a make bootstrap and make -k check on mips-unknown-linux-gnu, with --enable-multiarch --enable-multilib --enable-targets=all --with-arch-32=mips32r2 --with-arch-64=mips64r2 (thanks to the compile farm's gcc230.fsffrance.org) and a cross-compiler to mips64-linux-gnu hosted on x86_64-pc-linux-gnu. Ok for mainline? 2021-12-10 Roger Sayle gcc/ChangeLog * config/mips/mips.c (mips_vector_mode_supported_p): Allow V4HI and V8QI modes on TARGET_64BIT with ISA_HAS_WSBH. (mips_expand_vec_perm_const_1): With one_vector_p, try expanding a vselect directly before an interleaved variant. * mips.md (UNSPEC_WSBH, UNSPEC_DSBH, UNSPEC_DSHD): Delete. (bswapsi2): Change from define_insn_and_split to an expander. (bswapdi2): Change from define_insn_and_split to an expander. (wsbh): Represent as SI rotate by 16 of a bswap32. (wsbh_2): Also recognize as a bswap32 of a rotatert:SI ... 16. (wsbh_v4qi): Recognize wsbh from a vec_select:V4QI. (wsbh_v2hi): Recognize wsbh from a vec_select:V2HI. (dsbh): Represent as a DImode cast of a vec_select:V8QI. (dsbh_v8qi): Recognize dsbh from a vec_select:V8QI. (dshd): Represent as a DImode cast of a vec_select:V8QI. (dshd_v8qi): Recognize dshd from a vec_select:V8QI. (dshd_v4hi): Recognize dshd from a vec_select:V4HI. gcc/testsuite/ChangeLog * gcc.target/mips/dsbh-v8qi.c: New test case. * gcc.target/mips/dshd-v4hi.c: New test case. * gcc.target/mips/dshd-v8qi.c: New test case. * gcc.target/mips/wsbh.c: New test case. Thanks in advance, Roger diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 807bf1a..c5699d6 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -13407,9 +13407,12 @@ mips_vector_mode_supported_p (machine_mode mode) return TARGET_DSP; case E_V2SImode: + return TARGET_LOONGSON_MMI; + case E_V4HImode: case E_V8QImode: - return TARGET_LOONGSON_MMI; + return TARGET_LOONGSON_MMI + || (TARGET_64BIT && ISA_HAS_WSBH); default: return MSA_SUPPORTED_MODE_P (mode); @@ -21608,6 +21611,9 @@ mips_expand_vec_perm_const_1 (struct expand_vec_perm_d *d) if (d->one_vector_p) { + if (mips_expand_vselect (d->target, d->op0, d->perm, nelt)) + return true; + /* Try interleave with alternating operands. */ memcpy (perm2, d->perm, sizeof(perm2)); for (i = 1; i < nelt; i += 2) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 455b9b8..21364d6 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -81,11 +81,6 @@ UNSPEC_STORE_LEFT UNSPEC_STORE_RIGHT - ;; Integer operations that are too cumbersome to describe directly. - UNSPEC_WSBH - UNSPEC_DSBH - UNSPEC_DSHD - ;; Floating-point moves. UNSPEC_LOAD_LOW UNSPEC_LOAD_HIGH @@ -5866,45 +5861,139 @@ "wsbh\t%0,%1" [(set_attr "type" "shift")]) -(define_insn_and_split "bswapsi2" +(define_expand "bswapsi2" [(set (match_operand:SI 0 "register_operand" "=d") (bswap:SI (match_operand:SI 1 "register_operand" "d")))] "ISA_HAS_WSBH && ISA_HAS_ROR" - "#" - "&& 1" - [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_WSBH)) - (set (match_dup 0) (rotatert:SI (match_dup 0) (const_int 16)))] - "" - [(set_attr "insn_count" "2")]) +{ + rtx tmp = gen_reg_rtx (SImode); + emit_insn (gen_wsbh (tmp, operands[1])); + emit_insn (gen_rotrsi3 (operands[0], tmp, GEN_INT (16))); + DONE; +}) -(define_insn_and_split "bswapdi2" +(define_expand "bswapdi2" [(set (match_operand:DI 0 "register_operand" "=d") (bswap:DI (match_operand:DI 1 "register_operand" "d")))] "TARGET_64BIT && ISA_HAS_WSBH" - "#" - "&& 1" - [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_DSBH)) - (set (match_dup 0) (unspec:DI [(match_dup 0)] UNSPEC_DSHD))] - "" - [(set_attr "insn_count" "2")]) +{ + rtx tmp = gen_reg_rtx (DImode); + emit_insn (gen_dsbh (tmp, operands[1])); + emit_insn (gen_dshd (operands[0], tmp)); + DONE; +}) (define_insn "wsbh" [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_operand:SI 1 "register_operand" "d")] UNSPEC_WSBH))] + (rotatert:SI (bswap:SI (match_operand:SI 1 "register_operand" "d")) + (const_int 16)))] + "ISA_HAS_WSBH" + "wsbh\t%0,%1" + [(set_attr "type" "shift")]) + +;; Non-canonical variant of wsbh +(define_insn "wsbh_2" + [(set (match_operand:SI 0 "register_operand" "=d") + (bswap:SI (rotatert:SI (match_operand:SI 1 "register_operand" "d") + (const_int 16))))] + "ISA_HAS_WSBH" + "wsbh\t%0,%1" + [(set_attr "type" "shift")]) + +;; V4QI form of wsbh +(define_insn "wsbh_v4qi" + [(set (match_operand:V4QI 0 "register_operand") + (vec_select:V4QI (match_operand:V4QI 1 "register_operand") + (parallel [(const_int 1) + (const_int 0) + (const_int 3) + (const_int 2)])))] + "ISA_HAS_WSBH" + "wsbh\t%0,%1" + [(set_attr "type" "shift")]) + +;; V2HI form of wsbh +(define_insn "wsbh_v2hi" + [(set (match_operand:V2HI 0 "register_operand") + (vec_select:V2HI (match_operand:V2HI 1 "register_operand") + (parallel [(const_int 1) + (const_int 0)])))] "ISA_HAS_WSBH" "wsbh\t%0,%1" [(set_attr "type" "shift")]) (define_insn "dsbh" - [(set (match_operand:DI 0 "register_operand" "=d") - (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSBH))] + [(set (subreg:V8QI (match_operand:DI 0 "register_operand" "=d") 0) + (vec_select:V8QI + (subreg:V8QI (match_operand:DI 1 "register_operand" "d") 0) + (parallel [(const_int 1) + (const_int 0) + (const_int 3) + (const_int 2) + (const_int 5) + (const_int 4) + (const_int 7) + (const_int 6)])))] + "TARGET_64BIT && ISA_HAS_WSBH" + "dsbh\t%0,%1" + [(set_attr "type" "shift")]) + +;; V8QI form of dsbh +(define_insn "dsbh_v8qi" + [(set (match_operand:V8QI 0 "register_operand" "=d") + (vec_select:V8QI (match_operand:V8QI 1 "register_operand") + (parallel [(const_int 1) + (const_int 0) + (const_int 3) + (const_int 2) + (const_int 5) + (const_int 4) + (const_int 7) + (const_int 6)])))] "TARGET_64BIT && ISA_HAS_WSBH" "dsbh\t%0,%1" [(set_attr "type" "shift")]) (define_insn "dshd" - [(set (match_operand:DI 0 "register_operand" "=d") - (unspec:DI [(match_operand:DI 1 "register_operand" "d")] UNSPEC_DSHD))] + [(set (subreg:V8QI (match_operand:DI 0 "register_operand" "=d") 0) + (vec_select:V8QI + (subreg:V8QI (match_operand:DI 1 "register_operand" "d") 0) + (parallel [(const_int 6) + (const_int 7) + (const_int 4) + (const_int 5) + (const_int 2) + (const_int 3) + (const_int 0) + (const_int 1)])))] + "TARGET_64BIT && ISA_HAS_WSBH" + "dshd\t%0,%1" + [(set_attr "type" "shift")]) + +;; V8QI form of dshd +(define_insn "dshd_v8qi" + [(set (match_operand:V8QI 0 "register_operand" "=d") + (vec_select:V8QI (match_operand:V8QI 1 "register_operand") + (parallel [(const_int 6) + (const_int 7) + (const_int 4) + (const_int 5) + (const_int 2) + (const_int 3) + (const_int 0) + (const_int 1)])))] + "TARGET_64BIT && ISA_HAS_WSBH" + "dshd\t%0,%1" + [(set_attr "type" "shift")]) + +;; V4HI form of dshd +(define_insn "dshd_v4hi" + [(set (match_operand:V4HI 0 "register_operand" "=d") + (vec_select:V4HI (match_operand:V4HI 1 "register_operand") + (parallel [(const_int 3) + (const_int 2) + (const_int 1) + (const_int 0)])))] "TARGET_64BIT && ISA_HAS_WSBH" "dshd\t%0,%1" [(set_attr "type" "shift")]) diff --git a/gcc/testsuite/gcc.target/mips/dsbh-v8qi.c b/gcc/testsuite/gcc.target/mips/dsbh-v8qi.c new file mode 100644 index 0000000..0bb7a1a --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dsbh-v8qi.c @@ -0,0 +1,12 @@ +/* { dg-options "isa_rev>=2 -mgp64" } */ + +typedef char v8qi __attribute__((vector_size (8))); + +long long foo(long long x) +{ + v8qi t = (v8qi)x; + t = __builtin_shufflevector (t, t, 1, 0, 3, 2, 5, 4, 7, 6); + return (long long)t; +} + +/* { dg-final { scan-assembler "\tdsbh\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/dshd-v4hi.c b/gcc/testsuite/gcc.target/mips/dshd-v4hi.c new file mode 100644 index 0000000..309468f --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dshd-v4hi.c @@ -0,0 +1,13 @@ +/* { dg-options "isa_rev>=2 -mgp64" } */ + +typedef short v4hi __attribute__((vector_size (8))); + +long long foo(long long x) +{ + v4hi t = (v4hi)x; + t = __builtin_shufflevector (t, t, 3, 2, 1, 0); + return (long long)t; +} + +/* { dg-final { scan-assembler "\tdshd\t" } } */ + diff --git a/gcc/testsuite/gcc.target/mips/dshd-v8qi.c b/gcc/testsuite/gcc.target/mips/dshd-v8qi.c new file mode 100644 index 0000000..f07a735 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/dshd-v8qi.c @@ -0,0 +1,12 @@ +/* { dg-options "isa_rev>=2 -mgp64" } */ + +typedef char v8qi __attribute__((vector_size (8))); + +long long foo(long long x) +{ + v8qi t = (v8qi)x; + t = __builtin_shufflevector (t, t, 6, 7, 4, 5, 2, 3, 0, 1); + return (long long)t; +} + +/* { dg-final { scan-assembler "\tdshd\t" } } */ diff --git a/gcc/testsuite/gcc.target/mips/wsbh.c b/gcc/testsuite/gcc.target/mips/wsbh.c new file mode 100644 index 0000000..5f6c37b --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/wsbh.c @@ -0,0 +1,18 @@ +/* { dg-options "isa_rev>=2" } */ +/* { dg-skip-if "bswap recognition needs expensive optimizations" { *-*-* } { "-O0" "-O1" } { "" } } */ + +unsigned int foo(unsigned int x) +{ + unsigned int t = __builtin_bswap32(x); + return (t>>16) | (t<<16); +} + +unsigned int bar(unsigned int x) +{ + unsigned int t = (x>>16) | (x<<16); + return __builtin_bswap32(t); +} + +/* { dg-final { scan-assembler-times "\twsbh\t" 2 } } */ +/* { dg-final { scan-assembler-not "\tror\t" } } */ +