From patchwork Thu Jan 18 19:54:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Sayle X-Patchwork-Id: 84364 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 393A93858401 for ; Thu, 18 Jan 2024 19:55: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 88DD83858D33 for ; Thu, 18 Jan 2024 19:54:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 88DD83858D33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=nextmovesoftware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nextmovesoftware.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 88DD83858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=162.254.253.69 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705607693; cv=none; b=i9dsZ1L8wU9TLbuk1FyX3WEsGinWgOXGeV3Uu2ga6IBSnGK3EPPMe0Hn6/kccDVDP5+JFia4Jxz9VRYgZA3ScwXRPIwmE9bsb/YWoQbHcw2N4GvChKKL47hbrLJ4tRJpbcKPLT1mR5woMB0unNdLqCScB761En7NwYuHb46Crp0= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705607693; c=relaxed/simple; bh=GlgztELFYqx1Zw37OZR/2aiFmbu/Way9Q/FNxsKsixQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=GNAmzyolJqatNEcAZN9ZJDERqc4GTKvAlE76J48KOzUhdyXRbG+4cUV7i6LoAsZwfKts59ewgq4MZuQyzkrvm7qfa7fBl32HI7DDyl9c5tLS1WNaOV4YDk7rUYnzCGInz0lVLyyjvfQLiZGq+MmK8tOLj/EmcL3Bjwh9qbQk0qk= ARC-Authentication-Results: i=1; server2.sourceware.org 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=R8ZgkptbH6SxXHQj2qdsgYRuIZepyhqacFD3xULMoBg=; b=YIqw2ry1KzTZ1pI6H1L8DfFF5r u5qFn8/8iExIoHJX6lcB0/2u63e9HXghXsufo0heVvmwGGAOG2rWpTjvjhaFUFyzi9Ji3WS8xrZp5 oI1mEYrJW/Pj+OuDUZozn1xKFPu5bI3L36b4GSnnQdA53XzMR+n4foZWuTy76hiXTcoGxG4K4qXbK Tjcm6IsTepLJhOwSt34DqYpLFewSGuw5wMAT6PWeCVFr1ufcb3HARCIW6ZMSJvJWVl2wDo/mTs7nB 7u+4weFqPI2uBhL6a9altexUzPqY4BpleN3n9+TO6T10LXzT3K3Yh9leQXAKEe9gP+t478XPSs/+V mOnQCk6w==; Received: from host109-154-238-190.range109-154.btcentralplus.com ([109.154.238.190]:52627 helo=Dell) by server.nextmovesoftware.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1rQYTR-0001b1-2x; Thu, 18 Jan 2024 14:54:50 -0500 From: "Roger Sayle" To: Subject: [middle-end PATCH] Prefer PLUS over IOR in RTL expansion of multi-word shifts/rotates. Date: Thu, 18 Jan 2024 19:54:47 -0000 Message-ID: <023501da4a48$320e7540$962b5fc0$@nextmovesoftware.com> MIME-Version: 1.0 X-Mailer: Microsoft Outlook 16.0 Thread-Index: AdpKR2xVlZL0yXRTSYm++Sw+cEfGHw== 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.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, 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+patchwork=sourceware.org@gcc.gnu.org This patch tweaks RTL expansion of multi-word shifts and rotates to use PLUS rather than IOR for disjunctive operations. During expansion of these operations, the middle-end creates RTL like (X<>C2) where the constants C1 and C2 guarantee that bits don't overlap. Hence the IOR can be performed by any any_or_plus operation, such as IOR, XOR or PLUS; for word-size operations where carry chains aren't an issue these should all be equally fast (single-cycle) instructions. The benefit of this change is that targets with shift-and-add insns, like x86's lea, can benefit from the LSHIFT-ADD form. An example of a backend that benefits is ARC, which is demonstrated by these two simple functions: unsigned long long foo(unsigned long long x) { return x<<2; } which with -O2 is currently compiled to: foo: lsr r2,r0,30 asl_s r1,r1,2 asl_s r0,r0,2 j_s.d [blink] or_s r1,r1,r2 with this patch becomes: foo: lsr r2,r0,30 add2 r1,r2,r1 j_s.d [blink] asl_s r0,r0,2 unsigned long long bar(unsigned long long x) { return (x<<2)|(x>>62); } which with -O2 is currently compiled to 6 insns + return: bar: lsr r12,r0,30 asl_s r3,r1,2 asl_s r0,r0,2 lsr_s r1,r1,30 or_s r0,r0,r1 j_s.d [blink] or r1,r12,r3 with this patch becomes 4 insns + return: bar: lsr r3,r1,30 lsr r2,r0,30 add2 r1,r2,r1 j_s.d [blink] add2 r0,r3,r0 This patch has been tested on x86_64-pc-linux-gnu with make bootstrap and make -k check, both with and without --target_board=unix{-m32} with no new failures. Ok for mainline? 2024-01-18 Roger Sayle gcc/ChangeLog * expmed.cc (expand_shift_1): Use add_optab instead of ior_optab to generate PLUS instead or IOR when unioning disjoint bitfields. * optabs.cc (expand_subword_shift): Likewise. (expand_binop): Likewise for double-word rotate. Thanks in advance, Roger diff --git a/gcc/expmed.cc b/gcc/expmed.cc index 5916d6ed1bc..d1900f97f0c 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -2610,10 +2610,11 @@ expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted, else if (methods == OPTAB_LIB_WIDEN) { /* If we have been unable to open-code this by a rotation, - do it as the IOR of two shifts. I.e., to rotate A - by N bits, compute + do it as the IOR or PLUS of two shifts. I.e., to rotate + A by N bits, compute (A << N) | ((unsigned) A >> ((-N) & (C - 1))) - where C is the bitsize of A. + where C is the bitsize of A. If N cannot be zero, + use PLUS instead of IOR. It is theoretically possible that the target machine might not be able to perform either shift and hence we would @@ -2650,8 +2651,9 @@ expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted, temp1 = expand_shift_1 (left ? RSHIFT_EXPR : LSHIFT_EXPR, mode, shifted, other_amount, subtarget, 1); - return expand_binop (mode, ior_optab, temp, temp1, target, - unsignedp, methods); + return expand_binop (mode, + CONST_INT_P (op1) ? add_optab : ior_optab, + temp, temp1, target, unsignedp, methods); } temp = expand_binop (mode, diff --git a/gcc/optabs.cc b/gcc/optabs.cc index ce91f94ed43..dcd3e406719 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -566,8 +566,8 @@ expand_subword_shift (scalar_int_mode op1_mode, optab binoptab, if (tmp == 0) return false; - /* Now OR in the bits carried over from OUTOF_INPUT. */ - if (!force_expand_binop (word_mode, ior_optab, tmp, carries, + /* Now OR/PLUS in the bits carried over from OUTOF_INPUT. */ + if (!force_expand_binop (word_mode, add_optab, tmp, carries, into_target, unsignedp, methods)) return false; } @@ -1937,7 +1937,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, NULL_RTX, unsignedp, next_methods); if (into_temp1 != 0 && into_temp2 != 0) - inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2, + inter = expand_binop (word_mode, add_optab, into_temp1, into_temp2, into_target, unsignedp, next_methods); else inter = 0; @@ -1953,7 +1953,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, NULL_RTX, unsignedp, next_methods); if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0) - inter = expand_binop (word_mode, ior_optab, + inter = expand_binop (word_mode, add_optab, outof_temp1, outof_temp2, outof_target, unsignedp, next_methods);