From: Aldy Hernandez <aldyh@redhat.com>
To: GCC patches <gcc-patches@gcc.gnu.org>
Cc: Jakub Jelinek <jakub@redhat.com>,
Andrew MacLeod <amacleod@redhat.com>,
Aldy Hernandez <aldyh@redhat.com>
Subject: [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry.
Date: Wed, 9 Nov 2022 08:07:57 +0100 [thread overview]
Message-ID: <20221109070758.1030615-1-aldyh@redhat.com> (raw)
The PLUS_EXPR was always meant to be a template for further
development, since most of the binary operators will share a similar
structure. This patch abstracts out the common bits into the default
definition for range_operator_float::fold_range() and provides an
rv_fold() to be implemented by the individual entries wishing to use
the generic folder. This is akin to what we do with fold_range() and
wi_fold() in the integer version of range-ops.
gcc/ChangeLog:
* range-op-float.cc (range_operator_float::fold_range): Abstract
out from foperator_plus.
(range_operator_float::rv_fold): New.
(foperator_plus::fold_range): Remove.
(foperator_plus::rv_fold): New.
(propagate_nans): Remove.
* range-op.h (class range_operator_float): Add rv_fold.
---
gcc/range-op-float.cc | 156 +++++++++++++++++++++---------------------
gcc/range-op.h | 7 ++
2 files changed, 84 insertions(+), 79 deletions(-)
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 8282c912fc4..7075c25442a 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -49,13 +49,66 @@ along with GCC; see the file COPYING3. If not see
// Default definitions for floating point operators.
bool
-range_operator_float::fold_range (frange &r ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- const frange &lh ATTRIBUTE_UNUSED,
- const frange &rh ATTRIBUTE_UNUSED,
+range_operator_float::fold_range (frange &r, tree type,
+ const frange &op1, const frange &op2,
relation_trio) const
{
- return false;
+ if (empty_range_varying (r, type, op1, op2))
+ return true;
+ if (op1.known_isnan () || op2.known_isnan ())
+ {
+ r.set_nan (op1.type ());
+ return true;
+ }
+
+ REAL_VALUE_TYPE lb, ub;
+ bool maybe_nan;
+ rv_fold (lb, ub, maybe_nan, type,
+ op1.lower_bound (), op1.upper_bound (),
+ op2.lower_bound (), op2.upper_bound ());
+
+ // Handle possible NANs by saturating to the appropriate INF if only
+ // one end is a NAN. If both ends are a NAN, just return a NAN.
+ bool lb_nan = real_isnan (&lb);
+ bool ub_nan = real_isnan (&ub);
+ if (lb_nan && ub_nan)
+ {
+ r.set_nan (type);
+ return true;
+ }
+ if (lb_nan)
+ lb = dconstninf;
+ else if (ub_nan)
+ ub = dconstinf;
+
+ r.set (type, lb, ub);
+
+ if (lb_nan || ub_nan || maybe_nan)
+ // Keep the default NAN (with a varying sign) set by the setter.
+ ;
+ else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
+ r.clear_nan ();
+
+ return true;
+}
+
+// For a given operation, fold two sets of ranges into [lb, ub].
+// MAYBE_NAN is set to TRUE if, in addition to any result in LB or
+// UB, the final range has the possiblity of a NAN.
+void
+range_operator_float::rv_fold (REAL_VALUE_TYPE &lb,
+ REAL_VALUE_TYPE &ub,
+ bool &maybe_nan,
+ tree type ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &lh_lb ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &lh_ub ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &rh_lb ATTRIBUTE_UNUSED,
+ const REAL_VALUE_TYPE &rh_ub ATTRIBUTE_UNUSED)
+ const
+{
+ lb = dconstninf;
+ ub = dconstinf;
+ maybe_nan = true;
}
bool
@@ -192,19 +245,6 @@ frelop_early_resolve (irange &r, tree type,
&& relop_early_resolve (r, type, op1, op2, rel, my_rel));
}
-// If either operand is a NAN, set R to NAN and return TRUE.
-
-inline bool
-propagate_nans (frange &r, const frange &op1, const frange &op2)
-{
- if (op1.known_isnan () || op2.known_isnan ())
- {
- r.set_nan (op1.type ());
- return true;
- }
- return false;
-}
-
// Set VALUE to its next real value, or INF if the operation overflows.
inline void
@@ -1822,69 +1862,27 @@ foperator_unordered_equal::op1_range (frange &r, tree type,
class foperator_plus : public range_operator_float
{
- using range_operator_float::fold_range;
-
-public:
- bool fold_range (frange &r, tree type,
- const frange &lh,
- const frange &rh,
- relation_trio = TRIO_VARYING) const final override;
+ void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub, bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub) const final override
+ {
+ frange_arithmetic (PLUS_EXPR, type, lb, lh_lb, rh_lb, dconstninf);
+ frange_arithmetic (PLUS_EXPR, type, ub, lh_ub, rh_ub, dconstinf);
+
+ // [-INF] + [+INF] = NAN
+ if (real_isinf (&lh_lb, true) && real_isinf (&rh_ub, false))
+ maybe_nan = true;
+ // [+INF] + [-INF] = NAN
+ else if (real_isinf (&lh_ub, false) && real_isinf (&rh_lb, true))
+ maybe_nan = true;
+ else
+ maybe_nan = false;
+ }
} fop_plus;
-bool
-foperator_plus::fold_range (frange &r, tree type,
- const frange &op1, const frange &op2,
- relation_trio) const
-{
- if (empty_range_varying (r, type, op1, op2))
- return true;
- if (propagate_nans (r, op1, op2))
- return true;
-
- REAL_VALUE_TYPE lb, ub;
- frange_arithmetic (PLUS_EXPR, type, lb,
- op1.lower_bound (), op2.lower_bound (), dconstninf);
- frange_arithmetic (PLUS_EXPR, type, ub,
- op1.upper_bound (), op2.upper_bound (), dconstinf);
-
- // Handle possible NANs by saturating to the appropriate INF if only
- // one end is a NAN. If both ends are a NAN, just return a NAN.
- bool lb_nan = real_isnan (&lb);
- bool ub_nan = real_isnan (&ub);
- if (lb_nan && ub_nan)
- {
- r.set_nan (type);
- return true;
- }
- if (lb_nan)
- lb = dconstninf;
- else if (ub_nan)
- ub = dconstinf;
-
- r.set (type, lb, ub);
-
- // Some combinations can yield a NAN even if no operands have the
- // possibility of a NAN.
- bool maybe_nan;
- // [-INF] + [+INF] = NAN
- if (real_isinf (&op1.lower_bound (), true)
- && real_isinf (&op2.upper_bound (), false))
- maybe_nan = true;
- // [+INF] + [-INF] = NAN
- else if (real_isinf (&op1.upper_bound (), false)
- && real_isinf (&op2.lower_bound (), true))
- maybe_nan = true;
- else
- maybe_nan = false;
-
- if (lb_nan || ub_nan || maybe_nan)
- // Keep the default NAN (with a varying sign) set by the setter.
- ;
- else if (!op1.maybe_isnan () && !op2.maybe_isnan ())
- r.clear_nan ();
-
- return true;
-}
// Instantiate a range_op_table for floating point operations.
static floating_op_table global_floating_table;
diff --git a/gcc/range-op.h b/gcc/range-op.h
index c7249890142..442a6e1d299 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -117,6 +117,13 @@ public:
const frange &lh,
const frange &rh,
relation_trio = TRIO_VARYING) const;
+ virtual void rv_fold (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
+ bool &maybe_nan,
+ tree type,
+ const REAL_VALUE_TYPE &lh_lb,
+ const REAL_VALUE_TYPE &lh_ub,
+ const REAL_VALUE_TYPE &rh_lb,
+ const REAL_VALUE_TYPE &rh_ub) const;
// Unary operations have the range of the LHS as op2.
virtual bool fold_range (irange &r, tree type,
const frange &lh,
--
2.38.1
next reply other threads:[~2022-11-09 7:08 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-09 7:07 Aldy Hernandez [this message]
2022-11-09 7:07 ` [COMMITTED] [range-op-float] Implement MINUS_EXPR Aldy Hernandez
2022-11-09 13:49 ` Xi Ruoyao
2022-11-09 13:58 ` Xi Ruoyao
2022-11-09 15:45 ` Aldy Hernandez
2022-11-09 12:48 ` [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry Jakub Jelinek
2022-11-09 13:14 ` Aldy Hernandez
2022-11-09 13:32 ` Jakub Jelinek
2022-11-09 14:19 ` Jakub Jelinek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221109070758.1030615-1-aldyh@redhat.com \
--to=aldyh@redhat.com \
--cc=amacleod@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).