On Fri, Nov 11, 2022 at 11:12:01AM +0100, Aldy Hernandez wrote:
> > --- gcc/range-op-float.cc.jj        2022-11-11 10:13:30.879410560 +0100
> > +++ gcc/range-op-float.cc   2022-11-11 10:55:57.602617289 +0100
> > @@ -1911,7 +1911,125 @@ class foperator_minus : public range_ope
> >   } fop_minus;
> > -class foperator_mult : public range_operator_float
> > +class foperator_mult_div_base : public range_operator_float
> > +{
> > +protected:
> > +  // True if [lb, ub] is [+-0, +-0].
> > +  static bool zero_p (const REAL_VALUE_TYPE &lb,
> > +                 const REAL_VALUE_TYPE &ub)
> > +  {
> > +    return real_iszero (&lb) && real_iszero (&ub);
> > +  }
> > +
> > +  // True if +0 or -0 is in [lb, ub] range.
> > +  static bool contains_zero_p (const REAL_VALUE_TYPE &lb,
> > +                          const REAL_VALUE_TYPE &ub)
> > +  {
> > +    return (real_compare (LE_EXPR, &lb, &dconst0)
> > +       && real_compare (GE_EXPR, &ub, &dconst0));
> > +  }
> > +
> > +  // True if [lb, ub] is [-INF, -INF] or [+INF, +INF].
> > +  static bool singleton_inf_p (const REAL_VALUE_TYPE &lb,
> > +                          const REAL_VALUE_TYPE &ub)
> > +  {
> > +    return real_isinf (&lb) && real_isinf (&ub, real_isneg (&lb));
> > +  }
> > +
> > +  // Return -1 if binary op result must have sign bit set,
> > +  // 1 if binary op result must have sign bit clear,
> > +  // 0 otherwise.
> > +  // Sign bit of binary op result is exclusive or of the
> > +  // operand's sign bits.
> > +  static int signbit_known_p (const REAL_VALUE_TYPE &lh_lb,
> > +                         const REAL_VALUE_TYPE &lh_ub,
> > +                         const REAL_VALUE_TYPE &rh_lb,
> > +                         const REAL_VALUE_TYPE &rh_ub)
> > +  {
> > +    if (real_isneg (&lh_lb) == real_isneg (&lh_ub)
> > +   && real_isneg (&rh_lb) == real_isneg (&rh_ub))
> > +      {
> > +   if (real_isneg (&lh_lb) == real_isneg (&rh_ub))
> > +     return 1;
> > +   else
> > +     return -1;
> > +      }
> > +    return 0;
> > +  }
> > +
> > +  // Set [lb, ub] to [-0, -0], [-0, +0] or [+0, +0] depending on
> > +  // signbit_known.
> > +  static void zero_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
> > +                     int signbit_known)
> > +  {
> > +    ub = lb = dconst0;
> > +    if (signbit_known <= 0)
> > +      lb = real_value_negate (&dconst0);
> > +    if (signbit_known < 0)
> > +      ub = lb;
> > +  }
> > +
> > +  // Set [lb, ub] to [-INF, -INF], [-INF, +INF] or [+INF, +INF] depending 
> > on
> > +  // signbit_known.
> > +  static void inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
> > +                    int signbit_known)
> > +  {
> > +    if (signbit_known > 0)
> > +      ub = lb = dconstinf;
> > +    else if (signbit_known < 0)
> > +      ub = lb = dconstninf;
> > +    else
> > +      {
> > +   lb = dconstninf;
> > +   ub = dconstinf;
> > +      }
> > +  }
> > +
> > +  // Set [lb, ub] to [-INF, -0], [-INF, +INF] or [+0, +INF] depending on
> > +  // signbit_known.
> > +  static void zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE &ub,
> > +                            int signbit_known)
> > +  {
> > +    if (signbit_known > 0)
> > +      {
> > +   lb = dconst0;
> > +   ub = dconstinf;
> > +      }
> > +    else if (signbit_known < 0)
> > +      {
> > +   lb = dconstninf;
> > +   ub = real_value_negate (&dconst0);
> > +      }
> > +    else
> > +      {
> > +   lb = dconstninf;
> > +   ub = dconstinf;
> > +      }
> > +  }
> 
> The above functions look like they could be useful outside of the mult/div
> implementation.  Perhaps put them in file scope, instead limiting it to
> foperator_mult_div_base?

Well, I didn't want to export them to everything and most of the file
works on franges, not on REAL_VALUE_TYPE pairs.  But sure, if there
are other uses, it can be moved elsewhere.

> > +  static void zero_to_inf_range (REAL_VALUE_TYPE &lb, REAL_VALUE_TYPE
> &ub,
> > +                            int signbit_known)
> > +  {
> > +    if (signbit_known > 0)
> 
> The rest of frange uses bool for a sign.  Also, real_iszero, real_isinf,
> real_inf, etc all use bool sign.  Can you use a bool, or is there a reason
> for the int?

I need a tristate.  signbit is known and clear (this happens when
all the 4 bounds have the same sign), signbit is known and set
(this happens when one operand has signbit clear and the other signbit
set, or vice versa), or the state of the resulting signbit is unknown
(at least one operand has some values in the range with clear and others
with set signbit).

        Jakub

Reply via email to