From patchwork Thu Sep 21 02:43:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Pinski X-Patchwork-Id: 142697 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp4567476vqi; Wed, 20 Sep 2023 19:44:02 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGLzIHpRyEos9DG86D1Bt2/0mQwzUc6M1DF5C2oXeWLnMC1p4Nq3fpa2DaxnSpNrf1AjG/A X-Received: by 2002:a5d:5451:0:b0:31f:a25d:e9a with SMTP id w17-20020a5d5451000000b0031fa25d0e9amr3498402wrv.46.1695264242248; Wed, 20 Sep 2023 19:44:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695264242; cv=none; d=google.com; s=arc-20160816; b=hxFGKzAllL0Zz3lmj/9AGsDipqiseNpVl9Ipfs7IsZlYnZpQsFIY4QlkcDXx3bI5Dk cmtfON+f/eDu6gDE2UCE1/r3hGRINdAgQHdav0qiI4yUrWtscYE0hoNA1n9iwk6Sbit/ 5RD2OX5eDxN8PO+Re3yV9TyB8PpjeepCCtwg0+pNUq59ZL3l16WRoN6AW9lqiOEwGCGM xv0Hh0dgfYU74GKYeViFUb6be1w3oxVh3R6Bqt/89o83FJTXRVcttSTkgXg5fIR7yEUK /gq/55vLkTKt/RtLhLfhL3Uix+wCd2QYtBKexZsGTDYLKu1+YaKyZLwmG3wvNhTtmUL0 Nmog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature :dmarc-filter:delivered-to; bh=s051yhz0Q5EjChe9PbM9TqWhbh26E6F5aFHtgY9kJwE=; fh=XbcmRug6/SzczusyoNU1I7Lu5oY0AN2u0mWDzKoxdSs=; b=GYUiI/xCACNE1L9io/4FqX55kB1KRJMmPFBgXPavgQgPfPuCEvOMCj+SiPNOPDNZyX f1VlIDmm4RhV0Sz3IjIGgBw2ocNjGj6JnWp1mLWtZGhF6KGwYZeqp3F79QXv3pEj5wJs 9x1wVIv/8BEfuz+Tme+Tm5EWQ9urUVs/0wpBxw75Ft2T+pJq7gCi4WwwwwHvmf2X+z8V sjquHRGucrEMRUkZLUm4jQtXg9N3dZz+vdE0f256UiDnh5zPHK13xkd2bLO3ZA3ZTnQL aoW+ZbtGwY6B3A9ajAb/CTczYOYhnFRiqxldt4GJx8C6w0f0AnniNUf2H4E/PvdK4rTS wvug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=XLo+JecK; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id g10-20020a170906594a00b0099bd24d66aasi425637ejr.383.2023.09.20.19.44.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 19:44:02 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@marvell.com header.s=pfpt0220 header.b=XLo+JecK; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=marvell.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D9F10385773F for ; Thu, 21 Sep 2023 02:43:56 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by sourceware.org (Postfix) with ESMTPS id E03033858C52 for ; Thu, 21 Sep 2023 02:43:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E03033858C52 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=marvell.com Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 38KINXRr012101 for ; Wed, 20 Sep 2023 19:43:29 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=s051yhz0Q5EjChe9PbM9TqWhbh26E6F5aFHtgY9kJwE=; b=XLo+JecKK4WqIKeHCC1RclRn2DvKG5djhJXztY1wupmwEXLnYfF3/c2btDndAZvOVmiN h++BrNOTSiTnMWHOmmOpwfIdsy2iI/bdYqoUTbb87oZVMeGeclLo05KftcevDkl+x5f6 cd4axFdIfMGMJ3sQGSRMPZOfCH5RLv6Z8a8BAYDg/Wxwl9aU8iigJzd3+smnALCz3oS0 8bu376YCuZghZrOYOQwtloNL/eDxJ0xlW436Su3d9gA9tYbbuixdjemLOJXn1MHzE4fW WFGbI62Ztp4GSUpvw75CobvLzhHeiurWumzqoINh6cCg1SeKagxHPnF6jIRAOysww0T5 QA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3t85ptsdgb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT) for ; Wed, 20 Sep 2023 19:43:28 -0700 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Wed, 20 Sep 2023 19:43:25 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Wed, 20 Sep 2023 19:43:25 -0700 Received: from vpnclient.wrightpinski.org.com (unknown [10.69.242.187]) by maili.marvell.com (Postfix) with ESMTP id A17605B693B; Wed, 20 Sep 2023 19:43:25 -0700 (PDT) From: Andrew Pinski To: CC: Andrew Pinski Subject: [PATCH] MATCH: Simplify `(A ==/!= B) &/| (((cast)A) CMP C)` Date: Wed, 20 Sep 2023 19:43:13 -0700 Message-ID: <20230921024313.1941378-1-apinski@marvell.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Proofpoint-GUID: I8ld98KuBLNMxO7LuHoKlxDXEtkJjpRz X-Proofpoint-ORIG-GUID: I8ld98KuBLNMxO7LuHoKlxDXEtkJjpRz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-09-20_14,2023-09-20_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: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777613398103767966 X-GMAIL-MSGID: 1777613398103767966 This patch adds support to the pattern for `(A == B) &/| (A CMP C)` where the second A could be casted to a different type. Some were handled correctly if using seperate `if` statements but not if combined with BIT_AND/BIT_IOR. In the case of pr111456-1.c, the testcase would pass if `--param=logical-op-non-short-circuit=0` was used but now can be optimized always. OK? Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/106164 PR tree-optimization/111456 gcc/ChangeLog: * match.pd (`(A ==/!= B) & (A CMP C)`): Support an optional cast on the second A. (`(A ==/!= B) | (A CMP C)`): Likewise. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/cmpbit-6.c: New test. * gcc.dg/tree-ssa/cmpbit-7.c: New test. * gcc.dg/tree-ssa/pr111456-1.c: New test. --- gcc/match.pd | 76 +++++++++++++--------- gcc/testsuite/gcc.dg/tree-ssa/cmpbit-6.c | 22 +++++++ gcc/testsuite/gcc.dg/tree-ssa/cmpbit-7.c | 28 ++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c | 43 ++++++++++++ 4 files changed, 139 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpbit-6.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpbit-7.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c diff --git a/gcc/match.pd b/gcc/match.pd index a37af05f873..0bf91bde486 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2973,7 +2973,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1))) (gt @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); })))) -/* Convert (X == CST1) && (X OP2 CST2) to a known value +/* Convert (X == CST1) && ((other)X OP2 CST2) to a known value based on CST1 OP2 CST2. Similarly for (X != CST1). */ /* Convert (X == Y) && (X OP2 Y) to a known value if X is an integral type. Similarly for (X != Y). */ @@ -2981,26 +2981,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for code1 (eq ne) (for code2 (eq ne lt gt le ge) (simplify - (bit_and:c (code1@3 @0 @1) (code2@4 @0 @2)) + (bit_and:c (code1:c@3 @0 @1) (code2:c@4 (convert?@c0 @0) @2)) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) - && operand_equal_p (@1, @2))) + && bitwise_equal_p (@1, @2))) (with { bool one_before = false; bool one_after = false; int cmp = 0; + bool allbits = true; if (TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) { - cmp = tree_int_cst_compare (@1, @2); + allbits = TYPE_PRECISION (TREE_TYPE (@1)) <= TYPE_PRECISION (TREE_TYPE (@2)); + auto t1 = wi::to_wide (fold_convert (TREE_TYPE (@2), @1)); + auto t2 = wi::to_wide (@2); + cmp = wi::cmp (t1, t2, TYPE_SIGN (TREE_TYPE (@2))); if (cmp < 0 - && wi::to_wide (@1) == wi::to_wide (@2) - 1) + && t1 == t2 - 1) one_before = true; if (cmp > 0 - && wi::to_wide (@1) == wi::to_wide (@2) + 1) + && t1 == t2 + 1) one_after = true; } bool val; @@ -3018,25 +3022,29 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (switch (if (code1 == EQ_EXPR && val) @3) (if (code1 == EQ_EXPR && !val) { constant_boolean_node (false, type); }) - (if (code1 == NE_EXPR && !val) @4) + (if (code1 == NE_EXPR && !val && allbits) @4) (if (code1 == NE_EXPR && code2 == GE_EXPR - && cmp == 0) - (gt @0 @1)) + && cmp == 0 + && allbits) + (gt @c0 (convert @1))) (if (code1 == NE_EXPR && code2 == LE_EXPR - && cmp == 0) - (lt @0 @1)) + && cmp == 0 + && allbits) + (lt @c0 (convert @1))) /* (a != (b+1)) & (a > b) -> a > (b+1) */ (if (code1 == NE_EXPR && code2 == GT_EXPR - && one_after) - (gt @0 @1)) + && one_after + && allbits) + (gt @c0 (convert @1))) /* (a != (b-1)) & (a < b) -> a < (b-1) */ (if (code1 == NE_EXPR && code2 == LT_EXPR - && one_before) - (lt @0 @1)) + && one_before + && allbits) + (lt @c0 (convert @1))) ) ) ) @@ -3100,26 +3108,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for code1 (eq ne) (for code2 (eq ne lt gt le ge) (simplify - (bit_ior:c (code1@3 @0 @1) (code2@4 @0 @2)) + (bit_ior:c (code1:c@3 @0 @1) (code2:c@4 (convert?@c0 @0) @2)) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) - && operand_equal_p (@1, @2))) + && bitwise_equal_p (@1, @2))) (with { bool one_before = false; bool one_after = false; int cmp = 0; + bool allbits = true; if (TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) { - cmp = tree_int_cst_compare (@1, @2); + allbits = TYPE_PRECISION (TREE_TYPE (@1)) <= TYPE_PRECISION (TREE_TYPE (@2)); + auto t1 = wi::to_wide (fold_convert (TREE_TYPE (@2), @1)); + auto t2 = wi::to_wide (@2); + cmp = wi::cmp (t1, t2, TYPE_SIGN (TREE_TYPE (@2))); if (cmp < 0 - && wi::to_wide (@1) == wi::to_wide (@2) - 1) + && t1 == t2 - 1) one_before = true; if (cmp > 0 - && wi::to_wide (@1) == wi::to_wide (@2) + 1) + && t1 == t2 + 1) one_after = true; } bool val; @@ -3136,26 +3148,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) } (switch (if (code1 == EQ_EXPR && val) @4) - (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); }) - (if (code1 == NE_EXPR && !val) @3) + (if (code1 == NE_EXPR && val && allbits) { constant_boolean_node (true, type); }) + (if (code1 == NE_EXPR && !val && allbits) @3) (if (code1 == EQ_EXPR && code2 == GT_EXPR - && cmp == 0) - (ge @0 @1)) + && cmp == 0 + && allbits) + (ge @c0 @2)) (if (code1 == EQ_EXPR && code2 == LT_EXPR - && cmp == 0) - (le @0 @1)) + && cmp == 0 + && allbits) + (le @c0 @2)) /* (a == (b-1)) | (a >= b) -> a >= (b-1) */ (if (code1 == EQ_EXPR && code2 == GE_EXPR - && one_before) - (ge @0 @1)) + && one_before + && allbits) + (ge @c0 (convert @1))) /* (a == (b+1)) | (a <= b) -> a <= (b-1) */ (if (code1 == EQ_EXPR && code2 == LE_EXPR - && one_after) - (le @0 @1)) + && one_after + && allbits) + (le @c0 (convert @1))) ) ) ) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpbit-6.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpbit-6.c new file mode 100644 index 00000000000..4ec73f030bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpbit-6.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* PR tree-optimization/106164 */ +/* PR tree-optimization/111456 */ + +_Bool iu(int a) +{ + _Bool t = a == 0; + unsigned t1 = a; + _Bool t2 = t1 >= 3; + return t & t2; +} + +_Bool is(int a) +{ + _Bool t = a == 0; + short t1 = a; + _Bool t2 = t1 >= 3; + return t & t2; +} + +/* { dg-final { scan-tree-dump-times "return 0" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpbit-7.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpbit-7.c new file mode 100644 index 00000000000..ee04ebbaaed --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpbit-7.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop1" } */ +/* PR tree-optimization/106164 */ +/* PR tree-optimization/111456 */ + +_Bool f(int a) +{ + _Bool t = a == 3; + unsigned t1 = a; + _Bool t2 = t1 >= 3; + return t | t2; +} + +/* Should be able to optimize down to just `a > 2` during forwprop1 */ +/* { dg-final { scan-tree-dump-not "a_\[0-9\]+.D. == 3" "forwprop1" } } */ + +_Bool f1(int b) +{ + _Bool t = b == 3; + short t1 = b; + _Bool t2 = t1 >= 3; + return t | t2; +} + +/* Should be able to optimize down to just `a > 2` during forwprop1 as `((short)a) >= 3` is + true already when `a == 3`. */ +/* { dg-final { scan-tree-dump-not "b_\[0-9\]+.D. == 3" "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "_\[0-9\]+ > 2" 2 "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c new file mode 100644 index 00000000000..8a2f730b387 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr111456-1.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* PR tree-optimization/111456 */ + +void foo(void); +static int i; +static int *j = &i; +static char l; +static void(a)(char) {} +static short(b)(short c, short d) { return c - d; } +static short(e)(short f, int g) { + return f < 0 || g < 0 || g >= 32 ? f : f >> g; +} +static short(h)(short f, int g) { return g >= 2 ?: f >> g; } +static char k(char m, short n) { + short o; + int *p = &i; + if (!(((m) >= 1) && ((m) <= 1))) { + __builtin_unreachable(); + } + o = e(i, i); + if (h(1, o)) + ; + else { + m = 0; + for (; m >= -20; m = b(m, 9)) + if (a(i), n) { + if (*p) + ; + else + foo(); + ; + } else + return l; + } + return i; +} +int main() { k(0 <= 0 > *j, i); } + + +/* { dg-final { scan-tree-dump-not "foo " "optimized" } } */ +/* { dg-final { scan-tree-dump "return 0;" "optimized" } } */ +