Hi Aldy,
The proposed frange implementation looks cool.  The one technical tweak is
that if x is not NaN and not +Inf/-Inf, then x*0.0 is [-0.0,0.0].  It's because 
this
result is a range and not a constant that it can’t normally be constant folded,
unless it appears in a context where the sign of zero isn't important (such as
a comparison).

I suspect that frange needs pos_zero_p, neg_zero_p and any_zero_p instead
of just zero_p (and variants r.set_zero) to capture the subtleties.

Cheers,
Roger
--

> -----Original Message-----
> From: Aldy Hernandez <al...@redhat.com>
> Sent: 21 March 2022 05:56
> To: Jeff Law <jeffreya...@gmail.com>
> Cc: Andrew MacLeod <amacl...@redhat.com>; Roger Sayle
> <ro...@nextmovesoftware.com>; Richard Biener
> <richard.guent...@gmail.com>; GCC Patches <gcc-patches@gcc.gnu.org>
> Subject: Re: [PATCH] Ignore (possible) signed zeros in operands of FP
> comparisons.
> 
> On Fri, Mar 18, 2022 at 7:33 PM Aldy Hernandez <al...@redhat.com> wrote:
> 
> > > >>>>> Consider the following interesting example:
> > > >>>>>
> > > >>>>> int foo(int x, double y) {
> > > >>>>>      return (x * 0.0) < y;
> > > >>>>> }
> > > >>>>>
> > > >>>>> Although we know that x (when converted to double) can't be
> > > >>>>> NaN or Inf, we still worry that for negative values of x that
> > > >>>>> (x * 0.0) may be -0.0 and so perform the multiplication at
> > > >>>>> run-time. But in this case, the result of the comparison (-0.0
> > > >>>>> < y) will be exactly the same as (+0.0 < y) for any y, hence
> > > >>>>> the above may be safely constant folded to "0.0 <
> > > >>>> y"
> > > >>>>> avoiding the multiplication at run-time.
> 
> Ok, once the "frange" infrastructure is in place, it's actually trivial.  See 
> attached
> patch and tests.  We can do everything with small range-op entries and evrp /
> ranger will handle everything else.
> 
> Roger, I believe this is what you described:
> 
> +// { dg-do compile }
> +// { dg-options "-O2 -fno-tree-forwprop -fno-thread-jumps
> -fdump-tree-evrp -fdump-tree-optimized" }
> +
> +extern void link_error ();
> +
> +int foo(int x, double y)
> +{
> +      return (x * 0.0) < y;
> +}
> +
> +// The multiply should be gone by *vrp time.
> +// { dg-final { scan-tree-dump-not " \\* " "evrp" } }
> +
> +// Ultimately, there sound be no references to "x".
> +// { dg-final { scan-tree-dump-not "x_" "optimized" } }
> 
> With the attached patch (and pending patches), we keep track that a cast from
> int to float is guaranteed to not be NaN, which allows us to fold x*0.0 into 
> 0.0,
> and DCE to remove x altogether.  Also, as the other tests show, we are able to
> resolve __builtin_isnan's for the operations implemented.  It should be
> straightforward for someone with floating point foo to extend this to all
> operations.
> 
> Aldy

Reply via email to