From patchwork Mon May 1 06:29:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1775418 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) 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=xfIBl7fo; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Q8tdG74SXz1ydX for ; Mon, 1 May 2023 16:30:58 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 010C03850210 for ; Mon, 1 May 2023 06:30:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 010C03850210 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682922657; bh=KHXZuo9H46YtTalRJK9ZDWeE4MtUnRsCj/cm8SR264c=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=xfIBl7foSlGuIfFFmxxmqSJWv+rs5PsDU35+1aBXvTNx/40yqetMuIiW8eJ0esMhy HEky/80dPaqpj4HwP0WJq7RM+E7iaZLe2K3XqeCRpv8ZnFNUQcXsDCdbm7fdWg1K40 uMNvUh6eEyPOA0F2JlF5gu66bcpPVOizM8U82LPo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id BC79B3858C66 for ; Mon, 1 May 2023 06:29:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BC79B3858C66 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-224-VCmcbJ5GOSyZ-7jvHjmx-Q-1; Mon, 01 May 2023 02:29:14 -0400 X-MC-Unique: VCmcbJ5GOSyZ-7jvHjmx-Q-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id ED36988CC40 for ; Mon, 1 May 2023 06:29:13 +0000 (UTC) Received: from abulafia.quesejoda.com (unknown [10.39.192.81]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8565E112132E; Mon, 1 May 2023 06:29:13 +0000 (UTC) Received: from abulafia.quesejoda.com (localhost [127.0.0.1]) by abulafia.quesejoda.com (8.17.1/8.17.1) with ESMTPS id 3416TCWX564869 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 1 May 2023 08:29:12 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.17.1/8.17.1/Submit) id 3416TCXN564868; Mon, 1 May 2023 08:29:12 +0200 To: GCC patches Cc: Andrew MacLeod , Aldy Hernandez Subject: [COMMITTED] Replace vrp_val* with wide_ints. Date: Mon, 1 May 2023 08:29:02 +0200 Message-Id: <20230501062906.564803-8-aldyh@redhat.com> In-Reply-To: <20230501062906.564803-1-aldyh@redhat.com> References: <20230501062906.564803-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Aldy Hernandez via Gcc-patches From: Aldy Hernandez Reply-To: Aldy Hernandez Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This patch removes all uses of vrp_val_{min,max} in favor for a irange_val_* which are wide_int based. This will leave only one use of vrp_val_* which returns trees in range_of_ssa_name_with_loop_info() because it needs to work with non-integers (floats, etc). In a follow-up patch, this function will also be cleaned up such that vrp_val_* can be deleted. The functions min_limit and max_limit in range-op.cc are now useless as they're basically irange_val*. I didn't rename them yet to avoid churn. I'll do it in a later patch. gcc/ChangeLog: * gimple-range-fold.cc (adjust_pointer_diff_expr): Rewrite with irange_val*. (vrp_val_max): New. (vrp_val_min): New. * gimple-range-op.cc (cfn_strlen::fold_range): Use irange_val_*. * range-op.cc (max_limit): Same. (min_limit): Same. (plus_minus_ranges): Same. (operator_rshift::op1_range): Same. (operator_cast::inside_domain_p): Same. * value-range.cc (vrp_val_is_max): Delete. (vrp_val_is_min): Delete. (range_tests_misc): Use irange_val_*. * value-range.h (vrp_val_is_min): Delete. (vrp_val_is_max): Delete. (vrp_val_max): Delete. (irange_val_min): New. (vrp_val_min): Delete. (irange_val_max): New. * vr-values.cc (check_for_binary_op_overflow): Use irange_val_*. --- gcc/gimple-range-fold.cc | 40 +++++++++++++++++++++++++++++---- gcc/gimple-range-op.cc | 8 +++---- gcc/range-op.cc | 19 +++++++--------- gcc/value-range.cc | 37 +++++-------------------------- gcc/value-range.h | 41 +++++++--------------------------- gcc/vr-values.cc | 48 ++++++++++++++-------------------------- 6 files changed, 78 insertions(+), 115 deletions(-) diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 62875a35038..1b76e6e02a3 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -360,10 +360,10 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt) && vrp_operand_equal_p (op1, gimple_call_arg (call, 0)) && integer_zerop (gimple_call_arg (call, 1))) { - tree max = vrp_val_max (ptrdiff_type_node); - unsigned prec = TYPE_PRECISION (TREE_TYPE (max)); - wide_int wmaxm1 = wi::to_wide (max, prec) - 1; - res.intersect (int_range<2> (TREE_TYPE (max), wi::zero (prec), wmaxm1)); + wide_int maxm1 = irange_val_max (ptrdiff_type_node) - 1; + res.intersect (int_range<2> (ptrdiff_type_node, + wi::zero (TYPE_PRECISION (ptrdiff_type_node)), + maxm1)); } } @@ -966,6 +966,38 @@ tree_upper_bound (const vrange &r, tree type) return NULL; } +// Return the maximum value for TYPE. + +static inline tree +vrp_val_max (const_tree type) +{ + if (INTEGRAL_TYPE_P (type) + || POINTER_TYPE_P (type)) + return wide_int_to_tree (const_cast (type), irange_val_max (type)); + if (frange::supports_p (type)) + { + REAL_VALUE_TYPE r = frange_val_max (type); + return build_real (const_cast (type), r); + } + return NULL_TREE; +} + +// Return the minimum value for TYPE. + +static inline tree +vrp_val_min (const_tree type) +{ + if (INTEGRAL_TYPE_P (type) + || POINTER_TYPE_P (type)) + return wide_int_to_tree (const_cast (type), irange_val_min (type)); + if (frange::supports_p (type)) + { + REAL_VALUE_TYPE r = frange_val_min (type); + return build_real (const_cast (type), r); + } + return NULL_TREE; +} + // If SCEV has any information about phi node NAME, return it as a range in R. void diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 29c7c776a2c..3aef8357d8d 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -900,15 +900,13 @@ public: virtual bool fold_range (irange &r, tree type, const irange &, const irange &, relation_trio) const { - tree max = vrp_val_max (ptrdiff_type_node); - wide_int wmax - = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); + wide_int max = irange_val_max (ptrdiff_type_node); // To account for the terminating NULL, the maximum length // is one less than the maximum array size, which in turn // is one less than PTRDIFF_MAX (or SIZE_MAX where it's // smaller than the former type). // FIXME: Use max_object_size() - 1 here. - r.set (type, wi::zero (TYPE_PRECISION (type)), wmax - 2); + r.set (type, wi::zero (TYPE_PRECISION (type)), max - 2); return true; } } op_cfn_strlen; @@ -936,7 +934,7 @@ public: wi::shwi (m_is_pos ? 0 : 1, TYPE_PRECISION (type)), size ? wi::shwi (size - m_is_pos, TYPE_PRECISION (type)) - : wi::to_wide (vrp_val_max (type))); + : irange_val_max (type)); return true; } private: diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 224a561c170..fc0eef998e4 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -97,7 +97,7 @@ update_known_bitmask (irange &r, tree_code code, static inline wide_int max_limit (const_tree type) { - return wi::max_value (TYPE_PRECISION (type) , TYPE_SIGN (type)); + return irange_val_max (type); } // Return the lower limit for a type. @@ -105,7 +105,7 @@ max_limit (const_tree type) static inline wide_int min_limit (const_tree type) { - return wi::min_value (TYPE_PRECISION (type) , TYPE_SIGN (type)); + return irange_val_min (type); } // Return false if shifting by OP is undefined behavior. Otherwise, return @@ -1463,14 +1463,14 @@ plus_minus_ranges (irange &r_ov, irange &r_normal, const irange &offset, { // [ 0 , INF - OFF] lb = wi::zero (prec); - ub = wi::sub (wi::to_wide (vrp_val_max (type)), off, UNSIGNED, &ov); + ub = wi::sub (irange_val_max (type), off, UNSIGNED, &ov); kind = VREL_GT; } else { // [ OFF, INF ] lb = off; - ub = wi::to_wide (vrp_val_max (type)); + ub = irange_val_max (type); kind = VREL_LT; } int_range<2> normal_range (type, lb, ub); @@ -2594,13 +2594,10 @@ operator_rshift::op1_range (irange &r, // OP1 is anything from 0011 1000 to 0011 1111. That is, a // range from LHS<<3 plus a mask of the 3 bits we shifted on the // right hand side (0x07). - tree mask = fold_build1 (BIT_NOT_EXPR, type, - fold_build2 (LSHIFT_EXPR, type, - build_minus_one_cst (type), - wide_int_to_tree (op2.type (), shift))); + wide_int mask = wi::bit_not (wi::lshift (wi::minus_one (prec), shift)); int_range_max mask_range (type, wi::zero (TYPE_PRECISION (type)), - wi::to_wide (mask)); + mask); op_plus.fold_range (ub, type, lb, mask_range); r = lb; r.union_ (ub); @@ -2731,8 +2728,8 @@ operator_cast::inside_domain_p (const wide_int &min, const wide_int &max, const irange &range) const { - wide_int domain_min = wi::to_wide (vrp_val_min (range.type ())); - wide_int domain_max = wi::to_wide (vrp_val_max (range.type ())); + wide_int domain_min = irange_val_min (range.type ()); + wide_int domain_max = irange_val_max (range.type ()); signop domain_sign = TYPE_SIGN (range.type ()); return (wi::le_p (min, domain_max, domain_sign) && wi::le_p (max, domain_max, domain_sign) diff --git a/gcc/value-range.cc b/gcc/value-range.cc index f2148722a3a..cf694ccaa28 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1990,31 +1990,6 @@ debug (const value_range &vr) fprintf (stderr, "\n"); } -/* Return whether VAL is equal to the maximum value of its type. - We can't do a simple equality comparison with TYPE_MAX_VALUE because - C typedefs and Ada subtypes can produce types whose TYPE_MAX_VALUE - is not == to the integer constant with the same value in the type. */ - -bool -vrp_val_is_max (const_tree val) -{ - tree type_max = vrp_val_max (TREE_TYPE (val)); - return (val == type_max - || (type_max != NULL_TREE - && operand_equal_p (val, type_max, 0))); -} - -/* Return whether VAL is equal to the minimum value of its type. */ - -bool -vrp_val_is_min (const_tree val) -{ - tree type_min = vrp_val_min (TREE_TYPE (val)); - return (val == type_min - || (type_min != NULL_TREE - && operand_equal_p (val, type_min, 0))); -} - /* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */ bool @@ -2369,11 +2344,11 @@ range_tests_misc () // Test 1-bit signed integer union. // [-1,-1] U [0,0] = VARYING. tree one_bit_type = build_nonstandard_integer_type (1, 0); - tree one_bit_min = vrp_val_min (one_bit_type); - tree one_bit_max = vrp_val_max (one_bit_type); + wide_int one_bit_min = irange_val_min (one_bit_type); + wide_int one_bit_max = irange_val_max (one_bit_type); { - int_range<2> min = tree_range (one_bit_min, one_bit_min); - int_range<2> max = tree_range (one_bit_max, one_bit_max); + int_range<2> min = int_range<2> (one_bit_type, one_bit_min, one_bit_min); + int_range<2> max = int_range<2> (one_bit_type, one_bit_max, one_bit_max); max.union_ (min); ASSERT_TRUE (max.varying_p ()); } @@ -2382,8 +2357,8 @@ range_tests_misc () // Test inversion of 1-bit signed integers. { - int_range<2> min = tree_range (one_bit_min, one_bit_min); - int_range<2> max = tree_range (one_bit_max, one_bit_max); + int_range<2> min = int_range<2> (one_bit_type, one_bit_min, one_bit_min); + int_range<2> max = int_range<2> (one_bit_type, one_bit_max, one_bit_max); int_range<2> t; t = min; t.invert (); diff --git a/gcc/value-range.h b/gcc/value-range.h index 633a234d41f..b040e2f254f 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -635,8 +635,6 @@ Value_Range::supports_type_p (const_tree type) extern value_range_kind get_legacy_range (const irange &, tree &min, tree &max); extern void dump_value_range (FILE *, const vrange *); -extern bool vrp_val_is_min (const_tree); -extern bool vrp_val_is_max (const_tree); extern bool vrp_operand_equal_p (const_tree, const_tree); inline REAL_VALUE_TYPE frange_val_min (const_tree type); inline REAL_VALUE_TYPE frange_val_max (const_tree type); @@ -952,41 +950,18 @@ contains_zero_p (const irange &r) return r.contains_p (zero); } -// Return the maximum value for TYPE. - -inline tree -vrp_val_max (const_tree type) +inline wide_int +irange_val_min (const_tree type) { - if (INTEGRAL_TYPE_P (type)) - return TYPE_MAX_VALUE (type); - if (POINTER_TYPE_P (type)) - { - wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)); - return wide_int_to_tree (const_cast (type), max); - } - if (frange::supports_p (type)) - { - REAL_VALUE_TYPE r = frange_val_max (type); - return build_real (const_cast (type), r); - } - return NULL_TREE; + gcc_checking_assert (irange::supports_p (type)); + return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)); } -// Return the minimum value for TYPE. - -inline tree -vrp_val_min (const_tree type) +inline wide_int +irange_val_max (const_tree type) { - if (INTEGRAL_TYPE_P (type)) - return TYPE_MIN_VALUE (type); - if (POINTER_TYPE_P (type)) - return build_zero_cst (const_cast (type)); - if (frange::supports_p (type)) - { - REAL_VALUE_TYPE r = frange_val_min (type); - return build_real (const_cast (type), r); - } - return NULL_TREE; + gcc_checking_assert (irange::supports_p (type)); + return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)); } inline diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc index 49ae324419a..31df6b85ce6 100644 --- a/gcc/vr-values.cc +++ b/gcc/vr-values.cc @@ -103,34 +103,16 @@ check_for_binary_op_overflow (range_query *query, tree op0, tree op1, bool *ovf, gimple *s = NULL) { value_range vr0, vr1; - if (!query->range_of_expr (vr0, op0, s)) + if (!query->range_of_expr (vr0, op0, s) || vr0.undefined_p ()) vr0.set_varying (TREE_TYPE (op0)); - if (!query->range_of_expr (vr1, op1, s)) + if (!query->range_of_expr (vr1, op1, s) || vr1.undefined_p ()) vr1.set_varying (TREE_TYPE (op1)); - tree vr0min, vr0max, vr1min, vr1max; - if (vr0.undefined_p () || vr0.varying_p ()) - { - vr0min = vrp_val_min (TREE_TYPE (op0)); - vr0max = vrp_val_max (TREE_TYPE (op0)); - } - else - { - tree type = vr0.type (); - vr0min = wide_int_to_tree (type, vr0.lower_bound ()); - vr0max = wide_int_to_tree (type, vr0.upper_bound ()); - } - if (vr1.undefined_p () || vr1.varying_p ()) - { - vr1min = vrp_val_min (TREE_TYPE (op1)); - vr1max = vrp_val_max (TREE_TYPE (op1)); - } - else - { - tree type = vr1.type (); - vr1min = wide_int_to_tree (type, vr1.lower_bound ()); - vr1max = wide_int_to_tree (type, vr1.upper_bound ()); - } + tree vr0min = wide_int_to_tree (TREE_TYPE (op0), vr0.lower_bound ()); + tree vr0max = wide_int_to_tree (TREE_TYPE (op0), vr0.upper_bound ()); + tree vr1min = wide_int_to_tree (TREE_TYPE (op1), vr1.lower_bound ()); + tree vr1max = wide_int_to_tree (TREE_TYPE (op1), vr1.upper_bound ()); + *ovf = arith_overflowed_p (subcode, type, vr0min, subcode == MINUS_EXPR ? vr1max : vr1min); if (arith_overflowed_p (subcode, type, vr0max, @@ -152,10 +134,12 @@ check_for_binary_op_overflow (range_query *query, widest_int wmin, wmax; widest_int w[4]; int i; - w[0] = wi::to_widest (vr0min); - w[1] = wi::to_widest (vr0max); - w[2] = wi::to_widest (vr1min); - w[3] = wi::to_widest (vr1max); + signop sign0 = TYPE_SIGN (TREE_TYPE (op0)); + signop sign1 = TYPE_SIGN (TREE_TYPE (op1)); + w[0] = widest_int::from (vr0.lower_bound (), sign0); + w[1] = widest_int::from (vr0.upper_bound (), sign0); + w[2] = widest_int::from (vr1.lower_bound (), sign1); + w[3] = widest_int::from (vr1.upper_bound (), sign1); for (i = 0; i < 4; i++) { widest_int wt; @@ -186,8 +170,10 @@ check_for_binary_op_overflow (range_query *query, } /* The result of op0 CODE op1 is known to be in range [wmin, wmax]. */ - widest_int wtmin = wi::to_widest (vrp_val_min (type)); - widest_int wtmax = wi::to_widest (vrp_val_max (type)); + widest_int wtmin + = widest_int::from (irange_val_min (type), TYPE_SIGN (type)); + widest_int wtmax + = widest_int::from (irange_val_max (type), TYPE_SIGN (type)); /* If all values in [wmin, wmax] are smaller than [wtmin, wtmax] or all are larger than [wtmin, wtmax], the arithmetic operation will always overflow. */