public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry.
@ 2022-11-09  7:07 Aldy Hernandez
  2022-11-09  7:07 ` [COMMITTED] [range-op-float] Implement MINUS_EXPR Aldy Hernandez
  2022-11-09 12:48 ` [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry Jakub Jelinek
  0 siblings, 2 replies; 9+ messages in thread
From: Aldy Hernandez @ 2022-11-09  7:07 UTC (permalink / raw)
  To: GCC patches; +Cc: Jakub Jelinek, Andrew MacLeod, Aldy Hernandez

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


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [COMMITTED] [range-op-float] Implement MINUS_EXPR.
  2022-11-09  7:07 [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry Aldy Hernandez
@ 2022-11-09  7:07 ` Aldy Hernandez
  2022-11-09 13:49   ` Xi Ruoyao
  2022-11-09 12:48 ` [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry Jakub Jelinek
  1 sibling, 1 reply; 9+ messages in thread
From: Aldy Hernandez @ 2022-11-09  7:07 UTC (permalink / raw)
  To: GCC patches; +Cc: Jakub Jelinek, Andrew MacLeod, Aldy Hernandez

Now that the generic parts of the binary operators have been
abstracted, implementing MINUS_EXPR is a cinch.

The op[12]_range entries will be submitted as a follow-up.

gcc/ChangeLog:

	* range-op-float.cc (class foperator_minus): New.
	(floating_op_table::floating_op_table): Add MINUS_EXPR entry.
---
 gcc/range-op-float.cc | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 7075c25442a..d52e971f84e 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -1884,6 +1884,29 @@ class foperator_plus : public range_operator_float
 } fop_plus;
 
 
+class foperator_minus : public range_operator_float
+{
+  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 (MINUS_EXPR, type, lb, lh_lb, rh_ub, dconstninf);
+    frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb, dconstinf);
+
+    // [+INF] - [+INF] = NAN
+    if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
+      maybe_nan = true;
+    // [-INF] - [-INF] = NAN
+    else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
+      maybe_nan = true;
+    else
+      maybe_nan = false;
+  }
+} fop_minus;
+
 // Instantiate a range_op_table for floating point operations.
 static floating_op_table global_floating_table;
 
@@ -1917,6 +1940,7 @@ floating_op_table::floating_op_table ()
   set (ABS_EXPR, fop_abs);
   set (NEGATE_EXPR, fop_negate);
   set (PLUS_EXPR, fop_plus);
+  set (MINUS_EXPR, fop_minus);
 }
 
 // Return a pointer to the range_operator_float instance, if there is
-- 
2.38.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry.
  2022-11-09  7:07 [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry Aldy Hernandez
  2022-11-09  7:07 ` [COMMITTED] [range-op-float] Implement MINUS_EXPR Aldy Hernandez
@ 2022-11-09 12:48 ` Jakub Jelinek
  2022-11-09 13:14   ` Aldy Hernandez
  1 sibling, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2022-11-09 12:48 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: GCC patches, Andrew MacLeod

On Wed, Nov 09, 2022 at 08:07:57AM +0100, Aldy Hernandez wrote:
> 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.

Shouldn't foperator_mult be very similar to this (except that until
division is done op[12]_range can't be implemented), with the exception
that the invalid case isn't -INF + INF or INF + -INF, but
0 * +/-INF or +/-INF * 0?

	Jakub


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry.
  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
  0 siblings, 1 reply; 9+ messages in thread
From: Aldy Hernandez @ 2022-11-09 13:14 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: GCC patches, Andrew MacLeod

On Wed, Nov 9, 2022 at 1:48 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Wed, Nov 09, 2022 at 08:07:57AM +0100, Aldy Hernandez wrote:
> > 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.
>
> Shouldn't foperator_mult be very similar to this (except that until
> division is done op[12]_range can't be implemented), with the exception
> that the invalid case isn't -INF + INF or INF + -INF, but
> 0 * +/-INF or +/-INF * 0?

Multiplication and division are tricky because you have to keep track
of signs to order the resulting range.  It's the most annoying pattern
we have for integers:

// Multiplications, divisions and shifts are a bit tricky to handle,
// depending on the mix of signs we have in the two ranges, we need to
// operate on different values to get the minimum and maximum values
// for the new range.  One approach is to figure out all the
// variations of range combinations and do the operations.
//
// However, this involves several calls to compare_values and it is
// pretty convoluted.  It's simpler to do the 4 operations (MIN0 OP
// MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP MAX1) and then
// figure the smallest and largest values to form the new range.

But if you have a simpler approach, have at it.  I may have to bail on
multiplication and division for this cycle, cause I'm running out of
cycles :-/.

Hmmm...even if we don't get to implement mult/div in this cycle,
perhaps we could at least figure out if we'll NAN as you've suggested
above.  So, set [-INF,+INF] but without a NAN when applicable.

Aldy


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry.
  2022-11-09 13:14   ` Aldy Hernandez
@ 2022-11-09 13:32     ` Jakub Jelinek
  2022-11-09 14:19       ` Jakub Jelinek
  0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2022-11-09 13:32 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: GCC patches, Andrew MacLeod

On Wed, Nov 09, 2022 at 02:14:19PM +0100, Aldy Hernandez wrote:
> On Wed, Nov 9, 2022 at 1:48 PM Jakub Jelinek <jakub@redhat.com> wrote:
> >
> > On Wed, Nov 09, 2022 at 08:07:57AM +0100, Aldy Hernandez wrote:
> > > 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.
> >
> > Shouldn't foperator_mult be very similar to this (except that until
> > division is done op[12]_range can't be implemented), with the exception
> > that the invalid case isn't -INF + INF or INF + -INF, but
> > 0 * +/-INF or +/-INF * 0?
> 
> Multiplication and division are tricky because you have to keep track
> of signs to order the resulting range.  It's the most annoying pattern
> we have for integers:

Ah, you're right.
Reminds me of check_for_binary_op_overflow for multiplication.

	Jakub


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Implement MINUS_EXPR.
  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
  0 siblings, 1 reply; 9+ messages in thread
From: Xi Ruoyao @ 2022-11-09 13:49 UTC (permalink / raw)
  To: Aldy Hernandez, GCC patches; +Cc: Jakub Jelinek, Andrew MacLeod

[-- Attachment #1: Type: text/plain, Size: 2618 bytes --]

Hi Aldy,

This commit breaks the attached test case at -O2 on x86_64-linux-gnu and
loongarch64-linux-gnu :(.

The code is simplified from Glibc: the breakage causes two Glibc test
failures on loongarch64-linux-gnu.

Reverting the commit can fix the breakage.

On Wed, 2022-11-09 at 08:07 +0100, Aldy Hernandez via Gcc-patches wrote:
> Now that the generic parts of the binary operators have been
> abstracted, implementing MINUS_EXPR is a cinch.
> 
> The op[12]_range entries will be submitted as a follow-up.
> 
> gcc/ChangeLog:
> 
>         * range-op-float.cc (class foperator_minus): New.
>         (floating_op_table::floating_op_table): Add MINUS_EXPR entry.
> ---
>  gcc/range-op-float.cc | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
> index 7075c25442a..d52e971f84e 100644
> --- a/gcc/range-op-float.cc
> +++ b/gcc/range-op-float.cc
> @@ -1884,6 +1884,29 @@ class foperator_plus : public
> range_operator_float
>  } fop_plus;
>  
>  
> +class foperator_minus : public range_operator_float
> +{
> +  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 (MINUS_EXPR, type, lb, lh_lb, rh_ub,
> dconstninf);
> +    frange_arithmetic (MINUS_EXPR, type, ub, lh_ub, rh_lb,
> dconstinf);
> +
> +    // [+INF] - [+INF] = NAN
> +    if (real_isinf (&lh_ub, false) && real_isinf (&rh_ub, false))
> +      maybe_nan = true;
> +    // [-INF] - [-INF] = NAN
> +    else if (real_isinf (&lh_lb, true) && real_isinf (&rh_lb, true))
> +      maybe_nan = true;
> +    else
> +      maybe_nan = false;
> +  }
> +} fop_minus;
> +
>  // Instantiate a range_op_table for floating point operations.
>  static floating_op_table global_floating_table;
>  
> @@ -1917,6 +1940,7 @@ floating_op_table::floating_op_table ()
>    set (ABS_EXPR, fop_abs);
>    set (NEGATE_EXPR, fop_negate);
>    set (PLUS_EXPR, fop_plus);
> +  set (MINUS_EXPR, fop_minus);
>  }
>  
>  // Return a pointer to the range_operator_float instance, if there is

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

[-- Attachment #2: test1.c --]
[-- Type: text/x-csrc, Size: 417 bytes --]

__attribute__((noipa,noinline))
int t(double a, double b)
{
	double c = a - b;
	if (!__builtin_isfinite(c)) {
		if (__builtin_isnan(c)) {
			if (!__builtin_isnan(a) && !__builtin_isnan(b))
				return 1;
		} else if (__builtin_isfinite(a) && __builtin_isfinite(b))
			return 2;
	} else if (c == 0 && a != b)
		return 3;
	return 4;
}

int main()
{
	double a = __builtin_inf();
	if (t(a, a) != 1)
		__builtin_abort();
}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Implement MINUS_EXPR.
  2022-11-09 13:49   ` Xi Ruoyao
@ 2022-11-09 13:58     ` Xi Ruoyao
  2022-11-09 15:45       ` Aldy Hernandez
  0 siblings, 1 reply; 9+ messages in thread
From: Xi Ruoyao @ 2022-11-09 13:58 UTC (permalink / raw)
  To: Aldy Hernandez, GCC patches; +Cc: Jakub Jelinek, Andrew MacLeod

On Wed, 2022-11-09 at 21:49 +0800, Xi Ruoyao wrote:
> Hi Aldy,
> 
> This commit breaks the attached test case at -O2 on x86_64-linux-gnu and
  ^^^^^^^^^^^

Ah, not this one.  I meant r13-3842 "Implement op[12]_range operators
for PLUS_EXPR and MINUS_EXPR."

> loongarch64-linux-gnu :(.
> 
> The code is simplified from Glibc: the breakage causes two Glibc test
> failures on loongarch64-linux-gnu.
> 
> Reverting the commit can fix the breakage.
            ^^^^^^^^^^ also r13-3842.

/* snip */

> > The op[12]_range entries will be submitted as a follow-up.

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry.
  2022-11-09 13:32     ` Jakub Jelinek
@ 2022-11-09 14:19       ` Jakub Jelinek
  0 siblings, 0 replies; 9+ messages in thread
From: Jakub Jelinek @ 2022-11-09 14:19 UTC (permalink / raw)
  To: Aldy Hernandez, GCC patches, Andrew MacLeod

On Wed, Nov 09, 2022 at 02:32:55PM +0100, Jakub Jelinek wrote:
> On Wed, Nov 09, 2022 at 02:14:19PM +0100, Aldy Hernandez wrote:
> > On Wed, Nov 9, 2022 at 1:48 PM Jakub Jelinek <jakub@redhat.com> wrote:
> > >
> > > On Wed, Nov 09, 2022 at 08:07:57AM +0100, Aldy Hernandez wrote:
> > > > 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.
> > >
> > > Shouldn't foperator_mult be very similar to this (except that until
> > > division is done op[12]_range can't be implemented), with the exception
> > > that the invalid case isn't -INF + INF or INF + -INF, but
> > > 0 * +/-INF or +/-INF * 0?
> > 
> > Multiplication and division are tricky because you have to keep track
> > of signs to order the resulting range.  It's the most annoying pattern
> > we have for integers:
> 
> Ah, you're right.
> Reminds me of check_for_binary_op_overflow for multiplication.

On the other side, thinking more about it, it should be easier than
integral, because we don't need to deal with unsigned/wrap around and
overflows aren't undefined, but infinities (though I guess we still have
even for +/- the question how actually say PDP floats or ARM non-IEEE
mode __fp16 behave on overflows for floats that don't support infinities,
if it is saturating on HUGE_VAL*/-HUGE_VAL* or wraps around).
So just do the cross products, sort them to create the final range,
clear_nans on it and provide nans the normal way?

	Jakub


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [COMMITTED] [range-op-float] Implement MINUS_EXPR.
  2022-11-09 13:58     ` Xi Ruoyao
@ 2022-11-09 15:45       ` Aldy Hernandez
  0 siblings, 0 replies; 9+ messages in thread
From: Aldy Hernandez @ 2022-11-09 15:45 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: GCC patches, Jakub Jelinek, Andrew MacLeod

I have reverted the patch while I sort this out.

Thanks for the report and especially for the distilled test.  It's very useful.

Aldy

On Wed, Nov 9, 2022 at 2:58 PM Xi Ruoyao <xry111@xry111.site> wrote:
>
> On Wed, 2022-11-09 at 21:49 +0800, Xi Ruoyao wrote:
> > Hi Aldy,
> >
> > This commit breaks the attached test case at -O2 on x86_64-linux-gnu and
>   ^^^^^^^^^^^
>
> Ah, not this one.  I meant r13-3842 "Implement op[12]_range operators
> for PLUS_EXPR and MINUS_EXPR."
>
> > loongarch64-linux-gnu :(.
> >
> > The code is simplified from Glibc: the breakage causes two Glibc test
> > failures on loongarch64-linux-gnu.
> >
> > Reverting the commit can fix the breakage.
>             ^^^^^^^^^^ also r13-3842.
>
> /* snip */
>
> > > The op[12]_range entries will be submitted as a follow-up.
>
> --
> Xi Ruoyao <xry111@xry111.site>
> School of Aerospace Science and Technology, Xidian University
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-11-09 15:45 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-09  7:07 [COMMITTED] [range-op-float] Abstract out binary operator code out of PLUS_EXPR entry Aldy Hernandez
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

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).