From patchwork Wed Sep 14 15:08:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aldy Hernandez X-Patchwork-Id: 1677938 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=2620:52:3:1:0:246e:9693:128c; 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=HVCqotDX; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4MSNzD3hl8z1ypc for ; Thu, 15 Sep 2022 01:09:28 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E5C13384D141 for ; Wed, 14 Sep 2022 15:09:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E5C13384D141 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663168165; bh=4DSzsJJkv0ogqN4Gid6z6ubnWHZ9bNNzAl8pFS+EsKA=; 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=HVCqotDXUk02HYYQ3vyQxqbgnk/O3/sNhywZfchxrrdp8Q2YYC4/tRcjt6PU5ccgO r2nSbRL1ZQvMkURKzGJeN3V6P9XdmOPkDqfHRk1nvvxqJfYi+Ranzy5ESm8EaGV6Zo /2Fw34mLzSLYsCbwfzp5tdgAQR4mtb1/WpTWNCvo= 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 11FB5385841D for ; Wed, 14 Sep 2022 15:09:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 11FB5385841D 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-586-ElbHoBQxOcq_BYrWTVt6Tw-1; Wed, 14 Sep 2022 11:09:00 -0400 X-MC-Unique: ElbHoBQxOcq_BYrWTVt6Tw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5AC31101CC67 for ; Wed, 14 Sep 2022 15:09:00 +0000 (UTC) Received: from abulafia.quesejoda.com (unknown [10.40.192.189]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E3F3F40C83ED; Wed, 14 Sep 2022 15:08:59 +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 28EF8w8O1244449 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 14 Sep 2022 17:08:58 +0200 Received: (from aldyh@localhost) by abulafia.quesejoda.com (8.17.1/8.17.1/Submit) id 28EF8wbW1244448; Wed, 14 Sep 2022 17:08:58 +0200 To: GCC patches Subject: [COMMITTED] Provide cleaner set_nan(), clear_nan(), and update_nan() methods. Date: Wed, 14 Sep 2022 17:08:49 +0200 Message-Id: <20220914150852.1244397-2-aldyh@redhat.com> In-Reply-To: <20220914150852.1244397-1-aldyh@redhat.com> References: <20220914150852.1244397-1-aldyh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 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, 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" set_* has a very specific meaning for irange's and friends. Methods prefixed with set_* are setters clobbering the existing range. As such, the current set_nan() method is confusing in that it's not actually setting a range to a NAN, but twiddling the NAN flags for an existing frange. This patch replaces set_nan() with an update_nan() to set the flag, and clear_nan() to clear it. This makes the code clearer, and though the confusing tristate is still there, it will be removed in upcoming patches. Also, there is now an actual set_nan() method to set the range to a NAN. This replaces two out of class functions doing the same thing. In future patches I will also add the ability to create a NAN with a specific sign, but doing so now would be confusing because we're not tracking NAN signs. We should also submit set_signbit to the same fate, but it's about to get removed. No functional changes. Regstrapped on x86-64 Linux, plus I ran selftests for -ffinite-math-only. gcc/ChangeLog: * range-op-float.cc (frange_set_nan): Remove. (build_lt): Use set_nan, update_nan, clear_nan. (build_gt): Same. (foperator_equal::op1_range): Same. (foperator_not_equal::op1_range): Same. (foperator_lt::op1_range): Same. (foperator_lt::op2_range): Same. (foperator_le::op1_range): Same. (foperator_le::op2_range): Same. (foperator_gt::op1_range): Same. (foperator_gt::op2_range): Same. (foperator_ge::op1_range): Same. (foperator_ge::op2_range): Same. (foperator_unordered::op1_range): Same. (foperator_ordered::op1_range): Same. * value-query.cc (range_query::get_tree_range): Same. * value-range.cc (frange::set_nan): Same. (frange::update_nan): Same. (frange::union_): Same. (frange::intersect): Same. (range_tests_nan): Same. (range_tests_signed_zeros): Same. (range_tests_signbit): Same. (range_tests_floats): Same. * value-range.h (class frange): Add update_nan and clear_nan. (frange::set_nan): New. --- gcc/range-op-float.cc | 46 ++++++++++++++------------------------ gcc/value-query.cc | 4 ++-- gcc/value-range.cc | 52 +++++++++++++++++++++---------------------- gcc/value-range.h | 11 ++++----- 4 files changed, 51 insertions(+), 62 deletions(-) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 0f928b6c098..f979ca597cb 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -150,18 +150,6 @@ range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) cons return VREL_VARYING; } -// Set R to [NAN, NAN]. - -static inline void -frange_set_nan (frange &r, tree type) -{ - REAL_VALUE_TYPE rv; - bool res = real_nan (&rv, "", 1, TYPE_MODE (type)); - if (flag_checking) - gcc_assert (res); - r.set (type, rv, rv); -} - // Return TRUE if OP1 is known to be free of NANs. static inline bool @@ -248,7 +236,7 @@ build_lt (frange &r, tree type, const REAL_VALUE_TYPE &val) if (real_isinf (&val, 1)) { if (HONOR_NANS (type)) - frange_set_nan (r, type); + r.set_nan (type); else r.set_undefined (); return false; @@ -286,7 +274,7 @@ build_gt (frange &r, tree type, const REAL_VALUE_TYPE &val) if (real_isinf (&val, 0)) { if (HONOR_NANS (type)) - frange_set_nan (r, type); + r.set_nan (type); else r.set_undefined (); return false; @@ -392,14 +380,14 @@ foperator_equal::op1_range (frange &r, tree type, if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type))) r.set_signbit (fp_prop::VARYING); // The TRUE side of op1 == op2 implies op1 is !NAN. - r.set_nan (fp_prop::NO); + r.clear_nan (); break; case BRS_FALSE: r.set_varying (type); // The FALSE side of op1 == op1 implies op1 is a NAN. if (rel == VREL_EQ) - frange_set_nan (r, type); + r.set_nan (type); // If the result is false, the only time we know anything is // if OP2 is a constant. else if (op2.singleton_p () @@ -496,7 +484,7 @@ foperator_not_equal::op1_range (frange &r, tree type, if (HONOR_SIGNED_ZEROS (type) && r.contains_p (build_zero_cst (type))) r.set_signbit (fp_prop::VARYING); // The FALSE side of op1 != op2 implies op1 is !NAN. - r.set_nan (fp_prop::NO); + r.clear_nan (); break; default: @@ -563,7 +551,7 @@ foperator_lt::op1_range (frange &r, case BRS_TRUE: if (build_lt (r, type, op2.upper_bound ())) { - r.set_nan (fp_prop::NO); + r.clear_nan (); // x < y implies x is not +INF. frange_drop_inf (r, type); } @@ -591,7 +579,7 @@ foperator_lt::op2_range (frange &r, case BRS_TRUE: if (build_gt (r, type, op1.lower_bound ())) { - r.set_nan (fp_prop::NO); + r.clear_nan (); // x < y implies y is not -INF. frange_drop_ninf (r, type); } @@ -664,7 +652,7 @@ foperator_le::op1_range (frange &r, { case BRS_TRUE: if (build_le (r, type, op2.upper_bound ())) - r.set_nan (fp_prop::NO); + r.clear_nan (); break; case BRS_FALSE: @@ -688,7 +676,7 @@ foperator_le::op2_range (frange &r, { case BRS_TRUE: if (build_ge (r, type, op1.lower_bound ())) - r.set_nan (fp_prop::NO); + r.clear_nan (); break; case BRS_FALSE: @@ -759,7 +747,7 @@ foperator_gt::op1_range (frange &r, case BRS_TRUE: if (build_gt (r, type, op2.lower_bound ())) { - r.set_nan (fp_prop::NO); + r.clear_nan (); // x > y implies x is not -INF. frange_drop_ninf (r, type); } @@ -787,7 +775,7 @@ foperator_gt::op2_range (frange &r, case BRS_TRUE: if (build_lt (r, type, op1.upper_bound ())) { - r.set_nan (fp_prop::NO); + r.clear_nan (); // x > y implies y is not +INF. frange_drop_inf (r, type); } @@ -860,7 +848,7 @@ foperator_ge::op1_range (frange &r, { case BRS_TRUE: build_ge (r, type, op2.lower_bound ()); - r.set_nan (fp_prop::NO); + r.clear_nan (); break; case BRS_FALSE: @@ -887,7 +875,7 @@ foperator_ge::op2_range (frange &r, tree type, case BRS_TRUE: build_le (r, type, op1.upper_bound ()); - r.set_nan (fp_prop::NO); + r.clear_nan (); break; default: @@ -948,13 +936,13 @@ foperator_unordered::op1_range (frange &r, tree type, // Since at least one operand must be NAN, if one of them is // not, the other must be. if (!op2.maybe_nan ()) - frange_set_nan (r, type); + r.set_nan (type); break; case BRS_FALSE: r.set_varying (type); // A false UNORDERED means both operands are !NAN. - r.set_nan (fp_prop::NO); + r.clear_nan (); break; default: @@ -1011,14 +999,14 @@ foperator_ordered::op1_range (frange &r, tree type, case BRS_TRUE: r.set_varying (type); // The TRUE side of op1 ORDERED op2 implies op1 is !NAN. - r.set_nan (fp_prop::NO); + r.clear_nan (); break; case BRS_FALSE: r.set_varying (type); // The FALSE side of op1 ORDERED op1 implies op1 is !NAN. if (rel == VREL_EQ) - r.set_nan (fp_prop::NO); + r.clear_nan (); break; default: diff --git a/gcc/value-query.cc b/gcc/value-query.cc index de83f469be4..ea6e4b979ad 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -223,9 +223,9 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt) // Singletons from the tree world have known properties. REAL_VALUE_TYPE *rv = TREE_REAL_CST_PTR (expr); if (real_isnan (rv)) - f.set_nan (fp_prop::YES); + f.update_nan (fp_prop::YES); else - f.set_nan (fp_prop::NO); + f.clear_nan (); if (real_isneg (rv)) f.set_signbit (fp_prop::YES); else diff --git a/gcc/value-range.cc b/gcc/value-range.cc index d40a4ebf657..dd827421aca 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -270,7 +270,7 @@ tree_compare (tree_code code, tree op1, tree op2) // Set the NAN property. Adjust the range if appopriate. void -frange::set_nan (fp_prop::kind k) +frange::update_nan (fp_prop::kind k) { if (k == fp_prop::YES) { @@ -280,7 +280,7 @@ frange::set_nan (fp_prop::kind k) return; } gcc_checking_assert (!undefined_p ()); - *this = frange_nan (m_type); + set_nan (m_type); return; } @@ -474,7 +474,7 @@ frange::union_ (const vrange &v) *this = r; m_props = save; m_props.union_ (r.m_props); - set_nan (fp_prop::VARYING); + update_nan (fp_prop::VARYING); if (flag_checking) verify_range (); return true; @@ -482,7 +482,7 @@ frange::union_ (const vrange &v) if (r.known_nan ()) { m_props.union_ (r.m_props); - set_nan (fp_prop::VARYING); + update_nan (fp_prop::VARYING); if (flag_checking) verify_range (); return true; @@ -531,7 +531,7 @@ frange::intersect (const vrange &v) if (m_props == r.m_props) return false; - *this = frange_nan (m_type); + set_nan (m_type); return true; } // ?? Perhaps the intersection of a NAN and anything is a NAN ??. @@ -3634,14 +3634,14 @@ range_tests_nan () r1 = frange_float ("10", "12"); r0 = r1; ASSERT_EQ (r0, r1); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_NE (r0, r1); - r0.set_nan (fp_prop::YES); + r0.clear_nan (); ASSERT_NE (r0, r1); } // NAN ranges are not equal to each other. - r0 = frange_nan (float_type_node); + r0.set_nan (float_type_node); r1 = r0; ASSERT_FALSE (r0 == r1); ASSERT_FALSE (r0 == r0); @@ -3649,8 +3649,8 @@ range_tests_nan () // [5,6] U NAN = [5,6] NAN. r0 = frange_float ("5", "6"); - r0.set_nan (fp_prop::NO); - r1 = frange_nan (float_type_node); + r0.clear_nan (); + r1.set_nan (float_type_node); r0.union_ (r1); real_from_string (&q, "5"); real_from_string (&r, "6"); @@ -3659,34 +3659,34 @@ range_tests_nan () ASSERT_TRUE (r0.maybe_nan ()); // NAN U NAN = NAN - r0 = frange_nan (float_type_node); - r1 = frange_nan (float_type_node); + r0.set_nan (float_type_node); + r1.set_nan (float_type_node); r0.union_ (r1); ASSERT_TRUE (real_isnan (&r0.lower_bound ())); ASSERT_TRUE (real_isnan (&r1.upper_bound ())); ASSERT_TRUE (r0.known_nan ()); // [INF, INF] ^ NAN = VARYING - r0 = frange_nan (float_type_node); + r0.set_nan (float_type_node); r1 = frange_float ("+Inf", "+Inf"); r0.intersect (r1); ASSERT_TRUE (r0.varying_p ()); // NAN ^ NAN = NAN - r0 = frange_nan (float_type_node); - r1 = frange_nan (float_type_node); + r0.set_nan (float_type_node); + r1.set_nan (float_type_node); r0.intersect (r1); ASSERT_TRUE (r0.known_nan ()); // VARYING ^ NAN = NAN. - r0 = frange_nan (float_type_node); + r0.set_nan (float_type_node); r1.set_varying (float_type_node); r0.intersect (r1); ASSERT_TRUE (r0.known_nan ()); // Setting the NAN bit to yes, forces to range to [NAN, NAN]. r0.set_varying (float_type_node); - r0.set_nan (fp_prop::YES); + r0.update_nan (fp_prop::YES); ASSERT_TRUE (r0.known_nan ()); ASSERT_TRUE (real_isnan (&r0.lower_bound ())); ASSERT_TRUE (real_isnan (&r0.upper_bound ())); @@ -3736,7 +3736,7 @@ range_tests_signed_zeros () ASSERT_TRUE (r0.zero_p () && !r0.known_signbit (signbit)); // NAN U [5,6] should be [5,6] with no sign info. - r0 = frange_nan (float_type_node); + r0.set_nan (float_type_node); r1 = frange_float ("5", "6"); r0.union_ (r1); real_from_string (&q, "5"); @@ -3762,7 +3762,7 @@ range_tests_signbit () // the signbit property set. r0 = frange_float ("-5", "10"); r0.set_signbit (fp_prop::YES); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_TRUE (r0.known_signbit (signbit) && signbit); r1 = frange_float ("-5", "0"); ASSERT_TRUE (real_identical (&r0.lower_bound (), &r1.lower_bound ())); @@ -3770,20 +3770,20 @@ range_tests_signbit () // Negative numbers should have the SIGNBIT set. r0 = frange_float ("-5", "-1"); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_TRUE (r0.known_signbit (signbit) && signbit); // Positive numbers should have the SIGNBIT clear. r0 = frange_float ("1", "10"); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_TRUE (r0.known_signbit (signbit) && !signbit); // Numbers containing zero should have an unknown SIGNBIT. r0 = frange_float ("0", "10"); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_TRUE (!r0.known_signbit (signbit)); // Numbers spanning both positive and negative should have an // unknown SIGNBIT. r0 = frange_float ("-10", "10"); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_TRUE (!r0.known_signbit (signbit)); r0.set_varying (float_type_node); ASSERT_TRUE (!r0.known_signbit (signbit)); @@ -3791,12 +3791,12 @@ range_tests_signbit () // Ignore signbit changes when the sign bit is obviously known from // the range. r0 = frange_float ("5", "10"); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); r0.set_signbit (fp_prop::VARYING); ASSERT_TRUE (r0.known_signbit (signbit) && !signbit); r0 = frange_float ("-5", "-1"); r0.set_signbit (fp_prop::NO); - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_TRUE (r0.undefined_p ()); } @@ -3817,7 +3817,7 @@ range_tests_floats () if (r0.maybe_nan ()) ASSERT_TRUE (r0.varying_p ()); // ...unless it has some special property... - r0.set_nan (fp_prop::NO); + r0.clear_nan (); ASSERT_FALSE (r0.varying_p ()); // The endpoints of a VARYING are +-INF. diff --git a/gcc/value-range.h b/gcc/value-range.h index 0ba0193bc1f..6e896eb9ab5 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -348,6 +348,7 @@ public: virtual void set (tree, tree, value_range_kind = VR_RANGE) override; void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &, value_range_kind = VR_RANGE); + void set_nan (tree type); virtual void set_varying (tree type) override; virtual void set_undefined () override; virtual bool union_ (const vrange &) override; @@ -376,7 +377,8 @@ public: bool known_signbit (bool &signbit) const; // Accessors for FP properties. - void set_nan (fp_prop::kind f); + void update_nan (fp_prop::kind f); + void clear_nan () { update_nan (fp_prop::NO); } void set_signbit (fp_prop::kind); private: fp_prop get_nan () const { return m_props.get_nan (); } @@ -1186,13 +1188,12 @@ real_min_representable (REAL_VALUE_TYPE *r, tree type) // Build a NAN of type TYPE. -inline frange -frange_nan (tree type) +inline void +frange::set_nan (tree type) { REAL_VALUE_TYPE r; - gcc_assert (real_nan (&r, "", 1, TYPE_MODE (type))); - return frange (type, r, r); + set (type, r, r); } // Return TRUE if range is known to be finite.