From patchwork Mon Jan 8 14:43:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 1883738 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=a5PyaOBf; 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 4T7xfW3SZyz1yP7 for ; Tue, 9 Jan 2024 01:44:35 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 70495385842D for ; Mon, 8 Jan 2024 14:44:33 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by sourceware.org (Postfix) with ESMTPS id 01A983858CDB for ; Mon, 8 Jan 2024 14:44:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 01A983858CDB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 01A983858CDB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::12f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704725052; cv=none; b=wsPHQXcc72ypTxmxcHd8p+kjwSpFzsuToid11DA6kDiftBsrBmrFO+SghwKReS/ahWCIkMze9nFDSpGF2QCFqJ/8KejCip5ery6ifbO/JKCGUNha7yNxNt5kZjWYldFejVRcHYWFSS8WUq9RNqFmbzEl+b3eeGQSRZIlaYlqNPw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704725052; c=relaxed/simple; bh=tCD4271ZDn2vxTNZclxp/n40cNCmufflY9a91iEonH4=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=PQZGZO7l4vSCoMwQhAEjx/VtyeKLgIH4yPVy5NrXnJVtTaN3IQF1m78vyKh0G52zhHOzd1bJagHJPECO4UEf8VtlnnJLOcrS8s67Erjc3kOPA3wnFiwR5hHPxfiYBF6NA+hge8qJoKmTHLKrEh+ytvkjXGplfcFSjF7bfDTOq1w= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lf1-x12f.google.com with SMTP id 2adb3069b0e04-50e9e5c97e1so2007266e87.0 for ; Mon, 08 Jan 2024 06:44:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704725048; x=1705329848; darn=gcc.gnu.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=ypZUkAYJRdxrqluUl4b0wYQtgdLqewCRu/hPn9ir/NI=; b=a5PyaOBfF9FY9AXDxL84wfh9KEBcMsXQbb1Y4pXQjzwpdEaDIRK9jHwKDqhZ+pYpu+ 64sH9HgsceQdYy8+YjEyw++dDGNv0TzjfsKmZTgcnMaN+KHhMVhfKxDqsowtjbrORO4Z Sm5ntvUZdLqq7DCIl3DQ3uSK47/YE7N3rOwhtfqD6309pt6kksv/jGIXvsDmGxrDZ3sD h9+bVNKwZ0V7HU3KGnmS0av8rmyWLpB9CGciE5OXj92RNvDeOtbRszNzGkIIdB3eeRnb kEg2Axl/0zGLx9Nwx6HXgWJCtAgWdRZZzlABZCRgFxg5E8t8OU5Kj3AiG1yVVZcjcgGW XsIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704725048; x=1705329848; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=ypZUkAYJRdxrqluUl4b0wYQtgdLqewCRu/hPn9ir/NI=; b=JSR8JZjY+A7C5wOSf7RhncYEcDzk7tqs9FvFMJAzQEMyR9cIPyb1jFG6KUwvxgB2EB uJa7k70ifpnZwyH80CXekF+/qSP4PTF+MxQokokK3PRlDf4G8gZkV6mt8inj+SawN/HM Q5GHFCoPxT+KBh39aFpYxzRTqUAGFzw359ZpoiYC8uaUFXn1WtaO1x6pCXmF29E1hCnd o0vDoyVptsbqVxH54WGNqPdthes1sfxHJ61Hb2mqM7xnVpfrsx67PLVQsfFuqzggqj11 4/WvOC44fKjkpoSMPdyXrkTZ+e279pxd7nEXSNW4ZxG7pev9Lh7sx+y1sE5a6F4uU8u4 QZ8g== X-Gm-Message-State: AOJu0YxXShvfbKqeyHASb9JKXFeiDE8Vg1LQNkU103qJV60o/bua15Ei VRb6+XX0ymcAlItt8nqO0hbdEGT81r6mvTOniH8rDXPS0yXIuA== X-Google-Smtp-Source: AGHT+IFqYTDvOsiIi33ZjeyU5pbeqg7kmnFfqygf/hpJp7PZB+QlhqIhybrp2OZ0zz8MPszo4A9db3rWRItd4VDacoU= X-Received: by 2002:a05:6512:74:b0:50e:77b1:a3a4 with SMTP id i20-20020a056512007400b0050e77b1a3a4mr1352674lfo.122.1704725047761; Mon, 08 Jan 2024 06:44:07 -0800 (PST) MIME-Version: 1.0 From: Uros Bizjak Date: Mon, 8 Jan 2024 15:43:56 +0100 Message-ID: Subject: [PATCH] match.pd: Convert {I, X}OR of two values ANDed with alien CSTs to PLUS [PR108477] To: "gcc-patches@gcc.gnu.org" Cc: Richard Biener X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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+incoming=patchwork.ozlabs.org@gcc.gnu.org Instead of converting XOR or PLUS of two values, ANDed with two constants that have no bits in common, to IOR expression, convert IOR or XOR of said two ANDed values to PLUS expression. If we consider the following testcase: --cut here-- unsigned int foo (unsigned int a, unsigned int b) { unsigned int r = a & 0x1; unsigned int p = b & ~0x3; return r + p + 2; } unsigned int bar (unsigned int a, unsigned int b) { unsigned int r = a & 0x1; unsigned int p = b & ~0x3; return r | p | 2; } --cut here-- the above testcase compiles (x86_64 -O2) to: foo: andl $1, %edi andl $-4, %esi orl %esi, %edi leal 2(%rdi), %eax ret bar: andl $1, %edi andl $-4, %esi orl %esi, %edi movl %edi, %eax orl $2, %eax ret There is no further simplification possible in any case, we can't combine OR with a PLUS in the first case, and we don't have OR instruction with multiple inputs in the second case. If we switch around the logic in the conversion and convert from IOR/XOR to PLUS, then the resulting assembly reads: foo: andl $-4, %esi andl $1, %edi leal 2(%rsi,%rdi), %eax ret bar: andl $1, %edi andl $-4, %esi leal (%rdi,%rsi), %eax orl $2, %eax ret On x86, the conversion can now use LEA instruction, which is much more usable than OR instruction. In the first case, LEA implements three input ADD instruction, while in the second case, even though the instruction can't be combined with a follow-up OR, the non-destructive LEA avoids a move. PR target/108477 gcc/ChangeLog: * match.pd (A & CST1 | B & CST2 -> A & CST1 + B & CST2): Do not convert PLUS of two values, ANDed with two constants that have no bits in common to IOR exporession, convert IOR or XOR of said two ANDed values to PLUS expression. gcc/testsuite/ChangeLog: * gcc.target/i386/pr108477.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. OK for mainline? Uros. diff --git a/gcc/match.pd b/gcc/match.pd index 7b4b15acc41..deac18a7635 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1830,18 +1830,18 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && element_precision (type) <= element_precision (TREE_TYPE (@1))) (bit_not (rop (convert @0) (convert @1)))))) -/* If we are XORing or adding two BIT_AND_EXPR's, both of which are and'ing +/* If we are ORing or XORing two BIT_AND_EXPR's, both of which are and'ing with a constant, and the two constants have no bits in common, - we should treat this as a BIT_IOR_EXPR since this may produce more + we should treat this as a PLUS_EXPR since this may produce more simplifications. */ -(for op (bit_xor plus) +(for op (bit_ior bit_xor) (simplify (op (convert1? (bit_and@4 @0 INTEGER_CST@1)) (convert2? (bit_and@5 @2 INTEGER_CST@3))) (if (tree_nop_conversion_p (type, TREE_TYPE (@0)) && tree_nop_conversion_p (type, TREE_TYPE (@2)) && (wi::to_wide (@1) & wi::to_wide (@3)) == 0) - (bit_ior (convert @4) (convert @5))))) + (plus (convert @4) (convert @5))))) /* (X | Y) ^ X -> Y & ~ X*/ (simplify diff --git a/gcc/testsuite/gcc.target/i386/pr108477.c b/gcc/testsuite/gcc.target/i386/pr108477.c new file mode 100644 index 00000000000..fb320a84c6d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr108477.c @@ -0,0 +1,13 @@ +/* PR target/108477 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -masm=att" } */ + +unsigned int foo (unsigned int a, unsigned int b) +{ + unsigned int r = a & 0x1; + unsigned int p = b & ~0x3; + + return r + p + 2; +} + +/* { dg-final { scan-assembler-not "orl" } } */