From patchwork Mon Aug 1 06:15:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 56459 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 78C94384A890 for ; Mon, 1 Aug 2022 06:16:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 78C94384A890 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1659334585; bh=/iffnkh4WHvlcsriG+QMvtiuzGCS6qk+JZ4txWyfxBg=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=SypOVm1yQk7cc7KgcElWwiBnF2KiSf4c5XcZ2iurmQuZ2P6VuGaA2+8thte6DVlxz iUBZmn57lQXz2cl6THOLrNwAt9g1Fb6r7KR5+rfpX3BVDCixrcWj0j4kSNtMajz2cm rca9BtkurzKRJQOUn2mmpEX/ge8VoP85FzsspH7k= 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.129.124]) by sourceware.org (Postfix) with ESMTPS id 8F9F7385843D for ; Mon, 1 Aug 2022 06:15:54 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8F9F7385843D 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-241-RNsoNneCOKKGnKuyiARJOQ-1; Mon, 01 Aug 2022 02:15:52 -0400 X-MC-Unique: RNsoNneCOKKGnKuyiARJOQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BBBCF185A7B2 for ; Mon, 1 Aug 2022 06:15:51 +0000 (UTC) Received: from abulafia.quesejoda.com (unknown [10.39.192.163]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 716152166B2A; Mon, 1 Aug 2022 06:15:51 +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 2716FnWJ229710 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 1 Aug 2022 08:15:49 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.17.1/8.17.1/Submit) id 2716Fnd5229709; Mon, 1 Aug 2022 08:15:49 +0200 To: GCC patches Subject: [COMMITTED] Cleanups to frange. Date: Mon, 1 Aug 2022 08:15:40 +0200 Message-Id: <20220801061540.229684-3-aldyh@redhat.com> In-Reply-To: <20220801061540.229684-1-aldyh@redhat.com> References: <20220801061540.229684-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.0 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_LOW, SPF_HELO_NONE, SPF_NONE, 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.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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" These are some assorted cleanups to the frange class to make it easier to drop in an implementation with FP endpoints: * frange::set() had some asserts limiting the type of arguments passed. There's no reason why we can't handle all the variants. Worse comes to worse, we can always return a VARYING which is conservative and correct. * frange::normalize_kind() now returns a boolean that can be used in union and intersection to indicate that the range changed. * Implement vrp_val_max and vrp_val_min for floats. Also, move them earlier in the header file so frange can use them. Tested on x86-64 Linux. gcc/ChangeLog: * value-range.cc (tree_compare): New. (frange::set): Make more general. (frange::normalize_kind): Cleanup and return bool. (frange::union_): Use normalize_kind return value. (frange::intersect): Same. (frange::verify_range): Remove unnecessary else. * value-range.h (vrp_val_max): Move before frange class. (vrp_val_min): Same. (frange::frange): Remove set to m_type. --- gcc/value-range.cc | 102 +++++++++++++++++++++++++++++---------------- gcc/value-range.h | 70 ++++++++++++++++++------------- 2 files changed, 105 insertions(+), 67 deletions(-) diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 7adbf55c6a6..dc06f8b0078 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -260,66 +260,93 @@ frange::accept (const vrange_visitor &v) const v.visit (*this); } -// Setter for franges. Currently only singletons are supported. +// Helper function to compare floats. Returns TRUE if op1 .CODE. op2 +// is nonzero. + +static inline bool +tree_compare (tree_code code, tree op1, tree op2) +{ + return !integer_zerop (fold_build2 (code, integer_type_node, op1, op2)); +} + +// Setter for franges. void frange::set (tree min, tree max, value_range_kind kind) { - gcc_checking_assert (kind == VR_RANGE); - gcc_checking_assert (operand_equal_p (min, max)); gcc_checking_assert (TREE_CODE (min) == REAL_CST); + gcc_checking_assert (TREE_CODE (max) == REAL_CST); + + if (kind == VR_UNDEFINED) + { + set_undefined (); + return; + } + + // Treat VR_ANTI_RANGE and VR_VARYING as varying. + if (kind != VR_RANGE) + { + set_varying (TREE_TYPE (min)); + return; + } m_kind = kind; m_type = TREE_TYPE (min); - REAL_VALUE_TYPE *const cst = TREE_REAL_CST_PTR (min); - if (real_isnan (cst)) - m_props.nan_set_yes (); - else - m_props.nan_set_no (); - - if (real_isinf (cst)) + // Mark NANness. + if (real_isnan (TREE_REAL_CST_PTR (min)) + || real_isnan (TREE_REAL_CST_PTR (max))) { - if (real_isneg (cst)) - { - m_props.inf_set_no (); - m_props.ninf_set_yes (); - } - else - { - m_props.inf_set_yes (); - m_props.ninf_set_no (); - } + gcc_checking_assert (operand_equal_p (min, max)); + m_props.nan_set_yes (); } else + m_props.nan_set_no (); + + bool is_min = vrp_val_is_min (min); + bool is_max = vrp_val_is_max (max); + + // Mark when the endpoints can't be INF. + if (!is_min) + m_props.ninf_set_no (); + if (!is_max) + m_props.inf_set_no (); + + // Mark when the endpoints are definitely INF. + if (operand_equal_p (min, max)) { - m_props.inf_set_no (); - m_props.ninf_set_no (); + if (is_min) + m_props.ninf_set_yes (); + else if (is_max) + m_props.inf_set_yes (); } + // Check for swapped ranges. + gcc_checking_assert (m_props.nan_yes_p () + || tree_compare (LE_EXPR, min, max)); + if (flag_checking) verify_range (); } -// Normalize range to VARYING or UNDEFINED, or vice versa. +// Normalize range to VARYING or UNDEFINED, or vice versa. Return +// TRUE if anything changed. // // A range with no known properties can be dropped to VARYING. // Similarly, a VARYING with any properties should be dropped to a // VR_RANGE. Normalizing ranges upon changing them ensures there is // only one representation for a given range. -void +bool frange::normalize_kind () { if (m_kind == VR_RANGE) { // No FP properties set means varying. - if (m_props.nan_varying_p () - && m_props.inf_varying_p () - && m_props.ninf_varying_p ()) + if (m_props.varying_p ()) { set_varying (m_type); - return; + return true; } // Undefined is viral. if (m_props.nan_undefined_p () @@ -327,17 +354,19 @@ frange::normalize_kind () || m_props.ninf_undefined_p ()) { set_undefined (); - return; + return true; } } else if (m_kind == VR_VARYING) { // If a VARYING has any FP properties, it's no longer VARYING. - if (!m_props.nan_varying_p () - || !m_props.inf_varying_p () - || !m_props.ninf_varying_p ()) - m_kind = VR_RANGE; + if (!m_props.varying_p ()) + { + m_kind = VR_RANGE; + return true; + } } + return false; } bool @@ -354,7 +383,7 @@ frange::union_ (const vrange &v) } bool ret = m_props.union_ (r.m_props); - normalize_kind (); + ret |= normalize_kind (); if (flag_checking) verify_range (); @@ -380,7 +409,7 @@ frange::intersect (const vrange &v) } bool ret = m_props.intersect (r.m_props); - normalize_kind (); + ret |= normalize_kind (); if (flag_checking) verify_range (); @@ -429,12 +458,11 @@ frange::verify_range () gcc_checking_assert (m_props.undefined_p ()); return; } - else if (varying_p ()) + if (varying_p ()) { gcc_checking_assert (m_props.varying_p ()); return; } - gcc_checking_assert (m_kind == VR_RANGE); gcc_checking_assert (!m_props.varying_p () && !m_props.undefined_p ()); } diff --git a/gcc/value-range.h b/gcc/value-range.h index c6ab955c407..390fcb8fd99 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -359,7 +359,7 @@ public: FRANGE_PROP_ACCESSOR(ninf) private: void verify_range (); - void normalize_kind (); + bool normalize_kind (); frange_props m_props; tree m_type; @@ -1010,6 +1010,45 @@ irange::normalize_kind () } } +// Return the maximum value for TYPE. + +inline tree +vrp_val_max (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 real; + real_inf (&real); + return build_real (const_cast (type), real); + } + return NULL_TREE; +} + +// Return the minimum value for TYPE. + +inline tree +vrp_val_min (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 real, real_ninf; + real_inf (&real); + real_ninf = real_value_negate (&real); + return build_real (const_cast (type), real_ninf); + } + return NULL_TREE; +} // Supporting methods for frange. @@ -1039,7 +1078,6 @@ inline frange::frange () { m_discriminator = VR_FRANGE; - m_type = nullptr; set_undefined (); } @@ -1072,32 +1110,4 @@ frange::set_undefined () m_props.set_undefined (); } - -// Return the maximum value for TYPE. - -inline tree -vrp_val_max (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); - } - return NULL_TREE; -} - -// Return the minimum value for TYPE. - -inline tree -vrp_val_min (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)); - return NULL_TREE; -} - #endif // GCC_VALUE_RANGE_H