On Fri, 10 Mar 2023, Jakub Jelinek wrote: > Hi! > > This patch, incremental to the just posted one, improves the reverse > operation ranges significantly by widening just by 0.5ulp in each > direction rather than 1ulp. Again, REAL_VALUE_TYPE has both wider > exponent range and wider mantissa precision (160 bits) than any > supported type, this patch uses the latter property. > > The patch doesn't do it if -frounding-math, because then the rounding > can be +-1ulp in each direction depending on the rounding mode which > we don't know, or for IBM double double because that type is just weird > and we can't trust in sane properties. > > I've performed testing of these 2 patches on 300000 random tests as with > yesterday's patch, exact numbers are in the PR, but I see very significant > improvement in the precision of the ranges while keeping it conservatively > correct. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
The flow is a little bit obfuscated, but OK. Thanks, Richard. > 2023-03-10 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/109008 > * range-op-float.cc (float_widen_lhs_range): If not > -frounding-math and not IBM double double format, extend lhs > range just by 0.5ulp rather than 1ulp in each direction. > > --- gcc/range-op-float.cc.jj 2023-03-09 12:13:57.189790814 +0100 > +++ gcc/range-op-float.cc 2023-03-09 13:12:05.248873234 +0100 > @@ -2205,8 +2205,8 @@ zero_to_inf_range (REAL_VALUE_TYPE &lb, > [1., 1.] = op1 + [1., 1.]. op1's range is not [0., 0.], but > [-0x1.0p-54, 0x1.0p-53] (when not -frounding-math), any value for > which adding 1. to it results in 1. after rounding to nearest. > - So, for op1_range/op2_range extend the lhs range by 1ulp in each > - direction. See PR109008 for more details. */ > + So, for op1_range/op2_range extend the lhs range by 1ulp (or 0.5ulp) > + in each direction. See PR109008 for more details. */ > > static frange > float_widen_lhs_range (tree type, const frange &lhs) > @@ -2230,6 +2230,14 @@ float_widen_lhs_range (tree type, const > lb = dconstm1; > SET_REAL_EXP (&lb, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1); > } > + if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type))) > + { > + /* If not -frounding-math nor IBM double double, actually widen > + just by 0.5ulp rather than 1ulp. */ > + REAL_VALUE_TYPE tem; > + real_arithmetic (&tem, PLUS_EXPR, &lhs.lower_bound (), &lb); > + real_arithmetic (&lb, RDIV_EXPR, &tem, &dconst2); > + } > } > if (real_isfinite (&ub)) > { > @@ -2240,6 +2248,14 @@ float_widen_lhs_range (tree type, const > ub = dconst1; > SET_REAL_EXP (&ub, FLOAT_MODE_FORMAT (TYPE_MODE (type))->emax + 1); > } > + if (!flag_rounding_math && !MODE_COMPOSITE_P (TYPE_MODE (type))) > + { > + /* If not -frounding-math nor IBM double double, actually widen > + just by 0.5ulp rather than 1ulp. */ > + REAL_VALUE_TYPE tem; > + real_arithmetic (&tem, PLUS_EXPR, &lhs.upper_bound (), &ub); > + real_arithmetic (&ub, RDIV_EXPR, &tem, &dconst2); > + } > } > /* Temporarily disable -ffinite-math-only, so that frange::set doesn't > reduce the range back to real_min_representable (type) as lower bound > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; HRB 36809 (AG Nuernberg)