https://gcc.gnu.org/bugzilla/show_bug.cgi?id=24021

--- Comment #21 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Aldy Hernandez from comment #20)
> (In reply to Andrew Macleod from comment #19)
> > We can use the original testcase as the litmus test for basic support if we
> > compile it with
> > 
> > -O2  -fno-tree-fre  -fno-tree-dominator-opts
> > 
> > The unroller will unroll the loop and the VRP2 pass will be presented with:
> > 
> >  <bb 2> [local count: 97603129]:
> >  i_1 = 1.1000000149011611438876201418679556809365749359130859375e-1;
> >  i_17 = i_1 + 1.00000001490116119384765625e-1;
> >  i_22 = i_17 + 1.00000001490116119384765625e-1;
> >  i_27 = i_22 + 1.00000001490116119384765625e-1;
> >  i_32 = i_27 + 1.00000001490116119384765625e-1;
> >  i_37 = i_32 + 1.00000001490116119384765625e-1;
> >  i_42 = i_37 + 1.00000001490116119384765625e-1;
> >  i_47 = i_42 + 1.00000001490116119384765625e-1;
> >  i_52 = i_47 + 1.00000001490116119384765625e-1;
> >  if (i_52 == 0.0)
> >    goto <bb 4>; [50.00%]
> >  else
> >    goto <bb 3>; [50.00%]
> > 
> >  <bb 3> [local count: 48801565]:
> > 
> >  <bb 4> [local count: 97603129]:
> >  # lastPoint_12 = PHI <i_52(2), 2.0e+0(3)>
> >  return lastPoint_12;
> > 
> > Which is we can track floating point ranges in VRP and simplification,
> > recognize that i_52 != 0.0 and VRP2 should be able to resolve this to 
> > 
> > return 2.0e+0;
> 
> We can definitely get this with the current work.  All that's missing is the
> snippet implementing the PLUS_EXPR operator.  A simple implementation (with
> likely the NAN bits wrong :)) follows:
> 
> diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
> index d1c7a3b571b..cba7166ad2b 100644
> --- a/gcc/range-op-float.cc
> +++ b/gcc/range-op-float.cc
> @@ -1055,6 +1055,54 @@ foperator_mult::fold_range (frange &r, tree type,
>    return true;
>  }
>  
> +class foperator_plus : public range_operator
> +{
> +  using range_operator::fold_range;
> +public:
> +  virtual bool fold_range (frange &r, tree type,
> +                        const frange &lh,
> +                        const frange &rh,
> +                        relation_kind rel = VREL_NONE) const override;
> +} fop_plus;
> +
> +bool
> +foperator_plus::fold_range (frange &r, tree type,
> +                         const frange &lh,
> +                         const frange &rh,
> +                         relation_kind) const
> +{
> +  if (empty_range_varying (r, type, lh, rh))
> +    return true;
> +
> +  if (lh.get_prop (FRANGE_PROP_NAN)
> +      || rh.get_prop (FRANGE_PROP_NAN))
> +    {
> +      r.set_varying (type);
> +      return true;
> +    }
> +
> +  enum tree_code code_lb, code_ub;
> +  tree lh_lb = lh.lower_bound (&code_lb);
> +  tree lh_ub = lh.upper_bound (&code_ub);
> +  tree rh_lb = rh.lower_bound ();
> +  tree rh_ub = rh.upper_bound ();
> +
> +  REAL_VALUE_TYPE res_lb, res_ub;
> +  real_arithmetic (&res_lb, PLUS_EXPR,
> +                TREE_REAL_CST_PTR (lh_lb),
> +                TREE_REAL_CST_PTR (rh_lb));
> +  real_arithmetic (&res_ub, PLUS_EXPR,
> +                TREE_REAL_CST_PTR (lh_ub),
> +                TREE_REAL_CST_PTR (rh_ub));
> +
> +  r.set (code_lb,
> +      build_real (type, res_lb),
> +      build_real (type, res_ub),
> +      code_ub);
> +  return true;
> +}

This doesn't take flag_rounding_math or not always exactly precise floating
point computations into account.
It is also missing real_convert after real_arithmetics that performs at least
some of the rounding (and perhaps the inexact return value from real_arithmetic
should be taken into account).
Without flag_rounding_math and on non-MODE_COMPOSITE_P the basic arithmetics
will be probably exact most of the time, except perhaps for denormals which are
sometimes flushed to zero.  But as soon as one jumps to even sqrt and other
math functions, one needs to allow some epsilon up for upper bound and down for
lower bound, similarly for the basic ops with inexact and flag_rounding_math.
For MODE_COMPOSITE_P, our emulation doesn't match what is done at runtime, so
we need to be more forgiving.

Reply via email to