Re: [RFA] Implement basic range operators to enable floating point VRP.

2022-08-02 Thread Aldy Hernandez via Gcc-patches
Alright, I know everyon'es pretty busy and I am blocking myself here,
so I hereby approve my own patch, since I am the maintainer ;-).

After all, I'd like to have 5-6 days to field any possible fallout
before I disappear off to a tropical island to drink mojitos and beer.
Ok, not really-- just changing diapers, but without a laptop.

Feedback still welcome; I'll just address it as a follow-up.

Pushed.
Aldy

On Sun, Jul 31, 2022 at 8:11 PM Aldy Hernandez  wrote:
>
> PING
>
> Andrew, anyone, would you mind giving this a once over?  I realize
> reviewing ranger's range-op code is not on anyone's list of
> priorities, but I could use a sanity check.
>
> The patch is sufficiently self-contained to easily catch anything
> caused by it, and I'd like to commit earlier in the week to have
> enough time to field any possible fallout before I take a few days off
> next week.
>
> Updated patch attached.
>
> Thanks.
> Aldy
>
> On Mon, Jul 25, 2022 at 8:50 PM Aldy Hernandez  wrote:
> >
> > Without further ado, here is the implementation for floating point
> > range operators, plus the switch to enable all ranger clients to
> > handle floats.
> >
> > These are bare bone implementations good enough for relation operators
> > to work, while keeping the NAN bits up to date in the frange.  There
> > is also minimal support for keeping track of +-INF when it is obvious.
> >
> > I have included some basic tests to help get a feel of what is
> > ultimately handled.
> >
> > Since range-ops is the domain specific core of ranger, I think its
> > best if a global maintainer or an FP expert could review this.
> >
> > OK for trunk?
> >
> > Tested on x86-64 Linux.
> >
> > p.s. I haven't done extensive testing in DOM, but with this we're mighty
> > close for the forward threader there to be replaceable with the backward
> > threader, thus removing the last use of the forward threader.
> >
> > gcc/ChangeLog:
> >
> > * range-op-float.cc (finite_operands_p): New.
> > (frelop_early_resolve): New.
> > (default_frelop_fold_range): New.
> > (class foperator_equal): New.
> > (class foperator_not_equal): New.
> > (class foperator_lt): New.
> > (class foperator_le): New.
> > (class foperator_gt): New.
> > (class foperator_ge): New.
> > (class foperator_unordered): New.
> > (class foperator_ordered): New.
> > (class foperator_relop_unknown): New.
> > (floating_op_table::floating_op_table): Add above classes to
> > floating op table.
> > * value-range.h (frange::supports_p): Enable.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/opt/pr94589-2.C: Add notes.
> > * gcc.dg/tree-ssa/vrp-float-1.c: New test.
> > * gcc.dg/tree-ssa/vrp-float-11.c: New test.
> > * gcc.dg/tree-ssa/vrp-float-3.c: New test.
> > * gcc.dg/tree-ssa/vrp-float-4.c: New test.
> > * gcc.dg/tree-ssa/vrp-float-6.c: New test.
> > * gcc.dg/tree-ssa/vrp-float-7.c: New test.
> > * gcc.dg/tree-ssa/vrp-float-8.c: New test.
> > ---
> >  gcc/range-op-float.cc| 564 +++
> >  gcc/testsuite/g++.dg/opt/pr94589-2.C |  25 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c  |  19 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c |  26 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c  |  18 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c  |  16 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c  |  20 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c  |  14 +
> >  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c  |  26 +
> >  gcc/value-range.h|   3 +-
> >  10 files changed, 729 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c
> >  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c
> >
> > diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
> > index 8e9d83e3827..d94ff6f915a 100644
> > --- a/gcc/range-op-float.cc
> > +++ b/gcc/range-op-float.cc
> > @@ -150,6 +150,50 @@ range_operator_float::op1_op2_relation (const irange 
> >  ATTRIBUTE_UNUSED) cons
> >return VREL_VARYING;
> >  }
> >
> > +// Return TRUE if OP1 and OP2 are known to be free of NANs.
> > +
> > +static inline bool
> > +finite_operands_p (const frange , const frange )
> > +{
> > +  return (flag_finite_math_only
> > + || (op1.get_nan ().no_p ()
> > + && op2.get_nan ().no_p ()));
> > +}
> > +
> > +// Floating version of relop_early_resolve that takes into account NAN
> > +// and -ffinite-math-only.
> > +
> > +inline bool
> > +frelop_early_resolve (irange 

Re: [RFA] Implement basic range operators to enable floating point VRP.

2022-07-31 Thread Aldy Hernandez via Gcc-patches
PING

Andrew, anyone, would you mind giving this a once over?  I realize
reviewing ranger's range-op code is not on anyone's list of
priorities, but I could use a sanity check.

The patch is sufficiently self-contained to easily catch anything
caused by it, and I'd like to commit earlier in the week to have
enough time to field any possible fallout before I take a few days off
next week.

Updated patch attached.

Thanks.
Aldy

On Mon, Jul 25, 2022 at 8:50 PM Aldy Hernandez  wrote:
>
> Without further ado, here is the implementation for floating point
> range operators, plus the switch to enable all ranger clients to
> handle floats.
>
> These are bare bone implementations good enough for relation operators
> to work, while keeping the NAN bits up to date in the frange.  There
> is also minimal support for keeping track of +-INF when it is obvious.
>
> I have included some basic tests to help get a feel of what is
> ultimately handled.
>
> Since range-ops is the domain specific core of ranger, I think its
> best if a global maintainer or an FP expert could review this.
>
> OK for trunk?
>
> Tested on x86-64 Linux.
>
> p.s. I haven't done extensive testing in DOM, but with this we're mighty
> close for the forward threader there to be replaceable with the backward
> threader, thus removing the last use of the forward threader.
>
> gcc/ChangeLog:
>
> * range-op-float.cc (finite_operands_p): New.
> (frelop_early_resolve): New.
> (default_frelop_fold_range): New.
> (class foperator_equal): New.
> (class foperator_not_equal): New.
> (class foperator_lt): New.
> (class foperator_le): New.
> (class foperator_gt): New.
> (class foperator_ge): New.
> (class foperator_unordered): New.
> (class foperator_ordered): New.
> (class foperator_relop_unknown): New.
> (floating_op_table::floating_op_table): Add above classes to
> floating op table.
> * value-range.h (frange::supports_p): Enable.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/opt/pr94589-2.C: Add notes.
> * gcc.dg/tree-ssa/vrp-float-1.c: New test.
> * gcc.dg/tree-ssa/vrp-float-11.c: New test.
> * gcc.dg/tree-ssa/vrp-float-3.c: New test.
> * gcc.dg/tree-ssa/vrp-float-4.c: New test.
> * gcc.dg/tree-ssa/vrp-float-6.c: New test.
> * gcc.dg/tree-ssa/vrp-float-7.c: New test.
> * gcc.dg/tree-ssa/vrp-float-8.c: New test.
> ---
>  gcc/range-op-float.cc| 564 +++
>  gcc/testsuite/g++.dg/opt/pr94589-2.C |  25 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c  |  19 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c |  26 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c  |  18 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c  |  16 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c  |  20 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c  |  14 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c  |  26 +
>  gcc/value-range.h|   3 +-
>  10 files changed, 729 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c
>
> diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
> index 8e9d83e3827..d94ff6f915a 100644
> --- a/gcc/range-op-float.cc
> +++ b/gcc/range-op-float.cc
> @@ -150,6 +150,50 @@ range_operator_float::op1_op2_relation (const irange 
>  ATTRIBUTE_UNUSED) cons
>return VREL_VARYING;
>  }
>
> +// Return TRUE if OP1 and OP2 are known to be free of NANs.
> +
> +static inline bool
> +finite_operands_p (const frange , const frange )
> +{
> +  return (flag_finite_math_only
> + || (op1.get_nan ().no_p ()
> + && op2.get_nan ().no_p ()));
> +}
> +
> +// Floating version of relop_early_resolve that takes into account NAN
> +// and -ffinite-math-only.
> +
> +inline bool
> +frelop_early_resolve (irange , tree type,
> + const frange , const frange ,
> + relation_kind rel, relation_kind my_rel)
> +{
> +  // If either operand is undefined, return VARYING.
> +  if (empty_range_varying (r, type, op1, op2))
> +return true;
> +
> +  // We can fold relations from the oracle when we know both operands
> +  // are free of NANs, or when -ffinite-math-only.
> +  return (finite_operands_p (op1, op2)
> + && relop_early_resolve (r, type, op1, op2, rel, my_rel));
> +}
> +
> +// Default implementation of fold_range for relational operators.
> +// This amounts to passing on any known relations from the oracle, iff
> +// we know the operands are 

