From patchwork Tue Sep 12 04:21:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Pinski X-Patchwork-Id: 1832624 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=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Ba2MRYpb; 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 4Rl9RB2qXKz1yhL for ; Tue, 12 Sep 2023 14:22:28 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1F0A63858421 for ; Tue, 12 Sep 2023 04:22:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1F0A63858421 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1694492545; bh=Zjs71S//1o0Pecz98Diwjwho3CbFFjPSbM67O00eU8k=; h=To:CC:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=Ba2MRYpbJrHEC7RhOxcefe2XJ83IN5SXXbPdaN/h2Emmy3rUVFD/6vthETz9z5cUC mCDrAtqzB31shs3T1KJWLb7yIU9RFIXtTkCyE19QY/6JPHDzEJ+OMSyHeU6lKTpdQt xeqhATattoyQwWh+G0vLYc3rcmbgysGxDIo2gvTc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by sourceware.org (Postfix) with ESMTPS id 152F83858D3C for ; Tue, 12 Sep 2023 04:22:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 152F83858D3C Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 38BLPCgl006233 for ; Mon, 11 Sep 2023 21:22:03 -0700 Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3t200qkh33-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Mon, 11 Sep 2023 21:22:03 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Mon, 11 Sep 2023 21:22:02 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Mon, 11 Sep 2023 21:22:02 -0700 Received: from vpnclient.wrightpinski.org.com (unknown [10.69.242.187]) by maili.marvell.com (Postfix) with ESMTP id 7C9D13F705D; Mon, 11 Sep 2023 21:22:01 -0700 (PDT) To: CC: Andrew Pinski Subject: [PATCH] MATCH: Simplify (a CMP1 b) ^ (a CMP2 b) Date: Mon, 11 Sep 2023 21:21:52 -0700 Message-ID: <20230912042152.1412606-1-apinski@marvell.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 2Hl8gPMJxZZu9w6m98KhTAJtyoToZxfz X-Proofpoint-GUID: 2Hl8gPMJxZZu9w6m98KhTAJtyoToZxfz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-09-12_01,2023-09-05_01,2023-05-22_02 X-Spam-Status: No, score=-14.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP 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: , X-Patchwork-Original-From: Andrew Pinski via Gcc-patches From: Andrew Pinski Reply-To: Andrew Pinski Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This adds the missing optimizations here. Note we don't need to match where CMP1 and CMP2 are complements of each other as that is already handled elsewhere. I added a new executable testcase to make sure we optimize it correctly as I had originally messed up one of the entries for the resulting comparison to make sure they were 100% correct. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. PR tree-optimization/107881 gcc/ChangeLog: * match.pd (`(a CMP1 b) ^ (a CMP2 b)`): New pattern. (`(a CMP1 b) == (a CMP2 b)`): New pattern. gcc/testsuite/ChangeLog: * gcc.c-torture/execute/pr107881-1.c: New test. * gcc.dg/tree-ssa/cmpeq-4.c: New test. * gcc.dg/tree-ssa/cmpxor-1.c: New test. --- gcc/match.pd | 20 +++ .../gcc.c-torture/execute/pr107881-1.c | 115 ++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/cmpeq-4.c | 51 ++++++++ gcc/testsuite/gcc.dg/tree-ssa/cmpxor-1.c | 51 ++++++++ 4 files changed, 237 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr107881-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpeq-4.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpxor-1.c diff --git a/gcc/match.pd b/gcc/match.pd index e96e385c6fa..39c7ea1088f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3154,6 +3154,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { constant_boolean_node (true, type); }) )))))) +/* Optimize (a CMP b) ^ (a CMP b) */ +/* Optimize (a CMP b) != (a CMP b) */ +(for op (bit_xor ne) + (for cmp1 (lt lt lt le le le) + cmp2 (gt eq ne ge eq ne) + rcmp (ne le gt ne lt ge) + (simplify + (op:c (cmp1:c @0 @1) (cmp2:c @0 @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + (rcmp @0 @1))))) + +/* Optimize (a CMP b) == (a CMP b) */ +(for cmp1 (lt lt lt le le le) + cmp2 (gt eq ne ge eq ne) + rcmp (eq gt le eq ge lt) + (simplify + (eq:c (cmp1:c @0 @1) (cmp2:c @0 @1)) + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + (rcmp @0 @1)))) + /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) diff --git a/gcc/testsuite/gcc.c-torture/execute/pr107881-1.c b/gcc/testsuite/gcc.c-torture/execute/pr107881-1.c new file mode 100644 index 00000000000..063ec4c2797 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr107881-1.c @@ -0,0 +1,115 @@ +#define func(vol, op1, op2, op3) \ +_Bool op1##_##op2##_##op3##_##vol (int a, int b) \ +{ \ + vol _Bool x = op_##op1(a, b); \ + vol _Bool y = op_##op2(a, b); \ + return op_##op3(x, y); \ +} + +#define op_lt(a, b) ((a) < (b)) +#define op_le(a, b) ((a) <= (b)) +#define op_eq(a, b) ((a) == (b)) +#define op_ne(a, b) ((a) != (b)) +#define op_gt(a, b) ((a) > (b)) +#define op_ge(a, b) ((a) >= (b)) +#define op_xor(a, b) ((a) ^ (b)) + + +#define funcs(a) \ + a(lt,lt,ne) \ + a(lt,lt,eq) \ + a(lt,lt,xor) \ + a(lt,le,ne) \ + a(lt,le,eq) \ + a(lt,le,xor) \ + a(lt,gt,ne) \ + a(lt,gt,eq) \ + a(lt,gt,xor) \ + a(lt,ge,ne) \ + a(lt,ge,eq) \ + a(lt,ge,xor) \ + a(lt,eq,ne) \ + a(lt,eq,eq) \ + a(lt,eq,xor) \ + a(lt,ne,ne) \ + a(lt,ne,eq) \ + a(lt,ne,xor) \ + \ + a(le,lt,ne) \ + a(le,lt,eq) \ + a(le,lt,xor) \ + a(le,le,ne) \ + a(le,le,eq) \ + a(le,le,xor) \ + a(le,gt,ne) \ + a(le,gt,eq) \ + a(le,gt,xor) \ + a(le,ge,ne) \ + a(le,ge,eq) \ + a(le,ge,xor) \ + a(le,eq,ne) \ + a(le,eq,eq) \ + a(le,eq,xor) \ + a(le,ne,ne) \ + a(le,ne,eq) \ + a(le,ne,xor) \ + \ + a(gt,lt,ne) \ + a(gt,lt,eq) \ + a(gt,lt,xor) \ + a(gt,le,ne) \ + a(gt,le,eq) \ + a(gt,le,xor) \ + a(gt,gt,ne) \ + a(gt,gt,eq) \ + a(gt,gt,xor) \ + a(gt,ge,ne) \ + a(gt,ge,eq) \ + a(gt,ge,xor) \ + a(gt,eq,ne) \ + a(gt,eq,eq) \ + a(gt,eq,xor) \ + a(gt,ne,ne) \ + a(gt,ne,eq) \ + a(gt,ne,xor) \ + \ + a(ge,lt,ne) \ + a(ge,lt,eq) \ + a(ge,lt,xor) \ + a(ge,le,ne) \ + a(ge,le,eq) \ + a(ge,le,xor) \ + a(ge,gt,ne) \ + a(ge,gt,eq) \ + a(ge,gt,xor) \ + a(ge,ge,ne) \ + a(ge,ge,eq) \ + a(ge,ge,xor) \ + a(ge,eq,ne) \ + a(ge,eq,eq) \ + a(ge,eq,xor) \ + a(ge,ne,ne) \ + a(ge,ne,eq) \ + a(ge,ne,xor) + +#define funcs1(a,b,c) \ +func(,a,b,c) \ +func(volatile,a,b,c) + +funcs(funcs1) + +#define test(op1,op2,op3) \ +do { \ + if (op1##_##op2##_##op3##_(x,y) \ + != op1##_##op2##_##op3##_volatile(x,y)) \ + __builtin_abort(); \ +} while(0); + +int main() +{ + for(int x = -10; x < 10; x++) + for(int y = -10; y < 10; y++) + { + funcs(test) + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpeq-4.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpeq-4.c new file mode 100644 index 00000000000..868d80fdcca --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpeq-4.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-original" } */ +/* PR tree-optimization/107881 */ + +_Bool ltgt_eq(int a, int b) +{ + _Bool c = a < b; + _Bool d = a > b; + return c == d; // a == b +} +/* { dg-final { scan-tree-dump "a_\[0-9\]+.D. == b_\[0-9\]+.D.|b_\[0-9\]+.D. == a_\[0-9\]+.D." "optimized" } } */ + +_Bool lteq_eq(int x, int y) +{ + _Bool c = x < y; + _Bool d = x == y; + return c == d; // x > y +} +/* { dg-final { scan-tree-dump "x_\[0-9\]+.D. > y_\[0-9\]+.D.|y_\[0-9\]+.D. < x_\[0-9\]+.D." "optimized" } } */ + +_Bool ltne_eq(int z, int w) +{ + _Bool c = z < w; + _Bool d = z != w; + return c == d; // z <= w +} +/* { dg-final { scan-tree-dump "z_\[0-9\]+.D. <= w_\[0-9\]+.D.|w_\[0-9\]+.D. >= y_\[0-9\]+.D." "optimized" } } */ + +_Bool lege_eq(int i, int j) +{ + _Bool c = i <= j; + _Bool d = i >= j; + return c == d; // i == j +} +/* { dg-final { scan-tree-dump "i_\[0-9\]+.D. == j_\[0-9\]+.D.|j_\[0-9\]+.D. == i_\[0-9\]+.D." "optimized" } } */ + +_Bool leeq_eq(int k, int l) +{ + _Bool c = k <= l; + _Bool d = k == l; + return c == d; // k >= l +} +/* { dg-final { scan-tree-dump "k_\[0-9\]+.D. >= l_\[0-9\]+.D.|l_\[0-9\]+.D. <= k_\[0-9\]+.D." "optimized" } } */ + +_Bool lene_eq(int m, int n) +{ + _Bool c = m <= n; + _Bool d = m != n; + return c == d; // m < n +} +/* { dg-final { scan-tree-dump "m_\[0-9\]+.D. < n_\[0-9\]+.D.|n_\[0-9\]+.D. > m_\[0-9\]+.D." "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpxor-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpxor-1.c new file mode 100644 index 00000000000..8de2d9d2244 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpxor-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* PR tree-optimization/107881 */ + +_Bool ltgtxor(int a, int b) +{ + _Bool c = a < b; + _Bool d = a > b; + return c ^ d; // a != b +} +/* { dg-final { scan-tree-dump "a_\[0-9\]+.D. != b_\[0-9\]+.D.|b_\[0-9\]+.D. != a_\[0-9\]+.D." "optimized" } } */ + +_Bool lteqxor(int x, int y) +{ + _Bool c = x < y; + _Bool d = x == y; + return c ^ d; // x <= y (basically | here) +} +/* { dg-final { scan-tree-dump "x_\[0-9\]+.D. <= y_\[0-9\]+.D.|y_\[0-9\]+.D. >= x_\[0-9\]+.D." "optimized" } } */ + +_Bool ltnexor(int z, int w) +{ + _Bool c = z < w; + _Bool d = z != w; + return c ^ d; // z > w +} +/* { dg-final { scan-tree-dump "z_\[0-9\]+.D. > w_\[0-9\]+.D.|w_\[0-9\]+.D. < y_\[0-9\]+.D." "optimized" } } */ + +_Bool legexor(int i, int j) +{ + _Bool c = i <= j; + _Bool d = i >= j; + return c ^ d; // i != j +} +/* { dg-final { scan-tree-dump "i_\[0-9\]+.D. != j_\[0-9\]+.D.|j_\[0-9\]+.D. != i_\[0-9\]+.D." "optimized" } } */ + +_Bool leeqxor(int k, int l) +{ + _Bool c = k <= l; + _Bool d = k == l; + return c ^ d; // k < l +} +/* { dg-final { scan-tree-dump "k_\[0-9\]+.D. < l_\[0-9\]+.D.|l_\[0-9\]+.D. > k_\[0-9\]+.D." "optimized" } } */ + +_Bool lenexor(int m, int n) +{ + _Bool c = m <= n; + _Bool d = m != n; + return c ^ d; // m >= n +} +/* { dg-final { scan-tree-dump "m_\[0-9\]+.D. >= n_\[0-9\]+.D.|n_\[0-9\]+.D. <= m_\[0-9\]+.D." "optimized" } } */