From patchwork Fri Nov 4 12:34:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 80850 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1126264qge; Fri, 4 Nov 2016 05:34:45 -0700 (PDT) X-Received: by 10.98.131.197 with SMTP id h188mr26169130pfe.86.1478262885174; Fri, 04 Nov 2016 05:34:45 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s28si16222954pfe.176.2016.11.04.05.34.44 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Nov 2016 05:34:45 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-440426-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-440426-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-440426-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=oV4frXI4+/J0tRMMzAE02YZk8oP9IjO38/2Uw59AI+MjmoK+4yZgF uitfzRZ1lJgofcRHyDJwak+tAzECXXxhCuE0ucpcUueU7Xdh6Aqd3DJAsAE/L32K R0yVaG2aABzUUsVLI2b6g0wW84IFiip2LEDBtTtqBIRYl+bPmOm6Cs= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=0gigNxw+zOv2nbSPb5ihutx8kko=; b=P79VH7u/WIppCnomQ8Xl yn2RD4urpYDOiUoD1oOoUpHTe+BVhVd5ZtXqIZm6nI3kNuREIuSlkq+N5ARE6oDt D5qi9p09Q9dhCTQfsOSzbSTM5IeJilMf4u7uMHKsUmTqpng/yDW1WMm0QYCHMLZF GbroR68O2Rgh+8uvxpy54eo= Received: (qmail 7040 invoked by alias); 4 Nov 2016 12:34:31 -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 4963 invoked by uid 89); 4 Nov 2016 12:34:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=__SIZE_TYPE__, sk:fdumpt, RINT, sk:fdump-t X-HELO: mail2-relais-roc.national.inria.fr Received: from mail2-relais-roc.national.inria.fr (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 04 Nov 2016 12:34:18 +0000 Received: from ip-118.net-89-2-234.rev.numericable.fr (HELO laptop-mg.local) ([89.2.234.118]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 04 Nov 2016 13:34:16 +0100 Date: Fri, 4 Nov 2016 13:34:09 +0100 (CET) From: Marc Glisse To: gcc-patches@gcc.gnu.org Subject: Simplify X /[ex] 8 == 0 Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 Hello, this kind of simplification is already handled by fold_comparison, but the code is common with TRUNC_DIV_EXPR, which yields suboptimal code. In particular, for an unsigned number, X/8==0 means x<=7, while X/[ex]8==0 can be turned into X==0. When we have an explicit division by 0, there is a better optimisation possible (insert __builtin_unreachable() or __builtin_trap() after that statement, as in find_explicit_erroneous_behavior), so I don't touch it. For the overflow inequality case, it would have been a bit clearer to generate (cmp { build_zero_cst (TREE_TYPE (@0)); } @2) and let that be constant folded instead of having that ugly and error-prone test in constant_boolean_node, but I saved one tree ;-) Bootstrap+regtest on powerpc64le-unknown-linux-gnu, all the regressions are in the libitm part of the testsuite, they should be fixed by https://gcc.gnu.org/ml/gcc-patches/2016-10/msg02220.html , I'll rerun the testsuite when that patch is in. 2016-11-07 Marc Glisse gcc/ * fold-const.c (fold_comparison): Ignore EXACT_DIV_EXPR. * match.pd (A /[ex] B CMP C): New simplifications. gcc/testsuite/ * gcc.dg/tree-ssa/cmpexactdiv.c: New file. -- Marc Glisse Index: gcc/fold-const.c =================================================================== --- gcc/fold-const.c (revision 241840) +++ gcc/fold-const.c (working copy) @@ -8740,22 +8740,21 @@ fold_comparison (location_t loc, enum tr SET_EXPR_LOCATION (tem, loc); return tem; } return fold_build2_loc (loc, code, type, cval1, cval2); } } } /* We can fold X/C1 op C2 where C1 and C2 are integer constants into a single range test. */ - if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR - || TREE_CODE (arg0) == EXACT_DIV_EXPR) + if (TREE_CODE (arg0) == TRUNC_DIV_EXPR && TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && !integer_zerop (TREE_OPERAND (arg0, 1)) && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)) && !TREE_OVERFLOW (arg1)) { tem = fold_div_compare (loc, code, type, arg0, arg1); if (tem != NULL_TREE) return tem; } Index: gcc/match.pd =================================================================== --- gcc/match.pd (revision 241840) +++ gcc/match.pd (working copy) @@ -2314,20 +2314,50 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (ne @0 { build_real (TREE_TYPE (@0), c2); })))) /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs. */ (if (! HONOR_NANS (@0)) (cmp @0 { build_real (TREE_TYPE (@0), c2); }) /* sqrt(x) < c is the same as x >= 0 && x < c*c. */ (if (GENERIC) (truth_andif (ge @0 { build_real (TREE_TYPE (@0), dconst0); }) (cmp @0 { build_real (TREE_TYPE (@0), c2); })))))))))))) +/* Fold A /[ex] B CMP C to A CMP B * C. */ +(for cmp (eq ne) + (simplify + (cmp (exact_div @0 @1) INTEGER_CST@2) + (if (!integer_zerop (@1)) + (if (wi::eq_p (@2, 0)) + (cmp @0 @2) + (if (TREE_CODE (@1) == INTEGER_CST) + (with + { + bool ovf; + wide_int prod = wi::mul (@2, @1, TYPE_SIGN (TREE_TYPE (@1)), &ovf); + } + (if (ovf) + { constant_boolean_node (cmp == NE_EXPR, type); } + (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), prod); })))))))) +(for cmp (lt le gt ge) + (simplify + (cmp (exact_div @0 INTEGER_CST@1) INTEGER_CST@2) + (if (wi::gt_p (@1, 0, TYPE_SIGN (TREE_TYPE (@1)))) + (with + { + bool ovf; + wide_int prod = wi::mul (@2, @1, TYPE_SIGN (TREE_TYPE (@1)), &ovf); + } + (if (ovf) + { constant_boolean_node (wi::lt_p (@2, 0, TYPE_SIGN (TREE_TYPE (@2))) + != (cmp == LT_EXPR || cmp == LE_EXPR), type); } + (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), prod); })))))) + /* Unordered tests if either argument is a NaN. */ (simplify (bit_ior (unordered @0 @0) (unordered @1 @1)) (if (types_match (@0, @1)) (unordered @0 @1))) (simplify (bit_and (ordered @0 @0) (ordered @1 @1)) (if (types_match (@0, @1)) (ordered @0 @1))) (simplify Index: gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c (working copy) @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int f(int *p, int *q){ + __SIZE_TYPE__ n = q - p; + return n == 0; +} + +int g(int *p, int *q){ + __PTRDIFF_TYPE__ n = q - p; + return n <= 2; +} + +int h(long *p, long *q){ + __SIZE_TYPE__ n = q - p; + return n == (__SIZE_TYPE__)(-1)/2; +} + +/* { dg-final { scan-tree-dump-not "== 0" "optimized" } } */ +/* { dg-final { scan-tree-dump "<= 8" "optimized" { target { int32 } } } } */ +/* { dg-final { scan-tree-dump "return 0" "optimized" } } */