Re: [RFA] Implement basic range operators to enable floating point VRP.

2022-07-25 Thread Aldy Hernandez via Gcc-patches
I forgot to mention.  There's a regression in g++.dg/opt/pr94589-2.C,
where an early optimization by evrp causes phiopt to no longer
optimize a spaceship operator because it no longer sees the exact
sequence of conditionals.  I have included the analysis in the patch.
Hopefully a phiopt expert can opine.

Aldy

On Mon, Jul 25, 2022 at 8:50 PM Aldy Hernandez  wrote:
>
> Without further ado, here is the implementation for floating point
> range operators, plus the switch to enable all ranger clients to
> handle floats.
>
> These are bare bone implementations good enough for relation operators
> to work, while keeping the NAN bits up to date in the frange.  There
> is also minimal support for keeping track of +-INF when it is obvious.
>
> I have included some basic tests to help get a feel of what is
> ultimately handled.
>
> Since range-ops is the domain specific core of ranger, I think its
> best if a global maintainer or an FP expert could review this.
>
> OK for trunk?
>
> Tested on x86-64 Linux.
>
> p.s. I haven't done extensive testing in DOM, but with this we're mighty
> close for the forward threader there to be replaceable with the backward
> threader, thus removing the last use of the forward threader.
>
> gcc/ChangeLog:
>
> * range-op-float.cc (finite_operands_p): New.
> (frelop_early_resolve): New.
> (default_frelop_fold_range): New.
> (class foperator_equal): New.
> (class foperator_not_equal): New.
> (class foperator_lt): New.
> (class foperator_le): New.
> (class foperator_gt): New.
> (class foperator_ge): New.
> (class foperator_unordered): New.
> (class foperator_ordered): New.
> (class foperator_relop_unknown): New.
> (floating_op_table::floating_op_table): Add above classes to
> floating op table.
> * value-range.h (frange::supports_p): Enable.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/opt/pr94589-2.C: Add notes.
> * gcc.dg/tree-ssa/vrp-float-1.c: New test.
> * gcc.dg/tree-ssa/vrp-float-11.c: New test.
> * gcc.dg/tree-ssa/vrp-float-3.c: New test.
> * gcc.dg/tree-ssa/vrp-float-4.c: New test.
> * gcc.dg/tree-ssa/vrp-float-6.c: New test.
> * gcc.dg/tree-ssa/vrp-float-7.c: New test.
> * gcc.dg/tree-ssa/vrp-float-8.c: New test.
> ---
>  gcc/range-op-float.cc| 564 +++
>  gcc/testsuite/g++.dg/opt/pr94589-2.C |  25 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c  |  19 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c |  26 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c  |  18 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c  |  16 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c  |  20 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c  |  14 +
>  gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c  |  26 +
>  gcc/value-range.h|   3 +-
>  10 files changed, 729 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c
>
> diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
> index 8e9d83e3827..d94ff6f915a 100644
> --- a/gcc/range-op-float.cc
> +++ b/gcc/range-op-float.cc
> @@ -150,6 +150,50 @@ range_operator_float::op1_op2_relation (const irange 
>  ATTRIBUTE_UNUSED) cons
>return VREL_VARYING;
>  }
>
> +// Return TRUE if OP1 and OP2 are known to be free of NANs.
> +
> +static inline bool
> +finite_operands_p (const frange , const frange )
> +{
> +  return (flag_finite_math_only
> + || (op1.get_nan ().no_p ()
> + && op2.get_nan ().no_p ()));
> +}
> +
> +// Floating version of relop_early_resolve that takes into account NAN
> +// and -ffinite-math-only.
> +
> +inline bool
> +frelop_early_resolve (irange , tree type,
> + const frange , const frange ,
> + relation_kind rel, relation_kind my_rel)
> +{
> +  // If either operand is undefined, return VARYING.
> +  if (empty_range_varying (r, type, op1, op2))
> +return true;
> +
> +  // We can fold relations from the oracle when we know both operands
> +  // are free of NANs, or when -ffinite-math-only.
> +  return (finite_operands_p (op1, op2)
> + && relop_early_resolve (r, type, op1, op2, rel, my_rel));
> +}
> +
> +// Default implementation of fold_range for relational operators.
> +// This amounts to passing on any known relations from the oracle, iff
> +// we know the operands are not NAN or -ffinite-math-only holds.
> +
> +static inline bool
> +default_frelop_fold_range (irange , tree type,
> +  

[RFA] Implement basic range operators to enable floating point VRP.

2022-07-25 Thread Aldy Hernandez via Gcc-patches
Without further ado, here is the implementation for floating point
range operators, plus the switch to enable all ranger clients to
handle floats.

These are bare bone implementations good enough for relation operators
to work, while keeping the NAN bits up to date in the frange.  There
is also minimal support for keeping track of +-INF when it is obvious.

I have included some basic tests to help get a feel of what is
ultimately handled.

Since range-ops is the domain specific core of ranger, I think its
best if a global maintainer or an FP expert could review this.

OK for trunk?

Tested on x86-64 Linux.

p.s. I haven't done extensive testing in DOM, but with this we're mighty
close for the forward threader there to be replaceable with the backward
threader, thus removing the last use of the forward threader.

gcc/ChangeLog:

* range-op-float.cc (finite_operands_p): New.
(frelop_early_resolve): New.
(default_frelop_fold_range): New.
(class foperator_equal): New.
(class foperator_not_equal): New.
(class foperator_lt): New.
(class foperator_le): New.
(class foperator_gt): New.
(class foperator_ge): New.
(class foperator_unordered): New.
(class foperator_ordered): New.
(class foperator_relop_unknown): New.
(floating_op_table::floating_op_table): Add above classes to
floating op table.
* value-range.h (frange::supports_p): Enable.

gcc/testsuite/ChangeLog:

* g++.dg/opt/pr94589-2.C: Add notes.
* gcc.dg/tree-ssa/vrp-float-1.c: New test.
* gcc.dg/tree-ssa/vrp-float-11.c: New test.
* gcc.dg/tree-ssa/vrp-float-3.c: New test.
* gcc.dg/tree-ssa/vrp-float-4.c: New test.
* gcc.dg/tree-ssa/vrp-float-6.c: New test.
* gcc.dg/tree-ssa/vrp-float-7.c: New test.
* gcc.dg/tree-ssa/vrp-float-8.c: New test.
---
 gcc/range-op-float.cc| 564 +++
 gcc/testsuite/g++.dg/opt/pr94589-2.C |  25 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c  |  19 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c |  26 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c  |  18 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c  |  16 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c  |  20 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c  |  14 +
 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c  |  26 +
 gcc/value-range.h|   3 +-
 10 files changed, 729 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-11.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-3.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-4.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-6.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-7.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp-float-8.c

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 8e9d83e3827..d94ff6f915a 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -150,6 +150,50 @@ range_operator_float::op1_op2_relation (const irange  
ATTRIBUTE_UNUSED) cons
   return VREL_VARYING;
 }
 
