From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29496 invoked by alias); 29 Dec 2018 04:33:17 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 29483 invoked by uid 89); 29 Dec 2018 04:33:17 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=alone, differences, transformation, namely X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 29 Dec 2018 04:33:14 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 452D0C057F8F for ; Sat, 29 Dec 2018 04:33:13 +0000 (UTC) Received: from free.home (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B0F68608F3; Sat, 29 Dec 2018 04:33:12 +0000 (UTC) Received: from libre (free-to-gw.home [172.31.160.161]) by free.home (8.15.2/8.15.2) with ESMTP id wBT4X2tu480452; Sat, 29 Dec 2018 02:33:03 -0200 From: Alexandre Oliva To: Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: Re: [PR86153] simplify more overflow tests in VRP References: <67b3141e-ea22-1587-6617-72176acdc71a@redhat.com> Date: Sat, 29 Dec 2018 10:56:00 -0000 In-Reply-To: (Alexandre Oliva's message of "Wed, 19 Dec 2018 09:04:03 -0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-SW-Source: 2018-12/txt/msg01754.txt.bz2 On Dec 19, 2018, Alexandre Oliva wrote: > + op1 =3D x; > + code =3D (code =3D=3D LT_EXPR || code =3D=3D LE_EXPR) ? LE_EXPR : = GT_EXPR; So... I've done some more testing, and this alone seems to overlap nicely with what's in the trunk ATM, with a few exceptions: - for some reason, LE/GT do not get us some simplifications that EQ/NE do when x is zero, despite the unsigned type for op0, that ought to make them equivalent. That could probably be improved elsewhere, but it's easy enough to remedy with: if (integer_zerop (x)) code =3D (code =3D=3D LT_EXPR || code =3D=3D LE_EXPR) ? EQ_EXPR : NE_EX= PR; else code =3D (code =3D=3D LT_EXPR || code =3D=3D LE_EXPR) ? LE_EXPR : GT_EX= PR; =20=20=20 - other differences I observed involved other case we currently transform to equality, namely, if x is (u)max-1, we test op1 against zero. The transformation quoted above does better than this in at least 3 situations: a selftest in vec.c, cp_genericize_r in cp/cp-gimplify.c, and cp_maybe_mangle_decomp in cp/decl.c. In these cases, op0 has a known range from 0 to INT_MAX or INT_MAX-1, so a compare of op0 vs 2u*INT_MAX can be folded to a constant, but the compare of op1 vs 0 we currently use cannot. - the fact that in some cases a test against one of the overflow-related variables can be optimized when a test against the other can't surprised me; I would have expected the ranges and equivalences and whatnot to be such that this would never happen, but it does. It suggests we could get some additional folding out of trying op1 vs max-x when op0 vs x fails to resolve to a constant. FTR, here's the patchlet (-b) I've used to look for differences. commit 2fe0b2784815882c3e2821b171979b54c3ffdc55 Author: Alexandre Oliva Date: Sat Dec 29 00:21:42 2018 -0200 [PR86153/83239] identify vrp overflow simplification differences to inv= estigate diff --git a/gcc/vr-values.c b/gcc/vr-values.c index d71a703ab550..a40c41e4d139 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -2296,7 +2296,6 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops (e= num tree_code code, bool *strict_overflow_p, bool *only_ranges) { - tree ret; if (only_ranges) *only_ranges =3D true; =20 @@ -2316,6 +2315,40 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops (= enum tree_code code, tree x; if (overflow_comparison_p (code, op0, op1, use_equiv_p, &x)) { + tree ret1 =3D ovrflow_vrp_evaluate_conditional_warnv_with_ops (code,= op0, op1, x, + use_equiv_p, + strict_overflow_p, + only_ranges); + + op1 =3D x; + if (integer_zerop (x)) + code =3D (code =3D=3D LT_EXPR || code =3D=3D LE_EXPR) ? EQ_EXPR : NE_EXPR; + else + code =3D (code =3D=3D LT_EXPR || code =3D=3D LE_EXPR) ? LE_EXPR : GT_EXPR; + + tree ret2 =3D rest_of_vrp_evaluate_conditional_warnv_with_ops (code,= op0, op1, + use_equiv_p, + strict_overflow_p, + only_ranges); + gcc_assert (ret1 =3D=3D ret2 + || (ret1 && ret2 && operand_equal_p (ret1, ret2, 0))); + + return ret2; + } + else + return rest_of_vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, + use_equiv_p, + strict_overflow_p, + only_ranges); +} + +tree vr_values:: +ovrflow_vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, + tree op0, tree op1, tree x, + bool use_equiv_p, + bool *strict_overflow_p, + bool *only_ranges) +{ wide_int max =3D wi::max_value (TYPE_PRECISION (TREE_TYPE (op0)), UNSIGN= ED); /* B =3D A - 1; if (A < B) -> B =3D A - 1; if (A =3D=3D 0) B =3D A - 1; if (A > B) -> B =3D A - 1; if (A !=3D 0) @@ -2369,7 +2402,21 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops (= enum tree_code code, if (vri.undefined_p ()) return boolean_true_node; } - } + + return rest_of_vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, + use_equiv_p, + strict_overflow_p, + only_ranges); +} + +tree vr_values:: +rest_of_vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, + tree op0, tree op1, + bool use_equiv_p, + bool *strict_overflow_p, + bool *only_ranges) +{ + tree ret; =20 if ((ret =3D vrp_evaluate_conditional_warnv_with_ops_using_ranges (code, op0, op1, strict_overflow_p))) diff --git a/gcc/vr-values.h b/gcc/vr-values.h index 6785cb68fa76..e30719e82599 100644 --- a/gcc/vr-values.h +++ b/gcc/vr-values.h @@ -85,6 +85,17 @@ class vr_values tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code, tree, tree, bool, bool *, bool *); + tree rest_of_vrp_evaluate_conditional_warnv_with_ops (enum tree_code cod= e, + tree op0, tree op1, + bool use_equiv_p, + bool *strict_overflow_p, + bool *only_ranges); + tree ovrflow_vrp_evaluate_conditional_warnv_with_ops (enum tree_code cod= e, + tree op0, tree op1, tree x, + bool use_equiv_p, + bool *strict_overflow_p, + bool *only_ranges); + void extract_range_from_assignment (value_range *, gassign *); void extract_range_from_assert (value_range *, tree); void extract_range_from_ssa_name (value_range *, tree); --=20 Alexandre Oliva, freedom fighter https://FSFLA.org/blogs/lxo Be the change, be Free! FSF Latin America board member GNU Toolchain Engineer Free Software Evangelist Hay que enGNUrecerse, pero sin perder la terGNUra jam=C3=A1s-GNUChe