From patchwork Sat Jun 15 17:50:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 1948193 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=xry111.site header.i=@xry111.site header.a=rsa-sha256 header.s=default header.b=S9Fh3rHK; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4W1kH30kB5z20Pb for ; Sun, 16 Jun 2024 03:51:39 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 31DE4388264C for ; Sat, 15 Jun 2024 17:51:35 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 9807F387084B for ; Sat, 15 Jun 2024 17:51:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9807F387084B Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9807F387084B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1718473877; cv=none; b=jI5FpZpK7PtJAkbMNKEozwd9NEcTGlhkMxlneh0b9qTS65+4gvJvDZoYTDq0Pe4c+pKBK54qZSMhJCgM0iJd9AK3KKgtpucCYFwXjpgb0kEe/Di8xyHiKzxcbvR8tZ+UZQ9RlyAof+dQzOe9jHQmN3Y64wXiufw8FkeUJu46pTQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1718473877; c=relaxed/simple; bh=EGY6DVuO/2X//At8sAJqFpWPyVZkNyxbK7o5pEeC6EM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=qHaGp8QCBb9tx8/uFAI4kBjxD1IFTo9nFVYPUEKbio9a6syogW8nonzAnAvzij9yUj5THwO14JCyd4IQPFqcp0GaTSDsFOGCTEKmXTs4lKWkyBMqz5ssOtuKOrrxFNMiLyKlnDcIHEZmykR8Sfb3c+H0GhlFtWB+rIRyfVo9Erg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1718473872; bh=EGY6DVuO/2X//At8sAJqFpWPyVZkNyxbK7o5pEeC6EM=; h=From:To:Cc:Subject:Date:From; b=S9Fh3rHKREvt2IB9r70/5aKbm9aG9OuchW4pgFBIx8YrvZl9UY8eodftJGS3dga9y MrM8WMowRZpS5Qwwv3ECtAHzVj5Z7gtxAzPaEOUAYG2MnJfNRisDgYJkDRxjaOhcin S1KYtzyZypbvVufFlE5KGdlsfL2/UrQ8OCpSxx44= Received: from stargazer.. (unknown [IPv6:240e:358:1141:3000:dc73:854d:832e:2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 4685966499; Sat, 15 Jun 2024 13:51:08 -0400 (EDT) From: Xi Ruoyao To: gcc-patches@gcc.gnu.org Cc: chenglulu , i@xen0n.name, xuchenghua@loongson.cn, Xi Ruoyao Subject: [PATCH v2] LoongArch: Tweak IOR rtx_cost for bstrins Date: Sun, 16 Jun 2024 01:50:46 +0800 Message-ID: <20240615175102.1837-1-xry111@xry111.site> X-Mailer: git-send-email 2.45.2 MIME-Version: 1.0 X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Consider c &= 0xfff; a &= ~0xfff; b &= ~0xfff; a |= c; b |= c; This can be done with 2 bstrins instructions. But we need to recognize it in loongarch_rtx_costs or the compiler will not propagate "c & 0xfff" forward. gcc/ChangeLog: * config/loongarch/loongarch.cc: (loongarch_use_bstrins_for_ior_with_mask): Split the main logic into ... (loongarch_use_bstrins_for_ior_with_mask_1): ... here. (loongarch_rtx_costs): Special case for IOR those can be implemented with bstrins. gcc/testsuite/ChangeLog; * gcc.target/loongarch/bstrins-3.c: New test. --- Bootstrapped and regtested on loongarch64-linux-gnu. Ok for trunk? gcc/config/loongarch/loongarch.cc | 73 ++++++++++++++----- .../gcc.target/loongarch/bstrins-3.c | 16 ++++ 2 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/bstrins-3.c diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 6ec3ee62502..256b76d044b 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -3681,6 +3681,27 @@ loongarch_set_reg_reg_piece_cost (machine_mode mode, unsigned int units) return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units); } +static int +loongarch_use_bstrins_for_ior_with_mask_1 (machine_mode mode, + unsigned HOST_WIDE_INT mask1, + unsigned HOST_WIDE_INT mask2) +{ + if (mask1 != ~mask2 || !mask1 || !mask2) + return 0; + + /* Try to avoid a right-shift. */ + if (low_bitmask_len (mode, mask1) != -1) + return -1; + + if (low_bitmask_len (mode, mask2 >> (ffs_hwi (mask2) - 1)) != -1) + return 1; + + if (low_bitmask_len (mode, mask1 >> (ffs_hwi (mask1) - 1)) != -1) + return -1; + + return 0; +} + /* Return the cost of moving between two registers of mode MODE. */ static int @@ -3812,6 +3833,38 @@ loongarch_rtx_costs (rtx x, machine_mode mode, int outer_code, /* Fall through. */ case IOR: + { + rtx op[2] = {XEXP (x, 0), XEXP (x, 1)}; + if (GET_CODE (op[0]) == AND && GET_CODE (op[1]) == AND + && (mode == SImode || (TARGET_64BIT && mode == DImode))) + { + rtx rtx_mask0 = XEXP (op[0], 1), rtx_mask1 = XEXP (op[1], 1); + if (CONST_INT_P (rtx_mask0) && CONST_INT_P (rtx_mask1)) + { + unsigned HOST_WIDE_INT mask0 = UINTVAL (rtx_mask0); + unsigned HOST_WIDE_INT mask1 = UINTVAL (rtx_mask1); + if (loongarch_use_bstrins_for_ior_with_mask_1 (mode, + mask0, + mask1)) + { + /* A bstrins instruction */ + *total = COSTS_N_INSNS (1); + + /* A srai instruction */ + if (low_bitmask_len (mode, mask0) == -1 + && low_bitmask_len (mode, mask1) == -1) + *total += COSTS_N_INSNS (1); + + for (int i = 0; i < 2; i++) + *total += set_src_cost (XEXP (op[i], 0), mode, speed); + + return true; + } + } + } + } + + /* Fall through. */ case XOR: /* Double-word operations use two single-word operations. */ *total = loongarch_binary_cost (x, COSTS_N_INSNS (1), COSTS_N_INSNS (2), @@ -5796,23 +5849,9 @@ bool loongarch_pre_reload_split (void) int loongarch_use_bstrins_for_ior_with_mask (machine_mode mode, rtx *op) { - unsigned HOST_WIDE_INT mask1 = UINTVAL (op[2]); - unsigned HOST_WIDE_INT mask2 = UINTVAL (op[4]); - - if (mask1 != ~mask2 || !mask1 || !mask2) - return 0; - - /* Try to avoid a right-shift. */ - if (low_bitmask_len (mode, mask1) != -1) - return -1; - - if (low_bitmask_len (mode, mask2 >> (ffs_hwi (mask2) - 1)) != -1) - return 1; - - if (low_bitmask_len (mode, mask1 >> (ffs_hwi (mask1) - 1)) != -1) - return -1; - - return 0; + return loongarch_use_bstrins_for_ior_with_mask_1 (mode, + UINTVAL (op[2]), + UINTVAL (op[4])); } /* Rewrite a MEM for simple load/store under -mexplicit-relocs=auto diff --git a/gcc/testsuite/gcc.target/loongarch/bstrins-3.c b/gcc/testsuite/gcc.target/loongarch/bstrins-3.c new file mode 100644 index 00000000000..13762bdef42 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/bstrins-3.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-final" } */ +/* { dg-final { scan-rtl-dump-times "insv\[sd\]i" 2 "final" } } */ + +struct X { + long a, b; +}; + +struct X +test (long a, long b, long c) +{ + c &= 0xfff; + a &= ~0xfff; + b &= ~0xfff; + return (struct X){.a = a | c, .b = b | c}; +}