+// Return TRUE if OP1 and OP2 are known to be free of NANs.
+
+static inline bool
+finite_operands_p (const frange , const frange )
+{
+  return (flag_finite_math_only
+ || (op1.get_nan ().no_p ()
+ && op2.get_nan ().no_p ()));
+}
+
+// Floating version of relop_early_resolve that takes into account NAN
+// and -ffinite-math-only.
+
+inline bool
+frelop_early_resolve (irange , tree type,
+ const frange , const frange ,
+ relation_kind rel, relation_kind my_rel)
+{
+  // If either operand is undefined, return VARYING.
+  if (empty_range_varying (r, type, op1, op2))
+return true;
+
+  // We can fold relations from the oracle when we know both operands
+  // are free of NANs, or when -ffinite-math-only.
+  return (finite_operands_p (op1, op2)
+ && relop_early_resolve (r, type, op1, op2, rel, my_rel));
+}
+
+// Default implementation of fold_range for relational operators.
+// This amounts to passing on any known relations from the oracle, iff
+// we know the operands are not NAN or -ffinite-math-only holds.
+
+static inline bool
+default_frelop_fold_range (irange , tree type,
+ const frange , const frange ,
+ relation_kind rel, relation_kind my_rel)
+{
+  if (frelop_early_resolve (r, type, op1, op2, rel, my_rel))
+return true;
+
+  r.set_varying (type);
+  return true;
+}
+
 class foperator_identity : public range_operator_float
 {
   using range_operator_float::fold_range;
@@ -172,6 +216,509 @@ class foperator_identity : public range_operator_float
 public:
 } fop_identity;
 
+class foperator_equal : public range_operator_float
+{
+  using range_operator_float::fold_range;
+  using