From patchwork Thu Jun 27 06:11:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Li Jia He X-Patchwork-Id: 1123134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-503838-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="oQ5iHlWo"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Z8gk5RJlz9s4Y for ; Thu, 27 Jun 2019 16:12:16 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=L0indTE3388r q2kfypnbGOkxAEw2EIjxi/fZfVFPmaifG5tucFHsJEacjQXpyx1+HeG92qCTdrHg RW1s2AFVZu24OiJpkImcIlGe8WCKpvTjVhkeT5SFOyU9xeL47s2k9ipe7fs5LtcK ZtdGoXaR/FZ9wdQwxzZW1ux5pWQPvr4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=RwPkTeNyWsahjSzISe gTPBU2Y1g=; b=oQ5iHlWoqxFq0Prm2VaaaYONqbfrsKJHMzdN1U4ZsTApSDE4Hx 1Sgo0haWrOwwYZ/Jaas7J3c6c3wg6EUYX86O7jeV1eOo2o/lt7SEJvl2yKZLJmPy sITQmacUZgMZX5Fp4duHkxHLNw+cVqZwdzjpbKu/DJUTBEQrDT9GaBFPs= Received: (qmail 86460 invoked by alias); 27 Jun 2019 06:12:08 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 86451 invoked by uid 89); 27 Jun 2019 06:12:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KHOP_DYNAMIC, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Jun 2019 06:12:04 +0000 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x5R67YRI046673 for ; Thu, 27 Jun 2019 02:12:02 -0400 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0a-001b2d01.pphosted.com with ESMTP id 2tcnc7xjgq-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 27 Jun 2019 02:12:02 -0400 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 27 Jun 2019 07:12:00 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp01.uk.ibm.com (192.168.101.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 27 Jun 2019 07:11:58 +0100 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x5R6BvQY49610840 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 27 Jun 2019 06:11:57 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E733011C058; Thu, 27 Jun 2019 06:11:56 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 092DD11C050; Thu, 27 Jun 2019 06:11:56 +0000 (GMT) Received: from genoa.aus.stglabs.ibm.com (unknown [9.40.192.157]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Thu, 27 Jun 2019 06:11:55 +0000 (GMT) From: Li Jia He To: gcc-patches@gcc.gnu.org Cc: segher@kernel.crashing.org, wschmidt@linux.ibm.com, rguenther@suse.de, Li Jia He Subject: [PATCH][middle-end/88784] Middle end is missing some optimizations about unsigned Date: Thu, 27 Jun 2019 01:11:53 -0500 x-cbid: 19062706-4275-0000-0000-00000346A3EC X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19062706-4276-0000-0000-00003856AAEC Message-Id: <1561615913-22109-1-git-send-email-helijia@linux.ibm.com> X-IsSubscribed: yes Hi, According to the optimizable case described by Qi Feng on issue 88784, we can combine the cases into the following: 1. x > y && x != XXX_MIN --> x > y 2. x > y && x == XXX_MIN --> false 3. x <= y && x == XXX_MIN --> x == XXX_MIN 4. x < y && x != XXX_MAX --> x < y 5. x < y && x == XXX_MAX --> false 6. x >= y && x == XXX_MAX --> x == XXX_MAX 7. x > y || x != XXX_MIN --> x != XXX_MIN 8. x <= y || x != XXX_MIN --> true 9. x <= y || x == XXX_MIN --> x <= y 10. x < y || x != XXX_MAX --> x != UXXX_MAX 11. x >= y || x != XXX_MAX --> true 12. x >= y || x == XXX_MAX --> x >= y Note: XXX_MIN represents the minimum value of type x. XXX_MAX represents the maximum value of type x. Here we don't need to care about whether the operation is signed or unsigned. For example, in the below equation: 'x > y && x != XXX_MIN --> x > y' If the x type is signed int and XXX_MIN is INT_MIN, we can optimize it to 'x > y'. However, if the type of x is unsigned int and XXX_MIN is 0, we can still optimize it to 'x > y'. The regression testing for the patch was done on GCC mainline on powerpc64le-unknown-linux-gnu (Power 9 LE) with no regressions. Is it OK for trunk ? Thanks, Lijia He gcc/ChangeLog 2019-06-27 Li Jia He Qi Feng PR middle-end/88784 * gimple-fold.c (and_comparisons_contain_equal_operands): New function. (and_comparisons_1): Use and_comparisons_contain_equal_operands. (or_comparisons_contain_equal_operands): New function. (or_comparisons_1): Use or_comparisons_contain_equal_operands. gcc/testsuite/ChangeLog 2019-06-27 Li Jia He Qi Feng PR middle-end/88784 * gcc.dg/pr88784-1.c: New testcase. * gcc.dg/pr88784-2.c: New testcase. * gcc.dg/pr88784-3.c: New testcase. * gcc.dg/pr88784-4.c: New testcase. * gcc.dg/pr88784-5.c: New testcase. * gcc.dg/pr88784-6.c: New testcase. * gcc.dg/pr88784-7.c: New testcase. * gcc.dg/pr88784-8.c: New testcase. * gcc.dg/pr88784-9.c: New testcase. * gcc.dg/pr88784-10.c: New testcase. * gcc.dg/pr88784-11.c: New testcase. * gcc.dg/pr88784-12.c: New testcase. --- gcc/gimple-fold.c | 124 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr88784-1.c | 30 ++++++++ gcc/testsuite/gcc.dg/pr88784-10.c | 32 ++++++++ gcc/testsuite/gcc.dg/pr88784-11.c | 30 ++++++++ gcc/testsuite/gcc.dg/pr88784-12.c | 30 ++++++++ gcc/testsuite/gcc.dg/pr88784-2.c | 30 ++++++++ gcc/testsuite/gcc.dg/pr88784-3.c | 32 ++++++++ gcc/testsuite/gcc.dg/pr88784-4.c | 32 ++++++++ gcc/testsuite/gcc.dg/pr88784-5.c | 31 ++++++++ gcc/testsuite/gcc.dg/pr88784-6.c | 31 ++++++++ gcc/testsuite/gcc.dg/pr88784-7.c | 31 ++++++++ gcc/testsuite/gcc.dg/pr88784-8.c | 31 ++++++++ gcc/testsuite/gcc.dg/pr88784-9.c | 32 ++++++++ 13 files changed, 496 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr88784-1.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-10.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-11.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-12.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-2.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-3.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-4.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-5.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-6.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-7.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-8.c create mode 100644 gcc/testsuite/gcc.dg/pr88784-9.c diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index dfb31a02078..6d2472d2fcb 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5535,6 +5535,62 @@ and_var_with_comparison_1 (gimple *stmt, return NULL_TREE; } +/* Try to simplify the AND of two comparisons defined by + (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively. + This optimization needs to satisfy op1a equal to op2a + or op1b equal to op2a. If this can be done without + constructing an intermediate value, return the resulting + tree; otherwise NULL_TREE is returned. */ + +static tree +and_comparisons_contain_equal_operands (enum tree_code code1, tree op1a, + tree op1b, enum tree_code code2, + tree op2a, tree op2b) +{ + /* Transform ((Y1 CODE1 X) AND (X CODE2 Y2)) to + ((X CODE1' Y1) AND (X CODE2 Y2)). */ + if (!operand_equal_p (op1a, op1b, 0) && operand_equal_p (op1b, op2a, 0) + && !operand_equal_p (op2a, op2b, 0)) + return and_comparisons_contain_equal_operands (swap_tree_comparison (code1), + op1b, op1a, code2, op2a, + op2b); + + tree op1a_type = TREE_TYPE (op1a); + tree op1b_type = TREE_TYPE (op1b); + tree op2b_type = TREE_TYPE (op2b); + + if (INTEGRAL_TYPE_P (op1a_type) && INTEGRAL_TYPE_P (op1b_type) + && operand_equal_p (op1a, op2a, 0) && TREE_CODE (op2b) == INTEGER_CST) + { + if (wi::eq_p (wi::to_wide (op2b), wi::min_value (op2b_type))) + { + /* x > y && x != XXX_MIN --> x > y */ + if (code1 == GT_EXPR && code2 == NE_EXPR) + return fold_build2 (code1, boolean_type_node, op1a, op1b); + /* x > y && x == XXX_MIN --> false */ + if (code1 == GT_EXPR && code2 == EQ_EXPR) + return boolean_false_node; + /* x <= y && x == XXX_MIN --> x == XXX_MIN */ + if (code1 == LE_EXPR && code2 == EQ_EXPR) + return fold_build2 (code2, boolean_type_node, op2a, op2b); + } + else if (wi::eq_p (wi::to_wide (op2b), wi::max_value (op2b_type))) + { + /* x < y && x != XXX_MAX --> x < y */ + if (code1 == LT_EXPR && code2 == NE_EXPR) + return fold_build2 (code1, boolean_type_node, op1a, op1b); + /* x < y && x == XXX_MAX --> false */ + if (code1 == LT_EXPR && code2 == EQ_EXPR) + return boolean_false_node; + /* x >= y && x == XXX_MAX --> x == XXX_MAX */ + if (code1 == GE_EXPR && code2 == EQ_EXPR) + return fold_build2 (code2, boolean_type_node, op2a, op2b); + } + } + + return NULL_TREE; +} + /* Try to simplify the AND of two comparisons defined by (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively. If this can be done without constructing an intermediate value, @@ -5546,6 +5602,12 @@ static tree and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { + /* Try to optimize ((x CODE1 y1) AND (x CODE2 y2)) + and ((y1 CODE1 x) AND (x CODE2 y2)). */ + if (tree t = and_comparisons_contain_equal_operands (code1, op1a, op1b, code2, + op2a, op2b)) + return t; + tree truth_type = truth_type_for (TREE_TYPE (op1a)); /* First check for ((x CODE1 y) AND (x CODE2 y)). */ @@ -5999,6 +6061,62 @@ or_var_with_comparison_1 (gimple *stmt, return NULL_TREE; } +/* Try to simplify the OR of two comparisons defined by + (OP1A CODE1 OP1B) or (OP2A CODE2 OP2B), respectively. + This optimization needs to satisfy op1a equal to op2a + or op1b equal to op2a. If this can be done without + constructing an intermediate value, return the resulting + tree; otherwise NULL_TREE is returned. */ + +static tree +or_comparisons_contain_equal_operands (enum tree_code code1, tree op1a, + tree op1b, enum tree_code code2, + tree op2a, tree op2b) +{ + /* Transform ((Y1 CODE1 X) OR (X CODE2 Y2)) to + ((X CODE1' Y1) OR (X CODE2 Y2)). */ + if (!operand_equal_p (op1a, op1b, 0) && operand_equal_p (op1b, op2a, 0) + && !operand_equal_p (op2a, op2b, 0)) + return or_comparisons_contain_equal_operands (swap_tree_comparison (code1), + op1b, op1a, code2, op2a, + op2b); + + tree op1a_type = TREE_TYPE (op1a); + tree op1b_type = TREE_TYPE (op1b); + tree op2b_type = TREE_TYPE (op2b); + + if (INTEGRAL_TYPE_P (op1a_type) && INTEGRAL_TYPE_P (op1b_type) + && operand_equal_p (op1a, op2a, 0) && TREE_CODE (op2b) == INTEGER_CST) + { + if (wi::eq_p (wi::to_wide (op2b), wi::min_value (op2b_type))) + { + /* x > y || x != XXX_MIN --> x != XXX_MIN */ + if (code1 == GT_EXPR && code2 == NE_EXPR) + return fold_build2 (code2, boolean_type_node, op2a, op2b); + /* x <= y || x != XXX_MIN --> true */ + if (code1 == LE_EXPR && code2 == NE_EXPR) + return boolean_true_node; + /* x <= y || x == XXX_MIN --> x <= y */ + if (code1 == LE_EXPR && code2 == EQ_EXPR) + return fold_build2 (code1, boolean_type_node, op1a, op1b); + } + else if (wi::eq_p (wi::to_wide (op2b), wi::max_value (op2b_type))) + { + /* x < y || x != XXX_MAX --> x != XXX_MAX */ + if (code1 == LT_EXPR && code2 == NE_EXPR) + return fold_build2 (code2, boolean_type_node, op2a, op2b); + /* x >= y || x != XXX_MAX --> true */ + if (code1 == GE_EXPR && code2 == NE_EXPR) + return boolean_true_node; + /* x >= y || x == XXX_MAX --> x >= y */ + if (code1 == GE_EXPR && code2 == EQ_EXPR) + return fold_build2 (code1, boolean_type_node, op1a, op1b); + } + } + + return NULL_TREE; +} + /* Try to simplify the OR of two comparisons defined by (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively. If this can be done without constructing an intermediate value, @@ -6010,6 +6128,12 @@ static tree or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { + /* Try to optimize ((x CODE1 y1) OR (x CODE2 y2)) + and ((y1 CODE1 x) OR (x CODE2 y2)). */ + if (tree t = or_comparisons_contain_equal_operands (code1, op1a, op1b, code2, + op2a, op2b)) + return t; + tree truth_type = truth_type_for (TREE_TYPE (op1a)); /* First check for ((x CODE1 y) OR (x CODE2 y)). */ diff --git a/gcc/testsuite/gcc.dg/pr88784-1.c b/gcc/testsuite/gcc.dg/pr88784-1.c new file mode 100644 index 00000000000..067d40d0739 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-1.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x != 0 --> x > y */ + return x > y && x != 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x != UINT_MAX --> x < y */ + return x < y && x != UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x != INT_MIN --> x > y */ + return x > y && x != INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x != INT_MAX --> x < y */ + return x < y && x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-10.c b/gcc/testsuite/gcc.dg/pr88784-10.c new file mode 100644 index 00000000000..fa185d680c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-10.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x != 0 --> true */ + return x <= y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x != UINT_MAX --> true */ + return x >= y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x != INT_MIN --> true */ + return x <= y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x != INT_MAX --> true */ + return x >= y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "dce3" } } */ +/* { dg-final { scan-tree-dump-not " <= " "dce3" } } */ +/* { dg-final { scan-tree-dump-not " >= " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-11.c b/gcc/testsuite/gcc.dg/pr88784-11.c new file mode 100644 index 00000000000..4465910efbb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-11.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x == 0 --> x <= y */ + return x <= y || x == 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x == UINT_MAX --> x >= y */ + return x >= y || x == UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x == INT_MIN --> x <= y */ + return x <= y || x == INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x == INT_MAX --> x >= y */ + return x >= y || x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-12.c b/gcc/testsuite/gcc.dg/pr88784-12.c new file mode 100644 index 00000000000..477bba07821 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-12.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x == 0 --> x <= y */ + return x <= y || x == 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x == UINT_MAX --> x >= y */ + return x >= y || x == UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x == INT_MIN --> x <= y */ + return x <= y || x == INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x == INT_MAX --> x >= y */ + return x >= y || x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-2.c b/gcc/testsuite/gcc.dg/pr88784-2.c new file mode 100644 index 00000000000..265ddc7ceeb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x != 0 --> x > y */ + return x > y && x != 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x != UINT_MAX --> x < y */ + return x < y && x != UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x != INT_MIN --> x > y */ + return x > y && x != INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x != INT_MAX --> x < y */ + return x < y && x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-3.c b/gcc/testsuite/gcc.dg/pr88784-3.c new file mode 100644 index 00000000000..be2ce315e60 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-3.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x == 0 --> false */ + return x > y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x == UINT_MAX --> false */ + return x < y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x == INT_MIN --> false */ + return x > y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x == INT_MAX --> false */ + return x < y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-4.c b/gcc/testsuite/gcc.dg/pr88784-4.c new file mode 100644 index 00000000000..b927e712464 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x > y && x == 0 --> false */ + return x > y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x < y && x == UINT_MAX --> false */ + return x < y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x > y && x == INT_MIN --> false */ + return x > y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x < y && x == INT_MAX --> false */ + return x < y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " == " "dce3" } } */ +/* { dg-final { scan-tree-dump-not " > " "dce3" } } */ +/* { dg-final { scan-tree-dump-not " < " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-5.c b/gcc/testsuite/gcc.dg/pr88784-5.c new file mode 100644 index 00000000000..c6a349d7c75 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-5.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x <= y && x == 0 --> x == 0 */ + return x <= y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x >= y && x == UINT_MAX --> x == UINT_MAX */ + return x >= y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x <= y && x == INT_MIN --> x == INT_MIN */ + return x <= y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x >= y && x == INT_MAX --> x == INT_MAX */ + return x >= y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-6.c b/gcc/testsuite/gcc.dg/pr88784-6.c new file mode 100644 index 00000000000..5b5d2221bf0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-6.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */ + +#include + +_Bool and1(unsigned x, unsigned y) +{ + /* x <= y && x == 0 --> x == 0 */ + return x <= y && x == 0; +} + +_Bool and2(unsigned x, unsigned y) +{ + /* x >= y && x == UINT_MAX --> x == UINT_MAX */ + return x >= y && x == UINT_MAX; +} + +_Bool and3(signed x, signed y) +{ + /* x <= y && x == INT_MIN --> x == INT_MIN */ + return x <= y && x == INT_MIN; +} + +_Bool and4(signed x, signed y) +{ + /* x >= y && x == INT_MAX --> x == INT_MAX */ + return x >= y && x == INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " <= " "dce3" } } */ +/* { dg-final { scan-tree-dump-not " >= " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-7.c b/gcc/testsuite/gcc.dg/pr88784-7.c new file mode 100644 index 00000000000..937d2d26593 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-7.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x > y || x != 0 --> x != 0 */ + return x > y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x < y || x != UINT_MAX --> x != UINT_MAX */ + return x < y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x > y || x != INT_MIN --> x != INT_MIN */ + return x > y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x < y || x != INT_MAX --> x != INT_MAX */ + return x < y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " > " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " < " "ifcombine" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-8.c b/gcc/testsuite/gcc.dg/pr88784-8.c new file mode 100644 index 00000000000..7f5c845eb27 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-8.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce3 --param logical-op-non-short-circuit=1" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x > y || x != 0 --> x != 0 */ + return x > y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x < y || x != UINT_MAX --> x != UINT_MAX */ + return x < y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x > y || x != INT_MIN --> x != INT_MIN */ + return x > y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x < y || x != INT_MAX --> x != INT_MAX */ + return x < y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " > " "dce3" } } */ +/* { dg-final { scan-tree-dump-not " < " "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr88784-9.c b/gcc/testsuite/gcc.dg/pr88784-9.c new file mode 100644 index 00000000000..94f62d94ede --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr88784-9.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ifcombine --param logical-op-non-short-circuit=0" } */ + +#include + +_Bool or1(unsigned x, unsigned y) +{ + /* x <= y || x != 0 --> true */ + return x <= y || x != 0; +} + +_Bool or2(unsigned x, unsigned y) +{ + /* x >= y || x != UINT_MAX --> true */ + return x >= y || x != UINT_MAX; +} + +_Bool or3(signed x, signed y) +{ + /* x <= y || x != INT_MIN --> true */ + return x <= y || x != INT_MIN; +} + +_Bool or4(signed x, signed y) +{ + /* x >= y || x != INT_MAX --> true */ + return x >= y || x != INT_MAX; +} + +/* { dg-final { scan-tree-dump-not " != " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " <= " "ifcombine" } } */ +/* { dg-final { scan-tree-dump-not " >= " "ifcombine" } } */