Cache reals for 1/4, 1/6 and 1/9

Richard Biener richard.guenther@gmail.com
Tue Oct 6 08:26:00 GMT 2015


On Mon, Oct 5, 2015 at 4:47 PM, Richard Sandiford
<richard.sandiford@arm.com> wrote:
> Richard Biener <richard.guenther@gmail.com> writes:
>> On Thu, Oct 1, 2015 at 3:59 PM, Bernd Schmidt <bschmidt@redhat.com> wrote:
>>> On 10/01/2015 03:51 PM, Richard Sandiford wrote:
>>>>
>>>> We have a global 1/2 and a cached 1/3, but recalculate 1/4, 1/6 and 1/9
>>>> each time we need them.  That seems a bit arbitrary and makes the folding
>>>> code more noisy (especially once it's moved to match.pd).
>>>>
>>>> This patch caches the other three constants too.  Bootstrapped &
>>>> regression-tested on x86_64-linux-gnu.  OK to install?
>>>
>>>
>>> Looks reasonable enough.
>>
>> Given
>>
>> /* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
>>
>> const REAL_VALUE_TYPE *
>> dconst_third_ptr (void)
>> {
>>   static REAL_VALUE_TYPE value;
>>
>>   /* Initialize mathematical constants for constant folding builtins.
>>      These constants need to be given to at least 160 bits precision.  */
>>   if (value.cl == rvc_zero)
>>     {
>>       real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
>>     }
>>   return &value;
>> }
>>
>> I wonder if it makes sense to have
>>
>> template<int a, int b>
>> const REAL_VALUE_TYPE &
>> dconst (void)
>> {
>>   static REAL_VALUE_TYPE value;
>>   if (value.cl == rvc_zero)
>>     real_arithmetic (&value, RDIV_EXPR, real_digit (a), real_digit (b));
>>   return value;
>> }
>>
>> instead which allows us to use
>>
>>   dconst<1,2>()
>>
>> in place of dconst_half () and allows arbitrary extra cached constants to be
>> added (well, double-check that, but I think the function static should be
>> a .comdat).
>
> You suggested on IRC that we do the same for the integral constants,
> so e.g. dconst0 becomes dconst<0> ().  Here's the result.  Like I said,
> I think this may be a case of "be careful what you wish for".
>
> Bootstrapped & regression-tested on x86_64-linux-gnu.  Also tested by
> building one target per CPU directory and checking that there were no
> new warnings and no changes in testsuite output at -O2.  OK to install?

Ok.  Note that if people don't like the dconst<1,2> () syntax we could wrap
it in a macro

#define DCONST(a, args...) dconst<a, #args> ()

and use DCONST(1, 2) (well, if I got the variadic macro syntax right and if
that's a required feature in C++04, it's in C++11 at least).

I wonder if C++23 will finally get sth like Schemes define-syntax ;)

Thanks,
Richard.

> Thanks,
> Richard
>
>
> gcc/ada/
>         * gcc-interface/trans.c (convert_with_check): Use dconst template
>         instead of static variables.
>
> gcc/c-family/
>         * c-common.c (c_common_truthvalue_conversion): Use dconst template
>         instead of static variables.
>         * c-lex.c (interpret_float): Likewise.
>         * c-ubsan.c (ubsan_instrument_division): Likewise.
>
> gcc/java/
>         * decl.c (java_init_decl_processing): Use dconst template instead
>         of static variables.
>
> gcc/
>         * real.h (dconst0, dconst1, dconst2, dconstm1, dconsthalf): Delete.
>         (dconst_third, dconst_third_ptr): Delete.
>         (real_from_fraction): Declare.
>         (dconst): New function.
>         * real.c (real_from_fraction): New function.
>         (real_digit, dconst_third_ptr): Delete.
>         (exact_real_inverse, real_to_decimal_for_mode, decimal_integer_string)
>         (ten_to_mptwo, times_pten): Use dconst instead of real_digit.
>         (real_powi, real_floor, real_ceil, real_round): Use dconst
>         instead of static variables.
>         * emit-rtl.c (dconst0, dconst1, dconst2, dconstm1, dconsthalf): Delete.
>         (init_emit_once): Don't initialize them.
>         * builtins.c (fold_builtin_sqrt, fold_builtin_cbrt): Use dconst
>         instead of static variables.  Also use dconst<1, 6> and dconst<1, 9>
>         instead of deriving them from doncst_third.
>         (expand_builtin_cexpi, expand_builtin_signbit, fold_builtin_cabs)
>         (fold_builtin_pow, fold_builtin_powi, fold_builtin_signbit)
>         (fold_builtin_modf, fold_builtin_classify, fold_builtin_fpclassify)
>         (fold_builtin_1, fold_builtin_2): Use dconst instead of static
>         variables.
>         * doc/match-and-simplify.texi: Likewise (in examples).
>         * config/aarch64/aarch64.c (aarch64_float_const_zero_rtx_p): Likewise.
>         * config/c6x/c6x.md (divsf3, divdf3): Likewise.
>         * config/fr30/fr30.c (fr30_const_double_is_zero): Likewise.
>         * config/i386/i386.c (standard_80387_constant_p): Likewise.
>         (ix86_expand_convert_uns_didf_sse, ix86_expand_convert_uns_sidf_sse)
>         (ix86_expand_convert_sign_didf_sse, ix86_expand_convert_uns_sisf_sse)
>         (ix86_expand_vector_convert_uns_vsivsf): Likewise.
>         (ix86_expand_adjust_ufix_to_sfix_si, ix86_emit_i387_round): Likewise.
>         (ix86_emit_swsqrtsf, ix86_gen_TWO52, ix86_expand_lround): Likewise.
>         (ix86_expand_floorceildf_32, ix86_expand_floorceil): Likewise.
>         (ix86_expand_rounddf_32, ix86_expand_truncdf_32): Likewise.
>         (ix86_expand_round, ix86_expand_round_sse4): Likewise.
>         * config/i386/i386.md (fixuns_trunc<mode>si2): Likewise.
>         * config/i386/sse.md (vec_unpacku_float_hi_v4si): Likewise.
>         (vec_unpacku_float_lo_v4si, vec_unpacku_float_hi_v8si): Likewise.
>         (vec_unpacku_float_hi_v16si, vec_unpacku_float_lo_v8si): Likewise.
>         (vec_unpacku_float_lo_v16si, round<mode>2): Likewise.
>         * config/m68k/m68k.c (floating_exact_log2): Likewise.
>         * config/rs6000/rs6000.c (rs6000_emit_swdiv): Likewise.
>         (rs6000_scale_v2df): Likewise.
>         * config/rs6000/rs6000.md (*cmptf_internal2): Likewise.
>         * config/sh/sh.c (fp_zero_operand, fp_one_operand): Likewise.
>         * config/xtensa/predicates.md (const_float_1_operand): Likewise.
>         * cprop.c (implicit_set_cond_p): Likewise.
>         * dfp.c (decimal_to_decnumber): Likewise.
>         * expmed.c (expand_mult): Likewise.
>         * fold-const.c (const_binop, distribute_real_division): Likewise.
>         (fold_binary_loc): Likewise.
>         * match.pd: Likewise throughout.
>         * simplify-rtx.c (simplify_binary_operation_1): Likewise.
>         (simplify_const_binary_operation): Likewise.
>         * tree-call-cdce.c (check_pow): Likewise.
>         (gen_conditions_for_pow_cst_base): Likewise.
>         * tree-chrec.c (chrec_fold_plus_poly_poly): Likewise.
>         (chrec_fold_multiply_poly_poly, chrec_fold_plus_1): Likewise.
>         * tree-complex.c (some_nonzerop, get_component_ssa_name): Likewise.
>         (expand_complex_multiplication): Likewise.
>         * tree-inline.c (estimate_num_insns): Likewise.
>         * tree-scalar-evolution.c (add_to_evolution_1): Likewise.
>         (add_to_evolution): Likewise.
>         * tree-ssa-dom.c (record_equality): Likewise.
>         * tree-ssa-math-opts.c (powi_as_mults): Likewise.
>         (representable_as_half_series_p, expand_pow_as_sqrts): Likewise.
>         (pass_cse_sincos::execute): Likewise.
>         (pass_optimize_widening_mul::execute): Likewise.
>         (gimple_expand_builtin_pow): Likewise.  Use dconst instead of
>         local variables for 3 and 1/4.
>         * tree-ssa-uncprop.c (associate_equivalences_with_edges): Use dconst
>         instead of static variables.
>         * tree-vect-loop.c (get_initial_def_for_reduction): Likewise.
>         * tree-vect-patterns.c (vect_recog_pow_pattern): Likewise.
>         * tree-vect-slp.c (vect_get_constant_vectors): Likewise.
>         * tree.c (build_one_cst, build_minus_one_cst, build_zero_cst)
>         (real_zerop, real_onep, real_minus_onep): Likewise.
>         * ubsan.c (ubsan_instrument_float_cast): Likewise.
>
> diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
> index f1e2dcb..f00dfee 100644
> --- a/gcc/ada/gcc-interface/trans.c
> +++ b/gcc/ada/gcc-interface/trans.c
> @@ -9048,7 +9048,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp,
>        /* Compute the exact value calc_type'Pred (0.5) at compile time.  */
>        fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type));
>        real_2expN (&half_minus_pred_half, -(fmt->p) - 1, TYPE_MODE (calc_type));
> -      real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf,
> +      real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
>                        &half_minus_pred_half);
>        gnu_pred_half = build_real (calc_type, pred_half);
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index 89bea60..85ba6dd 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -2659,7 +2659,7 @@ expand_builtin_cexpi (tree exp, rtx target)
>         }
>
>        narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
> -                         build_real (type, dconst0), arg);
> +                         build_real (type, dconst<0> ()), arg);
>
>        /* Make sure not to fold the cexp call again.  */
>        call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
> @@ -4983,7 +4983,7 @@ expand_builtin_signbit (tree exp, rtx target)
>      gcc_assert (!fmt->has_signed_zero || !HONOR_SIGNED_ZEROS (fmode));
>
>      arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
> -                      build_real (TREE_TYPE (arg), dconst0));
> +                      build_real (TREE_TYPE (arg), dconst<0> ()));
>      return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
>    }
>
> @@ -7642,7 +7642,7 @@ fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
>  static tree
>  build_complex_cproj (tree type, bool neg)
>  {
> -  REAL_VALUE_TYPE rinf, rzero = dconst0;
> +  REAL_VALUE_TYPE rinf, rzero = dconst<0> ();
>
>    real_inf (&rinf);
>    rzero.sign = neg;
> @@ -7720,7 +7720,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
>      return NULL_TREE;
>
>    /* Calculate the result when the argument is a constant.  */
> -  if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
> +  if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst<0> (), NULL, true)))
>      return res;
>
>    /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
> @@ -7730,7 +7730,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
>        tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
>        arg = fold_build2_loc (loc, MULT_EXPR, type,
>                          CALL_EXPR_ARG (arg, 0),
> -                        build_real (type, dconsthalf));
> +                        build_real (type, dconst<1, 2> ()));
>        return build_call_expr_loc (loc, expfn, 1, arg);
>      }
>
> @@ -7742,20 +7742,10 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
>        if (powfn)
>         {
>           tree arg0 = CALL_EXPR_ARG (arg, 0);
> -         tree tree_root;
> -         /* The inner root was either sqrt or cbrt.  */
> -         /* This was a conditional expression but it triggered a bug
> -            in Sun C 5.5.  */
> -         REAL_VALUE_TYPE dconstroot;
> -         if (BUILTIN_SQRT_P (fcode))
> -           dconstroot = dconsthalf;
> -         else
> -           dconstroot = dconst_third ();
> -
> -         /* Adjust for the outer root.  */
> -         SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
> -         tree_root = build_real_truncate (type, dconstroot);
> -         return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
> +         tree arg1 = (BUILTIN_SQRT_P (fcode)
> +                      ? build_real (type, dconst<1, 4> ())
> +                      : build_real_truncate (type, dconst<1, 6> ()));
> +         return build_call_expr_loc (loc, powfn, 2, arg0, arg1);
>         }
>      }
>
> @@ -7772,7 +7762,7 @@ fold_builtin_sqrt (location_t loc, tree arg, tree type)
>        if (!tree_expr_nonnegative_p (arg0))
>         arg0 = build1 (ABS_EXPR, type, arg0);
>        narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
> -                          build_real (type, dconsthalf));
> +                          build_real (type, dconst<1, 2> ()));
>        return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
>      }
>
> @@ -7803,7 +7793,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
>           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
>           arg = fold_build2_loc (loc, MULT_EXPR, type,
>                                  CALL_EXPR_ARG (arg, 0),
> -                                build_real_truncate (type, dconst_third ()));
> +                                build_real_truncate (type, dconst<1, 3> ()));
>           return build_call_expr_loc (loc, expfn, 1, arg);
>         }
>
> @@ -7815,11 +7805,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
>           if (powfn)
>             {
>               tree arg0 = CALL_EXPR_ARG (arg, 0);
> -             tree tree_root;
> -             REAL_VALUE_TYPE dconstroot = dconst_third ();
> -
> -             SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
> -             tree_root = build_real_truncate (type, dconstroot);
> +             tree tree_root = build_real_truncate (type, dconst<1, 6> ());
>               return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
>             }
>         }
> @@ -7834,12 +7820,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
>
>               if (powfn)
>                 {
> -                 tree tree_root;
> -                 REAL_VALUE_TYPE dconstroot;
> -
> -                 real_arithmetic (&dconstroot, MULT_EXPR,
> -                                   dconst_third_ptr (), dconst_third_ptr ());
> -                 tree_root = build_real_truncate (type, dconstroot);
> +                 tree tree_root = build_real_truncate (type, dconst<1, 9> ());
>                   return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
>                 }
>             }
> @@ -7855,7 +7836,7 @@ fold_builtin_cbrt (location_t loc, tree arg, tree type)
>           if (tree_expr_nonnegative_p (arg00))
>             {
>               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
> -             tree c = build_real_truncate (type, dconst_third ());
> +             tree c = build_real_truncate (type, dconst<1, 3> ());
>               tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01, c);
>               return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
>             }
> @@ -8407,7 +8388,8 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
>
>    /* Optimize pow(1.0,y) = 1.0.  */
>    if (real_onep (arg0))
> -    return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
> +    return omit_one_operand_loc (loc, type,
> +                                build_real (type, dconst<1> ()), arg1);
>
>    if (TREE_CODE (arg1) == REAL_CST
>        && !TREE_OVERFLOW (arg1))
> @@ -8419,22 +8401,22 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
>        c = TREE_REAL_CST (arg1);
>
>        /* Optimize pow(x,0.0) = 1.0.  */
> -      if (real_equal (&c, &dconst0))
> -       return omit_one_operand_loc (loc, type, build_real (type, dconst1),
> -                                arg0);
> +      if (real_equal (&c, &dconst<0> ()))
> +       return omit_one_operand_loc (loc, type,
> +                                    build_real (type, dconst<1> ()), arg0);
>
>        /* Optimize pow(x,1.0) = x.  */
> -      if (real_equal (&c, &dconst1))
> +      if (real_equal (&c, &dconst<1> ()))
>         return arg0;
>
>        /* Optimize pow(x,-1.0) = 1.0/x.  */
> -      if (real_equal (&c, &dconstm1))
> +      if (real_equal (&c, &dconst<-1> ()))
>         return fold_build2_loc (loc, RDIV_EXPR, type,
> -                           build_real (type, dconst1), arg0);
> +                           build_real (type, dconst<1> ()), arg0);
>
>        /* Optimize pow(x,0.5) = sqrt(x).  */
>        if (flag_unsafe_math_optimizations
> -         && real_equal (&c, &dconsthalf))
> +         && real_equal (&c, &dconst<1, 2> ()))
>         {
>           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
>
> @@ -8446,7 +8428,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
>        if (flag_unsafe_math_optimizations)
>         {
>           const REAL_VALUE_TYPE dconstroot
> -           = real_value_truncate (TYPE_MODE (type), dconst_third ());
> +           = real_value_truncate (TYPE_MODE (type), dconst<1, 3> ());
>
>           if (real_equal (&c, &dconstroot))
>             {
> @@ -8467,7 +8449,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
>               && !TREE_OVERFLOW (arg0)
>               && (n > 0
>                   || (!flag_trapping_math && !flag_errno_math)
> -                 || !real_equal (&TREE_REAL_CST (arg0), &dconst0)))
> +                 || !real_equal (&TREE_REAL_CST (arg0), &dconst<0> ())))
>             {
>               REAL_VALUE_TYPE x;
>               bool inexact;
> @@ -8506,7 +8488,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
>         {
>           tree narg0 = CALL_EXPR_ARG (arg0, 0);
>           tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
> -                                   build_real (type, dconsthalf));
> +                                   build_real (type, dconst<1, 2> ()));
>           return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
>         }
>
> @@ -8516,7 +8498,7 @@ fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
>           tree arg = CALL_EXPR_ARG (arg0, 0);
>           if (tree_expr_nonnegative_p (arg))
>             {
> -             tree c = build_real_truncate (type, dconst_third ());
> +             tree c = build_real_truncate (type, dconst<1, 3> ());
>               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1, c);
>               return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
>             }
> @@ -8552,7 +8534,8 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
>
>    /* Optimize pow(1.0,y) = 1.0.  */
>    if (real_onep (arg0))
> -    return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
> +    return omit_one_operand_loc (loc, type,
> +                                build_real (type, dconst<1> ()), arg1);
>
>    if (tree_fits_shwi_p (arg1))
>      {
> @@ -8570,8 +8553,8 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
>
>        /* Optimize pow(x,0) = 1.0.  */
>        if (c == 0)
> -       return omit_one_operand_loc (loc, type, build_real (type, dconst1),
> -                                arg0);
> +       return omit_one_operand_loc (loc, type,
> +                                    build_real (type, dconst<1> ()), arg0);
>
>        /* Optimize pow(x,1) = x.  */
>        if (c == 1)
> @@ -8580,7 +8563,7 @@ fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
>        /* Optimize pow(x,-1) = 1.0/x.  */
>        if (c == -1)
>         return fold_build2_loc (loc, RDIV_EXPR, type,
> -                          build_real (type, dconst1), arg0);
> +                               build_real (type, dconst<1> ()), arg0);
>      }
>
>    return NULL_TREE;
> @@ -8922,7 +8905,8 @@ fold_builtin_signbit (location_t loc, tree arg, tree type)
>    if (!HONOR_SIGNED_ZEROS (arg))
>      return fold_convert (type,
>                          fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
> -                       build_real (TREE_TYPE (arg), dconst0)));
> +                                         build_real (TREE_TYPE (arg),
> +                                                     dconst<0> ())));
>
>    return NULL_TREE;
>  }
> @@ -9398,7 +9382,7 @@ fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
>         break;
>        case rvc_inf:
>         /* For +-Inf, return (*arg1 = arg0, +-0).  */
> -       frac = dconst0;
> +       frac = dconst<0> ();
>         frac.sign = value->sign;
>         trunc = *value;
>         break;
> @@ -9536,7 +9520,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
>         {
>           r = TREE_REAL_CST (arg);
>           if (real_isinf (&r))
> -           return real_compare (GT_EXPR, &r, &dconst0)
> +           return real_compare (GT_EXPR, &r, &dconst<0> ())
>                    ? integer_one_node : integer_minus_one_node;
>           else
>             return integer_zero_node;
> @@ -9651,7 +9635,7 @@ fold_builtin_fpclassify (location_t loc, tree *args, int nargs)
>              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
>
>    tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
> -                    build_real (type, dconst0));
> +                    build_real (type, dconst<0> ()));
>    res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
>                      tmp, fp_zero, fp_subnormal);
>
> @@ -9967,13 +9951,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
>      CASE_FLT_FN (BUILT_IN_ASIN):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_asin,
> -                            &dconstm1, &dconst1, true);
> +                            &dconst<-1> (), &dconst<1> (), true);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_ACOS):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_acos,
> -                            &dconstm1, &dconst1, true);
> +                            &dconst<-1> (), &dconst<1> (), true);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_ATAN):
> @@ -9989,13 +9973,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
>      CASE_FLT_FN (BUILT_IN_ACOSH):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
> -                            &dconst1, NULL, true);
> +                            &dconst<1> (), NULL, true);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_ATANH):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
> -                            &dconstm1, &dconst1, false);
> +                            &dconst<-1> (), &dconst<1> (), false);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_SIN):
> @@ -10062,23 +10046,25 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
>
>      CASE_FLT_FN (BUILT_IN_LOG):
>        if (validate_arg (arg0, REAL_TYPE))
> -        return do_mpfr_arg1 (arg0, type, mpfr_log, &dconst0, NULL, false);
> +       return do_mpfr_arg1 (arg0, type, mpfr_log, &dconst<0> (), NULL, false);
>        break;
>
>      CASE_FLT_FN (BUILT_IN_LOG2):
>        if (validate_arg (arg0, REAL_TYPE))
> -        return do_mpfr_arg1 (arg0, type, mpfr_log2, &dconst0, NULL, false);
> +       return do_mpfr_arg1 (arg0, type, mpfr_log2,
> +                            &dconst<0> (), NULL, false);
>        break;
>
>      CASE_FLT_FN (BUILT_IN_LOG10):
>        if (validate_arg (arg0, REAL_TYPE))
> -        return do_mpfr_arg1 (arg0, type, mpfr_log10, &dconst0, NULL, false);
> +       return do_mpfr_arg1 (arg0, type, mpfr_log10,
> +                            &dconst<0> (), NULL, false);
>        break;
>
>      CASE_FLT_FN (BUILT_IN_LOG1P):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
> -                            &dconstm1, NULL, false);
> +                            &dconst<-1> (), NULL, false);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_J0):
> @@ -10096,13 +10082,13 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
>      CASE_FLT_FN (BUILT_IN_Y0):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_y0,
> -                            &dconst0, NULL, false);
> +                            &dconst<0> (), NULL, false);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_Y1):
>        if (validate_arg (arg0, REAL_TYPE))
>         return do_mpfr_arg1 (arg0, type, mpfr_y1,
> -                            &dconst0, NULL, false);
> +                            &dconst<0> (), NULL, false);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_NAN):
> @@ -10247,7 +10233,7 @@ fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1)
>        if (validate_arg (arg0, INTEGER_TYPE)
>           && validate_arg (arg1, REAL_TYPE))
>         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
> -                                &dconst0, false);
> +                                &dconst<0> (), false);
>      break;
>
>      CASE_FLT_FN (BUILT_IN_DREM):
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index 4b64a44..9d1126b 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -4983,7 +4983,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
>                                   : truthvalue_true_node;
>
>      case REAL_CST:
> -      return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst0)
> +      return real_compare (NE_EXPR, &TREE_REAL_CST (expr), &dconst<0> ())
>              ? truthvalue_true_node
>              : truthvalue_false_node;
>
> diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
> index c69f4a6..30db6a9 100644
> --- a/gcc/c-family/c-lex.c
> +++ b/gcc/c-family/c-lex.c
> @@ -914,9 +914,9 @@ interpret_float (const cpp_token *token, unsigned int flags,
>         }
>      }
>    /* We also give a warning if the value underflows.  */
> -  else if (real_equal (&real, &dconst0)
> +  else if (real_equal (&real, &dconst<0> ())
>            || (const_type != type
> -              && real_equal (&real_trunc, &dconst0)))
> +              && real_equal (&real_trunc, &dconst<0> ())))
>      {
>        REAL_VALUE_TYPE realvoidmode;
>        int oflow = real_from_string (&realvoidmode, copy);
> @@ -924,7 +924,7 @@ interpret_float (const cpp_token *token, unsigned int flags,
>                               : (oflow < 0 ? OT_UNDERFLOW : OT_OVERFLOW));
>        if (!(flags & CPP_N_USERDEF))
>         {
> -         if (oflow < 0 || !real_equal (&realvoidmode, &dconst0))
> +         if (oflow < 0 || !real_equal (&realvoidmode, &dconst<0> ()))
>             warning (OPT_Woverflow, "floating constant truncated to zero");
>         }
>      }
> diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
> index 672762c..68b76b8 100644
> --- a/gcc/c-family/c-ubsan.c
> +++ b/gcc/c-family/c-ubsan.c
> @@ -65,7 +65,7 @@ ubsan_instrument_division (location_t loc, tree op0, tree op1)
>    else if (TREE_CODE (type) == REAL_TYPE
>            && (flag_sanitize & SANITIZE_FLOAT_DIVIDE))
>      t = fold_build2 (EQ_EXPR, boolean_type_node,
> -                    op1, build_real (type, dconst0));
> +                    op1, build_real (type, dconst<0> ()));
>    else
>      return NULL_TREE;
>
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index c9fe368..7fe1831 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -3768,7 +3768,7 @@ aarch64_float_const_zero_rtx_p (rtx x)
>
>    if (REAL_VALUE_MINUS_ZERO (*CONST_DOUBLE_REAL_VALUE (x)))
>      return !HONOR_SIGNED_ZEROS (GET_MODE (x));
> -  return real_equal (CONST_DOUBLE_REAL_VALUE (x), &dconst0);
> +  return real_equal (CONST_DOUBLE_REAL_VALUE (x), &dconst<0> ());
>  }
>
>  /* Return the fixed registers used for condition codes.  */
> diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md
> index fa89587..7824cd7 100644
> --- a/gcc/config/c6x/c6x.md
> +++ b/gcc/config/c6x/c6x.md
> @@ -2809,7 +2809,8 @@
>    "TARGET_FP && flag_reciprocal_math"
>  {
>    operands[3] = force_reg (SFmode,
> -                          const_double_from_real_value (dconst2, SFmode));
> +                          const_double_from_real_value (dconst<2> (),
> +                                                        SFmode));
>    operands[4] = gen_reg_rtx (SFmode);
>    operands[5] = gen_reg_rtx (SFmode);
>    operands[6] = gen_reg_rtx (SFmode);
> @@ -2834,7 +2835,8 @@
>    "TARGET_FP && flag_reciprocal_math"
>  {
>    operands[3] = force_reg (DFmode,
> -                          const_double_from_real_value (dconst2, DFmode));
> +                          const_double_from_real_value (dconst<2> (),
> +                                                        DFmode));
>    operands[4] = gen_reg_rtx (DFmode);
>    operands[5] = gen_reg_rtx (DFmode);
>    operands[6] = gen_reg_rtx (DFmode);
> diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c
> index 6afd5d4..20ab6e4 100644
> --- a/gcc/config/fr30/fr30.c
> +++ b/gcc/config/fr30/fr30.c
> @@ -889,7 +889,7 @@ fr30_const_double_is_zero (rtx operand)
>    if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
>      return 0;
>
> -  return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst0);
> +  return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst<0> ());
>  }
>
>  /*}}}*/
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index d59b59b..5591f78 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -10511,7 +10511,7 @@ standard_80387_constant_p (rtx x)
>       fldz;fchs or fld1;fchs sequence.  */
>    if (real_isnegzero (r))
>      return 8;
> -  if (real_identical (r, &dconstm1))
> +  if (real_identical (r, &dconst<-1> ()))
>      return 9;
>
>    return 0;
> @@ -20296,8 +20296,8 @@ ix86_expand_convert_uns_didf_sse (rtx target, rtx input)
>
>    /* Subtract off those 0x1.0p52 and 0x1.0p84 biases, to produce values
>       in [0,2**32-1] and [0]+[2**32,2**64-1] respectively.  */
> -  real_ldexp (&bias_lo_rvt, &dconst1, 52);
> -  real_ldexp (&bias_hi_rvt, &dconst1, 84);
> +  real_ldexp (&bias_lo_rvt, &dconst<1> (), 52);
> +  real_ldexp (&bias_hi_rvt, &dconst<1> (), 84);
>    biases = const_double_from_real_value (bias_lo_rvt, DFmode);
>    x = const_double_from_real_value (bias_hi_rvt, DFmode);
>    biases = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, biases, x));
> @@ -20339,7 +20339,7 @@ ix86_expand_convert_uns_sidf_sse (rtx target, rtx input)
>    fp = gen_reg_rtx (DFmode);
>    emit_insn (gen_floatsidf2 (fp, x));
>
> -  real_ldexp (&TWO31r, &dconst1, 31);
> +  real_ldexp (&TWO31r, &dconst<1> (), 31);
>    x = const_double_from_real_value (TWO31r, DFmode);
>
>    x = expand_simple_binop (DFmode, PLUS, fp, x, target, 0, OPTAB_DIRECT);
> @@ -20361,7 +20361,7 @@ ix86_expand_convert_sign_didf_sse (rtx target, rtx input)
>
>    emit_insn (gen_floatsidf2 (fp_hi, gen_highpart (SImode, input)));
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>    fp_hi = expand_simple_binop (DFmode, MULT, fp_hi, x, fp_hi, 0, OPTAB_DIRECT);
>
> @@ -20381,7 +20381,7 @@ ix86_expand_convert_uns_sisf_sse (rtx target, rtx input)
>    REAL_VALUE_TYPE ONE16r;
>    rtx fp_hi, fp_lo, int_hi, int_lo, x;
>
> -  real_ldexp (&ONE16r, &dconst1, 16);
> +  real_ldexp (&ONE16r, &dconst<1> (), 16);
>    x = const_double_from_real_value (ONE16r, SFmode);
>    int_lo = expand_simple_binop (SImode, AND, input, GEN_INT(0xffff),
>                                       NULL, 0, OPTAB_DIRECT);
> @@ -20425,7 +20425,7 @@ ix86_expand_vector_convert_uns_vsivsf (rtx target, rtx val)
>    emit_insn (cvt (tmp[3], tmp[1]));
>    tmp[4] = gen_reg_rtx (fltmode);
>    emit_insn (cvt (tmp[4], tmp[2]));
> -  real_ldexp (&TWO16r, &dconst1, 16);
> +  real_ldexp (&TWO16r, &dconst<1> (), 16);
>    tmp[5] = const_double_from_real_value (TWO16r, SFmode);
>    tmp[5] = force_reg (fltmode, ix86_build_const_vector (fltmode, 1, tmp[5]));
>    tmp[6] = expand_simple_binop (fltmode, MULT, tmp[4], tmp[5], NULL_RTX, 1,
> @@ -20454,7 +20454,7 @@ ix86_expand_adjust_ufix_to_sfix_si (rtx val, rtx *xorp)
>
>    for (i = 0; i < 3; i++)
>      tmp[i] = gen_reg_rtx (mode);
> -  real_ldexp (&TWO31r, &dconst1, 31);
> +  real_ldexp (&TWO31r, &dconst<1> (), 31);
>    two31r = const_double_from_real_value (TWO31r, scalarmode);
>    two31r = ix86_build_const_vector (mode, 1, two31r);
>    two31r = force_reg (mode, two31r);
> @@ -47089,7 +47089,7 @@ void ix86_emit_i387_round (rtx op0, rtx op1)
>    e2 = gen_reg_rtx (inmode);
>    res = gen_reg_rtx (outmode);
>
> -  half = const_double_from_real_value (dconsthalf, inmode);
> +  half = const_double_from_real_value (dconst<1, 2> (), inmode);
>
>    /* round(a) = sgn(a) * floor(fabs(a) + 0.5) */
>
> @@ -47223,7 +47223,7 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, machine_mode mode,
>    real_from_integer (&r, VOIDmode, -3, SIGNED);
>    mthree = const_double_from_real_value (r, SFmode);
>
> -  real_arithmetic (&r, NEGATE_EXPR, &dconsthalf, NULL);
> +  real_arithmetic (&r, NEGATE_EXPR, &dconst<1, 2> (), NULL);
>    mhalf = const_double_from_real_value (r, SFmode);
>    unspec = UNSPEC_RSQRT;
>
> @@ -47508,7 +47508,7 @@ ix86_gen_TWO52 (machine_mode mode)
>    REAL_VALUE_TYPE TWO52r;
>    rtx TWO52;
>
> -  real_ldexp (&TWO52r, &dconst1, mode == DFmode ? 52 : 23);
> +  real_ldexp (&TWO52r, &dconst<1> (), mode == DFmode ? 52 : 23);
>    TWO52 = const_double_from_real_value (TWO52r, mode);
>    TWO52 = force_reg (mode, TWO52);
>
> @@ -47532,7 +47532,8 @@ ix86_expand_lround (rtx op0, rtx op1)
>    /* load nextafter (0.5, 0.0) */
>    fmt = REAL_MODE_FORMAT (mode);
>    real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
> -  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
> +  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
> +                  &half_minus_pred_half);
>
>    /* adj = copysign (0.5, op1) */
>    adj = force_reg (mode, const_double_from_real_value (pred_half, mode));
> @@ -47664,7 +47665,8 @@ ix86_expand_floorceildf_32 (rtx operand0, rtx operand1, bool do_floor)
>    /* generate 1.0 or -1.0 */
>    one = force_reg (mode,
>                    const_double_from_real_value (do_floor
> -                                                ? dconst1 : dconstm1, mode));
> +                                                ? dconst<1> ()
> +                                                : dconst<-1> (), mode));
>
>    /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
>    tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
> @@ -47723,7 +47725,7 @@ ix86_expand_floorceil (rtx operand0, rtx operand1, bool do_floor)
>    expand_float (xa, xi, 0);
>
>    /* generate 1.0 */
> -  one = force_reg (mode, const_double_from_real_value (dconst1, mode));
> +  one = force_reg (mode, const_double_from_real_value (dconst<1> (), mode));
>
>    /* Compensate: xa = xa - (xa > operand1 ? 1 : 0) */
>    tmp = ix86_expand_sse_compare_mask (UNGT, xa, res, !do_floor);
> @@ -47788,7 +47790,8 @@ ix86_expand_rounddf_32 (rtx operand0, rtx operand1)
>    dxa = expand_simple_binop (mode, MINUS, xa2, xa, NULL_RTX, 0, OPTAB_DIRECT);
>
>    /* generate 0.5, 1.0 and -0.5 */
> -  half = force_reg (mode, const_double_from_real_value (dconsthalf, mode));
> +  half = force_reg (mode, const_double_from_real_value (dconst<1, 2> (),
> +                                                       mode));
>    one = expand_simple_binop (mode, PLUS, half, half, NULL_RTX, 0, OPTAB_DIRECT);
>    mhalf = expand_simple_binop (mode, MINUS, half, one, NULL_RTX,
>                                0, OPTAB_DIRECT);
> @@ -47898,7 +47901,7 @@ ix86_expand_truncdf_32 (rtx operand0, rtx operand1)
>    emit_move_insn (res, tmp);
>
>    /* generate 1.0 */
> -  one = force_reg (mode, const_double_from_real_value (dconst1, mode));
> +  one = force_reg (mode, const_double_from_real_value (dconst<1> (), mode));
>
>    /* Compensate: res = xa2 - (res > xa ? 1 : 0)  */
>    mask = ix86_expand_sse_compare_mask (UNGT, res, xa, false);
> @@ -47946,7 +47949,8 @@ ix86_expand_round (rtx operand0, rtx operand1)
>    /* load nextafter (0.5, 0.0) */
>    fmt = REAL_MODE_FORMAT (mode);
>    real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
> -  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
> +  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
> +                  &half_minus_pred_half);
>
>    /* xa = xa + 0.5 */
>    half = force_reg (mode, const_double_from_real_value (pred_half, mode));
> @@ -47997,7 +48001,8 @@ ix86_expand_round_sse4 (rtx op0, rtx op1)
>    /* load nextafter (0.5, 0.0) */
>    fmt = REAL_MODE_FORMAT (mode);
>    real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
> -  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
> +  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
> +                  &half_minus_pred_half);
>    half = const_double_from_real_value (pred_half, mode);
>
>    /* e1 = copysign (0.5, op1) */
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 5fcebb5..140bc0f 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -4643,7 +4643,7 @@
>    if (optimize_insn_for_size_p ())
>      FAIL;
>
> -  real_ldexp (&TWO31r, &dconst1, 31);
> +  real_ldexp (&TWO31r, &dconst<1> (), 31);
>    two31 = const_double_from_real_value (TWO31r, mode);
>    two31 = ix86_build_const_vector (vecmode, true, two31);
>    operands[2] = force_reg (vecmode, two31);
> diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
> index 9b7a338..a016b26 100644
> --- a/gcc/config/i386/sse.md
> +++ b/gcc/config/i386/sse.md
> @@ -5432,7 +5432,7 @@
>    rtx x;
>    int i;
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>
>    operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
> @@ -5463,7 +5463,7 @@
>    rtx x;
>    int i;
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>
>    operands[3] = force_reg (V2DFmode, CONST0_RTX (V2DFmode));
> @@ -5483,7 +5483,7 @@
>    rtx x, tmp[6];
>    int i;
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>
>    tmp[0] = force_reg (V4DFmode, CONST0_RTX (V4DFmode));
> @@ -5508,7 +5508,7 @@
>    REAL_VALUE_TYPE TWO32r;
>    rtx k, x, tmp[4];
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>
>    tmp[0] = force_reg (V8DFmode, CONST0_RTX (V8DFmode));
> @@ -5534,7 +5534,7 @@
>    rtx x, tmp[5];
>    int i;
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>
>    tmp[0] = force_reg (V4DFmode, CONST0_RTX (V4DFmode));
> @@ -5557,7 +5557,7 @@
>    REAL_VALUE_TYPE TWO32r;
>    rtx k, x, tmp[3];
>
> -  real_ldexp (&TWO32r, &dconst1, 32);
> +  real_ldexp (&TWO32r, &dconst<1> (), 32);
>    x = const_double_from_real_value (TWO32r, DFmode);
>
>    tmp[0] = force_reg (V8DFmode, CONST0_RTX (V8DFmode));
> @@ -14881,7 +14881,8 @@
>    /* load nextafter (0.5, 0.0) */
>    fmt = REAL_MODE_FORMAT (scalar_mode);
>    real_2expN (&half_minus_pred_half, -(fmt->p) - 1, scalar_mode);
> -  real_arithmetic (&pred_half, MINUS_EXPR, &dconsthalf, &half_minus_pred_half);
> +  real_arithmetic (&pred_half, MINUS_EXPR, &dconst<1, 2> (),
> +                  &half_minus_pred_half);
>    half = const_double_from_real_value (pred_half, scalar_mode);
>
>    vec_half = ix86_build_const_vector (<MODE>mode, true, half);
> diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
> index bfc19f3..e7226ac 100644
> --- a/gcc/config/m68k/m68k.c
> +++ b/gcc/config/m68k/m68k.c
> @@ -4365,7 +4365,7 @@ floating_exact_log2 (rtx x)
>
>    r = CONST_DOUBLE_REAL_VALUE (x);
>
> -  if (real_less (r, &dconst1))
> +  if (real_less (r, &dconst<1> ()))
>      return 0;
>
>    exp = real_exponent (r);
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index c00d730..39a9a75 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -31944,7 +31944,7 @@ rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
>
>    gcc_assert (code != CODE_FOR_nothing);
>
> -  one = rs6000_load_constant_and_splat (mode, dconst1);
> +  one = rs6000_load_constant_and_splat (mode, dconst<1> ());
>
>    /* x0 = 1./d estimate */
>    x0 = gen_reg_rtx (mode);
> @@ -32684,7 +32684,7 @@ rs6000_scale_v2df (rtx tgt, rtx src, int scale)
>    rtvec v = rtvec_alloc (2);
>    rtx elt;
>    rtx scale_vec = gen_reg_rtx (V2DFmode);
> -  (void)real_powi (&r_pow, DFmode, &dconst2, hwi_scale);
> +  (void)real_powi (&r_pow, DFmode, &dconst<2> (), hwi_scale);
>    elt = const_double_from_real_value (r_pow, DFmode);
>    RTVEC_ELT (v, 0) = elt;
>    RTVEC_ELT (v, 1) = elt;
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index cf40f10..ae4f492 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -10578,7 +10578,7 @@
>    operands[14] = force_const_mem (DFmode,
>                                   const_double_from_real_value (rv, DFmode));
>    operands[15] = force_const_mem (DFmode,
> -                                 const_double_from_real_value (dconst0,
> +                                 const_double_from_real_value (dconst<0> (),
>                                                                 DFmode));
>    if (TARGET_TOC)
>      {
> diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
> index 92e9f9f..f7543d1 100644
> --- a/gcc/config/sh/sh.c
> +++ b/gcc/config/sh/sh.c
> @@ -10005,8 +10005,7 @@ fp_zero_operand (rtx op)
>    if (GET_MODE (op) != SFmode)
>      return false;
>
> -  r = CONST_DOUBLE_REAL_VALUE (op);
> -  return real_equal (r, &dconst0) && ! REAL_VALUE_MINUS_ZERO (*r);
> +  return real_equal (r, &dconst<0> ()) && ! REAL_VALUE_MINUS_ZERO (*r);
>  }
>
>  /* Returns true if OP is a floating point value with value 1.0.  */
> @@ -10016,7 +10015,7 @@ fp_one_operand (rtx op)
>    if (GET_MODE (op) != SFmode)
>      return false;
>
> -  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst1);
> +  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst<1> ());
>  }
>
>  /* Return the TLS type for TLS symbols.  */
> diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
> index 00f2370..81e5ebe 100644
> --- a/gcc/config/xtensa/predicates.md
> +++ b/gcc/config/xtensa/predicates.md
> @@ -150,7 +150,7 @@
>  (define_predicate "const_float_1_operand"
>    (match_code "const_double")
>  {
> -  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst1);
> +  return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst<1> ());
>  })
>
>  (define_predicate "fpmem_offset_operand"
> diff --git a/gcc/cprop.c b/gcc/cprop.c
> index 4cb8586..f983350 100644
> --- a/gcc/cprop.c
> +++ b/gcc/cprop.c
> @@ -1352,7 +1352,7 @@ implicit_set_cond_p (const_rtx cond)
>        /* ??? The complex and vector checks are not implemented yet.  We just
>          always return zero for them.  */
>        if (CONST_DOUBLE_AS_FLOAT_P (cst)
> -         && real_equal (CONST_DOUBLE_REAL_VALUE (cst), &dconst0))
> +         && real_equal (CONST_DOUBLE_REAL_VALUE (cst), &dconst<0> ()))
>         return 0;
>        else
>         return 0;
> diff --git a/gcc/dfp.c b/gcc/dfp.c
> index ceb43d1..6dbdcad 100644
> --- a/gcc/dfp.c
> +++ b/gcc/dfp.c
> @@ -115,22 +115,22 @@ decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
>           /* dconst{1,2,m1,half} are used in various places in
>              the middle-end and optimizers, allow them here
>              as an exception by converting them to decimal.  */
> -         if (memcmp (r, &dconst1, sizeof (*r)) == 0)
> +         if (memcmp (r, &dconst<1> (), sizeof (*r)) == 0)
>             {
>               decNumberFromString (dn, "1", &set);
>               break;
>             }
> -         if (memcmp (r, &dconst2, sizeof (*r)) == 0)
> +         if (memcmp (r, &dconst<2> (), sizeof (*r)) == 0)
>             {
>               decNumberFromString (dn, "2", &set);
>               break;
>             }
> -         if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
> +         if (memcmp (r, &dconst<-1> (), sizeof (*r)) == 0)
>             {
>               decNumberFromString (dn, "-1", &set);
>               break;
>             }
> -         if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
> +         if (memcmp (r, &dconst<1, 2> (), sizeof (*r)) == 0)
>             {
>               decNumberFromString (dn, "0.5", &set);
>               break;
> diff --git a/gcc/doc/match-and-simplify.texi b/gcc/doc/match-and-simplify.texi
> index c5c2b7e..cc1f573 100644
> --- a/gcc/doc/match-and-simplify.texi
> +++ b/gcc/doc/match-and-simplify.texi
> @@ -165,7 +165,7 @@ chain conditions avoiding nesting @code{if}s too much:
>   (switch
>    /* a CMP (-0) -> a CMP 0  */
>    (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@@1)))
> -   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst0); @}))
> +   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst<0> ()); @}))
>    /* x != NaN is always true, other ops are always false.  */
>    (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@@1))
>         && ! HONOR_SNANS (@@1))
> @@ -180,7 +180,7 @@ Is equal to
>   (switch
>    /* a CMP (-0) -> a CMP 0  */
>    (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@@1)))
> -   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst0); @})
> +   (cmp @@0 @{ build_real (TREE_TYPE (@@1), dconst<0> ()); @})
>     /* x != NaN is always true, other ops are always false.  */
>     (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@@1))
>          && ! HONOR_SNANS (@@1))
> @@ -310,7 +310,8 @@ be added to a new @code{for}.  For example
>  (define_operator_list POW BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
>  (simplify
>   (SQRT (POW @@0 @@1))
> - (POW (abs @@0) (mult @@1 @{ built_real (TREE_TYPE (@@1), dconsthalf); @})))
> + (POW (abs @@0) (mult @@1 @{ build_real (TREE_TYPE (@@1),
> +                                      dconst<1, 2> ()); @})))
>  @end smallexample
>
>  is the same as
> @@ -320,7 +321,8 @@ is the same as
>       POW (BUILT_IN_POWF BUILT_IN_POW BUILT_IN_POWL)
>   (simplify
>    (SQRT (POW @@0 @@1))
> -  (POW (abs @@0) (mult @@1 @{ built_real (TREE_TYPE (@@1), dconsthalf); @}))))
> +  (POW (abs @@0) (mult @@1 @{ build_real (TREE_TYPE (@@1),
> +                                       dconst<1, 2> ()); @}))))
>  @end smallexample
>
>  Another building block are @code{with} expressions in the
> diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
> index c418c24..7d1dc5e 100644
> --- a/gcc/emit-rtl.c
> +++ b/gcc/emit-rtl.c
> @@ -104,12 +104,6 @@ rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
>
>  rtx const_true_rtx;
>
> -REAL_VALUE_TYPE dconst0;
> -REAL_VALUE_TYPE dconst1;
> -REAL_VALUE_TYPE dconst2;
> -REAL_VALUE_TYPE dconstm1;
> -REAL_VALUE_TYPE dconsthalf;
> -
>  /* Record fixed-point constant 0 and 1.  */
>  FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
>  FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
> @@ -5878,7 +5872,6 @@ init_emit_once (void)
>  {
>    int i;
>    machine_mode mode;
> -  machine_mode double_mode;
>
>    /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
>       CONST_FIXED, and memory attribute hash tables.  */
> @@ -5917,20 +5910,10 @@ init_emit_once (void)
>
>    double_mode = mode_for_size (DOUBLE_TYPE_SIZE, MODE_FLOAT, 0);
>
> -  real_from_integer (&dconst0, double_mode, 0, SIGNED);
> -  real_from_integer (&dconst1, double_mode, 1, SIGNED);
> -  real_from_integer (&dconst2, double_mode, 2, SIGNED);
> -
> -  dconstm1 = dconst1;
> -  dconstm1.sign = 1;
> -
> -  dconsthalf = dconst1;
> -  SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);
> -
>    for (i = 0; i < 3; i++)
>      {
>        const REAL_VALUE_TYPE *const r =
> -       (i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
> +       (i == 0 ? &dconst<0> () : i == 1 ? &dconst<1> () : &dconst<2> ());
>
>        for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
>            mode != VOIDmode;
> diff --git a/gcc/expmed.c b/gcc/expmed.c
> index 93cf508..6327993 100644
> --- a/gcc/expmed.c
> +++ b/gcc/expmed.c
> @@ -3235,7 +3235,7 @@ expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
>
>    /* Expand x*2.0 as x+x.  */
>    if (CONST_DOUBLE_AS_FLOAT_P (scalar_op1)
> -      && real_equal (CONST_DOUBLE_REAL_VALUE (scalar_op1), &dconst2))
> +      && real_equal (CONST_DOUBLE_REAL_VALUE (scalar_op1), &dconst<2> ()))
>      {
>        op0 = force_reg (GET_MODE (op0), op0);
>        return expand_binop (mode, add_optab, op0, op0,
> diff --git a/gcc/fold-const.c b/gcc/fold-const.c
> index 2851a29..60149c8 100644
> --- a/gcc/fold-const.c
> +++ b/gcc/fold-const.c
> @@ -1176,7 +1176,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
>        /* Don't perform operation if it would raise a division
>          by zero exception.  */
>        if (code == RDIV_EXPR
> -         && real_equal (&d2, &dconst0)
> +         && real_equal (&d2, &dconst<0> ())
>           && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
>         return NULL_TREE;
>
> @@ -3600,9 +3600,9 @@ distribute_real_division (location_t loc, enum tree_code code, tree type,
>        r0 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
>        r1 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
>        if (!mul0)
> -       real_arithmetic (&r0, RDIV_EXPR, &dconst1, &r0);
> +       real_arithmetic (&r0, RDIV_EXPR, &dconst<1> (), &r0);
>        if (!mul1)
> -        real_arithmetic (&r1, RDIV_EXPR, &dconst1, &r1);
> +       real_arithmetic (&r1, RDIV_EXPR, &dconst<1> (), &r1);
>        real_arithmetic (&r0, code, &r0, &r1);
>        return fold_build2_loc (loc, MULT_EXPR, type,
>                           TREE_OPERAND (arg0, 0),
> @@ -9914,7 +9914,7 @@ fold_binary_loc (location_t loc,
>
>                   if (powfn)
>                     {
> -                     tree arg = build_real (type, dconst2);
> +                     tree arg = build_real (type, dconst<2> ());
>                       return build_call_expr_loc (loc, powfn, 2, arg0, arg);
>                     }
>                 }
> diff --git a/gcc/java/decl.c b/gcc/java/decl.c
> index c035fe0..6bb3aa1 100644
> --- a/gcc/java/decl.c
> +++ b/gcc/java/decl.c
> @@ -669,8 +669,8 @@ java_init_decl_processing (void)
>                          double_type_node));
>    layout_type (double_type_node);
>
> -  float_zero_node = build_real (float_type_node, dconst0);
> -  double_zero_node = build_real (double_type_node, dconst0);
> +  float_zero_node = build_real (float_type_node, dconst<0> ());
> +  double_zero_node = build_real (double_type_node, dconst<0> ());
>
>    /* These are the vtables for arrays of primitives.  */
>    boolean_array_vtable = create_primitive_vtable ("boolean");
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 9962b0a..8e2069b 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -1298,7 +1298,7 @@ along with GCC; see the file COPYING3.  If not see
>  (simplify
>   (plus @0 @0)
>   (if (SCALAR_FLOAT_TYPE_P (type))
> -  (mult @0 { build_real (type, dconst2); })))
> +  (mult @0 { build_real (type, dconst<2> ()); })))
>
>  (simplify
>   (minus integer_zerop @1)
> @@ -1598,7 +1598,7 @@ along with GCC; see the file COPYING3.  If not see
>    (switch
>     /* a CMP (-0) -> a CMP 0  */
>     (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1)))
> -    (cmp @0 { build_real (TREE_TYPE (@1), dconst0); }))
> +    (cmp @0 { build_real (TREE_TYPE (@1), dconst<0> ()); }))
>     /* x != NaN is always true, other ops are always false.  */
>     (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
>         && ! HONOR_SNANS (@1))
> @@ -1694,7 +1694,7 @@ along with GCC; see the file COPYING3.  If not see
>         (if (cmp == NE_EXPR || !HONOR_NANS (@0))
>         { constant_boolean_node (true, type); })
>         /* sqrt(x) > y is the same as x >= 0, if y is negative.  */
> -       (ge @0 { build_real (TREE_TYPE (@0), dconst0); })))
> +       (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); })))
>       (if (cmp == GT_EXPR || cmp == GE_EXPR)
>        (with
>         {
> @@ -1731,11 +1731,11 @@ along with GCC; see the file COPYING3.  If not see
>          /* sqrt(x) < y is x >= 0 when y is very large and we
>             don't care about Infinities.  */
>          (if (! HONOR_INFINITIES (@0))
> -         (ge @0 { build_real (TREE_TYPE (@0), dconst0); }))
> +         (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); }))
>          /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
>          (if (GENERIC)
>           (truth_andif
> -          (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
> +          (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); })
>            (ne @0 { build_real (TREE_TYPE (@0), c2); }))))
>         /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs.  */
>         (if (! HONOR_NANS (@0))
> @@ -1743,7 +1743,7 @@ along with GCC; see the file COPYING3.  If not see
>          /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
>          (if (GENERIC)
>           (truth_andif
> -          (ge @0 { build_real (TREE_TYPE (@0), dconst0); })
> +          (ge @0 { build_real (TREE_TYPE (@0), dconst<0> ()); })
>            (cmp @0 { build_real (TREE_TYPE (@0), c2); }))))))))))))
>
>  /* Unordered tests if either argument is a NaN.  */
> @@ -2193,7 +2193,7 @@ along with GCC; see the file COPYING3.  If not see
>           break;
>         CASE_FLT_FN (BUILT_IN_EXP2):
>           /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
> -         x = build_real (type, dconst2);
> +         x = build_real (type, dconst<2> ());
>           break;
>         CASE_FLT_FN (BUILT_IN_EXP10):
>         CASE_FLT_FN (BUILT_IN_POW10):
> @@ -2221,11 +2221,11 @@ along with GCC; see the file COPYING3.  If not see
>         {
>         CASE_FLT_FN (BUILT_IN_SQRT):
>          /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
> -        x = build_real (type, dconsthalf);
> +        x = build_real (type, dconst<1, 2> ());
>           break;
>         CASE_FLT_FN (BUILT_IN_CBRT):
>          /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
> -         x = build_real_truncate (type, dconst_third ());
> +        x = build_real_truncate (type, dconst<1, 3> ());
>           break;
>         default:
>          gcc_unreachable ();
> diff --git a/gcc/real.c b/gcc/real.c
> index 49d6739..fb77502 100644
> --- a/gcc/real.c
> +++ b/gcc/real.c
> @@ -111,7 +111,6 @@ static void decimal_integer_string (char *, const REAL_VALUE_TYPE *,
>
>  static const REAL_VALUE_TYPE * ten_to_ptwo (int);
>  static const REAL_VALUE_TYPE * ten_to_mptwo (int);
> -static const REAL_VALUE_TYPE * real_digit (int);
>  static void times_pten (REAL_VALUE_TYPE *, int);
>
>  static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
> @@ -1273,7 +1272,7 @@ real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
>  bool
>  exact_real_inverse (machine_mode mode, REAL_VALUE_TYPE *r)
>  {
> -  const REAL_VALUE_TYPE *one = real_digit (1);
> +  const REAL_VALUE_TYPE *one = &dconst<1> ();
>    REAL_VALUE_TYPE u;
>    int i;
>
> @@ -1579,7 +1578,7 @@ real_to_decimal_for_mode (char *str, const REAL_VALUE_TYPE *r_orig,
>    if (digits > max_digits)
>      digits = max_digits;
>
> -  one = real_digit (1);
> +  one = &dconst<1> ();
>    ten = ten_to_ptwo (0);
>
>    sign = r.sign;
> @@ -2225,6 +2224,22 @@ real_from_integer (REAL_VALUE_TYPE *r, machine_mode mode,
>      real_convert (r, mode, r);
>  }
>
> +/* Set VALUE to A/B, in maximum precision.  */
> +
> +void
> +real_from_fraction (REAL_VALUE_TYPE *value, int a, int b)
> +{
> +  if (b == 1)
> +    real_from_integer (value, VOIDmode, a, SIGNED);
> +  else
> +    {
> +      REAL_VALUE_TYPE areal, breal;
> +      real_from_integer (&areal, VOIDmode, a, SIGNED);
> +      real_from_integer (&breal, VOIDmode, b, SIGNED);
> +      real_arithmetic (value, RDIV_EXPR, &areal, &breal);
> +    }
> +}
> +
>  /* Render R, an integral value, as a floating point constant with no
>     specified exponent.  */
>
> @@ -2252,7 +2267,7 @@ decimal_integer_string (char *str, const REAL_VALUE_TYPE *r_orig,
>    digits = dec_exp + 1;
>    gcc_assert ((digits + 2) < (int)buf_size);
>
> -  pten = *real_digit (1);
> +  pten = dconst<1> ();
>    times_pten (&pten, dec_exp);
>
>    p = str;
> @@ -2326,27 +2341,11 @@ ten_to_mptwo (int n)
>    gcc_assert (n < EXP_BITS);
>
>    if (tens[n].cl == rvc_zero)
> -    do_divide (&tens[n], real_digit (1), ten_to_ptwo (n));
> +    do_divide (&tens[n], &dconst<1> (), ten_to_ptwo (n));
>
>    return &tens[n];
>  }
>
> -/* Returns N.  */
> -
> -static const REAL_VALUE_TYPE *
> -real_digit (int n)
> -{
> -  static REAL_VALUE_TYPE num[10];
> -
> -  gcc_assert (n >= 0);
> -  gcc_assert (n <= 9);
> -
> -  if (n > 0 && num[n].cl == rvc_zero)
> -    real_from_integer (&num[n], VOIDmode, n, UNSIGNED);
> -
> -  return &num[n];
> -}
> -
>  /* Multiply R by 10**EXP.  */
>
>  static void
> @@ -2359,7 +2358,7 @@ times_pten (REAL_VALUE_TYPE *r, int exp)
>    if (negative)
>      {
>        exp = -exp;
> -      pten = *real_digit (1);
> +      pten = dconst<1> ();
>        rr = &pten;
>      }
>    else
> @@ -2395,22 +2394,6 @@ dconst_e_ptr (void)
>    return &value;
>  }
>
> -/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
> -
> -const REAL_VALUE_TYPE *
> -dconst_third_ptr (void)
> -{
> -  static REAL_VALUE_TYPE value;
> -
> -  /* Initialize mathematical constants for constant folding builtins.
> -     These constants need to be given to at least 160 bits precision.  */
> -  if (value.cl == rvc_zero)
> -    {
> -      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
> -    }
> -  return &value;
> -}
> -
>  /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
>
>  const REAL_VALUE_TYPE *
> @@ -4878,7 +4861,7 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
>
>    if (n == 0)
>      {
> -      *r = dconst1;
> +      *r = dconst<1> ();
>        return false;
>      }
>    else if (n < 0)
> @@ -4906,7 +4889,7 @@ real_powi (REAL_VALUE_TYPE *r, machine_mode mode,
>      }
>
>    if (neg)
> -    inexact |= do_divide (&t, &dconst1, &t);
> +    inexact |= do_divide (&t, &dconst<1> (), &t);
>
>    real_convert (r, mode, &t);
>    return inexact;
> @@ -4935,7 +4918,7 @@ real_floor (REAL_VALUE_TYPE *r, machine_mode mode,
>
>    do_fix_trunc (&t, x);
>    if (! real_identical (&t, x) && x->sign)
> -    do_add (&t, &t, &dconstm1, 0);
> +    do_add (&t, &t, &dconst<-1> (), 0);
>    if (mode != VOIDmode)
>      real_convert (r, mode, &t);
>    else
> @@ -4953,7 +4936,7 @@ real_ceil (REAL_VALUE_TYPE *r, machine_mode mode,
>
>    do_fix_trunc (&t, x);
>    if (! real_identical (&t, x) && ! x->sign)
> -    do_add (&t, &t, &dconst1, 0);
> +    do_add (&t, &t, &dconst<1> (), 0);
>    if (mode != VOIDmode)
>      real_convert (r, mode, &t);
>    else
> @@ -4967,7 +4950,7 @@ void
>  real_round (REAL_VALUE_TYPE *r, machine_mode mode,
>             const REAL_VALUE_TYPE *x)
>  {
> -  do_add (r, x, &dconsthalf, x->sign);
> +  do_add (r, x, &dconst<1, 2> (), x->sign);
>    do_fix_trunc (r, r);
>    if (mode != VOIDmode)
>      real_convert (r, mode, r);
> diff --git a/gcc/real.h b/gcc/real.h
> index 1497279..72e1a04 100644
> --- a/gcc/real.h
> +++ b/gcc/real.h
> @@ -403,22 +403,12 @@ extern void real_ldexp (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
>
>  /* Constant real values 0, 1, 2, -1 and 0.5.  */
>
> -extern REAL_VALUE_TYPE dconst0;
> -extern REAL_VALUE_TYPE dconst1;
> -extern REAL_VALUE_TYPE dconst2;
> -extern REAL_VALUE_TYPE dconstm1;
> -extern REAL_VALUE_TYPE dconsthalf;
> -
> -#define dconst_e()  (*dconst_e_ptr ())
> -#define dconst_third()  (*dconst_third_ptr ())
> -#define dconst_sqrt2()  (*dconst_sqrt2_ptr ())
> +#define dconst_e() (*dconst_e_ptr ())
> +#define dconst_sqrt2() (*dconst_sqrt2_ptr ())
>
>  /* Function to return the real value special constant 'e'.  */
>  extern const REAL_VALUE_TYPE * dconst_e_ptr (void);
>
> -/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
> -extern const REAL_VALUE_TYPE * dconst_third_ptr (void);
> -
>  /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
>  extern const REAL_VALUE_TYPE * dconst_sqrt2_ptr (void);
>
> @@ -473,6 +463,26 @@ extern void get_max_float (const struct real_format *, char *, size_t);
>  extern wide_int real_to_integer (const REAL_VALUE_TYPE *, bool *, int);
>  extern void real_from_integer (REAL_VALUE_TYPE *, machine_mode,
>                                const wide_int_ref &, signop);
> +extern void real_from_fraction (REAL_VALUE_TYPE *, int, int);
> +
> +/* Return a constant A/B, in maximum precision.  */
> +template<int a, int b>
> +inline const REAL_VALUE_TYPE &
> +dconst (void)
> +{
> +  static REAL_VALUE_TYPE value;
> +  if (value.cl == rvc_zero)
> +    real_from_fraction (&value, a, b);
> +  return value;
> +}
> +
> +/* Return a real for integer constant A.  */
> +template<int a>
> +inline const REAL_VALUE_TYPE &
> +dconst (void)
> +{
> +  return dconst<a, 1> ();
> +}
>  #endif
>
>  #endif /* ! GCC_REAL_H */
> diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
> index 1f91afc..2e0afdd 100644
> --- a/gcc/simplify-rtx.c
> +++ b/gcc/simplify-rtx.c
> @@ -2464,11 +2464,11 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
>         {
>           const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
>
> -         if (real_equal (d1, &dconst2))
> +         if (real_equal (d1, &dconst<2> ()))
>             return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
>
>           if (!HONOR_SNANS (mode)
> -             && real_equal (d1, &dconstm1))
> +             && real_equal (d1, &dconst<-1> ()))
>             return simplify_gen_unary (NEG, mode, op0, mode);
>         }
>
> @@ -3093,17 +3093,17 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
>               const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
>
>               /* x/-1.0 is -x.  */
> -             if (real_equal (d1, &dconstm1)
> +             if (real_equal (d1, &dconst<-1> ())
>                   && !HONOR_SNANS (mode))
>                 return simplify_gen_unary (NEG, mode, op0, mode);
>
>               /* Change FP division by a constant into multiplication.
>                  Only do this with -freciprocal-math.  */
>               if (flag_reciprocal_math
> -                 && !real_equal (d1, &dconst0))
> +                 && !real_equal (d1, &dconst<0> ()))
>                 {
>                   REAL_VALUE_TYPE d;
> -                 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
> +                 real_arithmetic (&d, RDIV_EXPR, &dconst<1> (), d1);
>                   tem = const_double_from_real_value (d, mode);
>                   return simplify_gen_binary (MULT, mode, op0, tem);
>                 }
> @@ -3862,7 +3862,7 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
>             return 0;
>
>           if (code == DIV
> -             && real_equal (&f1, &dconst0)
> +             && real_equal (&f1, &dconst<0> ())
>               && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
>             return 0;
>
> @@ -3895,9 +3895,9 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
>
>           if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
>               && flag_trapping_math
> -             && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
> +             && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst<0> ()))
>                   || (REAL_VALUE_ISINF (f1)
> -                     && real_equal (&f0, &dconst0))))
> +                     && real_equal (&f0, &dconst<0> ()))))
>             /* Inf * 0 = NaN plus exception.  */
>             return 0;
>
> diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
> index 112a325..640e7e5 100644
> --- a/gcc/tree-call-cdce.c
> +++ b/gcc/tree-call-cdce.c
> @@ -199,9 +199,9 @@ check_pow (gcall *pow_call)
>        /* Only handle a fixed range of constant.  */
>        REAL_VALUE_TYPE mv;
>        REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
> -      if (real_equal (&bcv, &dconst1))
> +      if (real_equal (&bcv, &dconst<1> ()))
>          return false;
> -      if (real_less (&bcv, &dconst1))
> +      if (real_less (&bcv, &dconst<1> ()))
>          return false;
>        real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED);
>        if (real_less (&mv, &bcv))
> @@ -420,8 +420,8 @@ gen_conditions_for_pow_cst_base (tree base, tree expn,
>       sure it is consistent with check_pow.  */
>    REAL_VALUE_TYPE mv;
>    REAL_VALUE_TYPE bcv = TREE_REAL_CST (base);
> -  gcc_assert (!real_equal (&bcv, &dconst1)
> -              && !real_less (&bcv, &dconst1));
> +  gcc_assert (!real_equal (&bcv, &dconst<1> ())
> +             && !real_less (&bcv, &dconst<1> ()));
>    real_from_integer (&mv, TYPE_MODE (TREE_TYPE (base)), 256, UNSIGNED);
>    gcc_assert (!real_less (&mv, &bcv));
>
> diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
> index 649c9fe..4a67eb5 100644
> --- a/gcc/tree-chrec.c
> +++ b/gcc/tree-chrec.c
> @@ -132,7 +132,7 @@ chrec_fold_plus_poly_poly (enum tree_code code,
>            chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
>            chrec_fold_multiply (type, CHREC_RIGHT (poly1),
>                                 SCALAR_FLOAT_TYPE_P (type)
> -                               ? build_real (type, dconstm1)
> +                               ? build_real (type, dconst<-1> ())
>                                 : build_int_cst_type (type, -1)));
>      }
>
> @@ -233,7 +233,7 @@ chrec_fold_multiply_poly_poly (tree type,
>    t1 = chrec_fold_plus (type, t1, t2);
>    /* "2*b*d".  */
>    t2 = chrec_fold_multiply (type, SCALAR_FLOAT_TYPE_P (type)
> -                           ? build_real (type, dconst2)
> +                           ? build_real (type, dconst<2> ())
>                             : build_int_cst (type, 2), t2);
>
>    var = CHREC_VARIABLE (poly0);
> @@ -326,7 +326,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
>                chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
>                chrec_fold_multiply (type, CHREC_RIGHT (op1),
>                                     SCALAR_FLOAT_TYPE_P (type)
> -                                   ? build_real (type, dconstm1)
> +                                   ? build_real (type, dconst<-1> ())
>                                     : build_int_cst_type (type, -1)));
>
>         CASE_CONVERT:
> diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
> index 93c0a54..2dce4dc 100644
> --- a/gcc/tree-complex.c
> +++ b/gcc/tree-complex.c
> @@ -118,7 +118,7 @@ some_nonzerop (tree t)
>       cannot be treated the same as operations with a real or imaginary
>       operand if we care about the signs of zeros in the result.  */
>    if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
> -    zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
> +    zerop = real_identical (&TREE_REAL_CST (t), &dconst<0> ());
>    else if (TREE_CODE (t) == FIXED_CST)
>      zerop = fixed_zerop (t);
>    else if (TREE_CODE (t) == INTEGER_CST)
> @@ -495,7 +495,7 @@ get_component_ssa_name (tree ssa_name, bool imag_p)
>      {
>        tree inner_type = TREE_TYPE (TREE_TYPE (ssa_name));
>        if (SCALAR_FLOAT_TYPE_P (inner_type))
> -       return build_real (inner_type, dconst0);
> +       return build_real (inner_type, dconst<0> ());
>        else
>         return build_int_cst (inner_type, 0);
>      }
> @@ -1021,7 +1021,7 @@ expand_complex_multiplication (gimple_stmt_iterator *gsi, tree inner_type,
>      case PAIR (ONLY_IMAG, ONLY_REAL):
>        rr = ar;
>        if (TREE_CODE (ai) == REAL_CST
> -         && real_identical (&TREE_REAL_CST (ai), &dconst1))
> +         && real_identical (&TREE_REAL_CST (ai), &dconst<1> ()))
>         ri = br;
>        else
>         ri = gimplify_build2 (gsi, MULT_EXPR, inner_type, ai, br);
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index 9b525f3..0758895 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -4094,7 +4094,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights)
>                       if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
>                           && (real_equal
>                               (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
> -                              &dconst2)))
> +                              &dconst<2> ())))
>                         return estimate_operator_cost
>                             (MULT_EXPR, weights, gimple_call_arg (stmt, 0),
>                              gimple_call_arg (stmt, 0));
> diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
> index 0753bf3..e3f94fa 100644
> --- a/gcc/tree-scalar-evolution.c
> +++ b/gcc/tree-scalar-evolution.c
> @@ -638,7 +638,7 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
>               var = loop_nb;
>               left = chrec_before;
>               right = SCALAR_FLOAT_TYPE_P (type)
> -               ? build_real (type, dconst0)
> +               ? build_real (type, dconst<0> ())
>                 : build_int_cst (type, 0);
>             }
>           else
> @@ -840,7 +840,7 @@ add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
>
>    if (code == MINUS_EXPR)
>      to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
> -                                 ? build_real (type, dconstm1)
> +                                 ? build_real (type, dconst<-1> ())
>                                   : build_int_cst_type (type, -1));
>
>    res = add_to_evolution_1 (loop_nb, chrec_before, to_add, at_stmt);
> diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
> index c226da5..5919c84 100644
> --- a/gcc/tree-ssa-dom.c
> +++ b/gcc/tree-ssa-dom.c
> @@ -1158,7 +1158,7 @@ record_equality (tree x, tree y, class const_and_copies *const_and_copies)
>       nonzero.  */
>    if (HONOR_SIGNED_ZEROS (x)
>        && (TREE_CODE (y) != REAL_CST
> -         || real_equal (&dconst0, &TREE_REAL_CST (y))))
> +         || real_equal (&dconst<0> (), &TREE_REAL_CST (y))))
>      return;
>
>    const_and_copies->record_const_or_copy (x, y, prev_x);
> diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
> index 39c027c..288daef 100644
> --- a/gcc/tree-ssa-math-opts.c
> +++ b/gcc/tree-ssa-math-opts.c
> @@ -1003,7 +1003,7 @@ powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
>    tree target;
>
>    if (n == 0)
> -    return build_real (type, dconst1);
> +    return build_real (type, dconst<1> ());
>
>    memset (cache, 0,  sizeof (cache));
>    cache[1] = arg0;
> @@ -1015,7 +1015,7 @@ powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
>    /* If the original exponent was negative, reciprocate the result.  */
>    target = make_temp_ssa_name (type, NULL, "powmult");
>    div_stmt = gimple_build_assign (target, RDIV_EXPR,
> -                                 build_real (type, dconst1), result);
> +                                 build_real (type, dconst<1> ()), result);
>    gimple_set_location (div_stmt, loc);
>    gsi_insert_before (gsi, div_stmt, GSI_SAME_STMT);
>
> @@ -1128,7 +1128,7 @@ bool
>  representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
>                                  struct pow_synth_sqrt_info *info)
>  {
> -  REAL_VALUE_TYPE factor = dconsthalf;
> +  REAL_VALUE_TYPE factor = dconst<1, 2> ();
>    REAL_VALUE_TYPE remainder = c;
>
>    info->deepest = 0;
> @@ -1145,7 +1145,7 @@ representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
>
>        /* We have hit zero.  The number is representable as a sum
>           of powers of 0.5.  */
> -      if (real_equal (&res, &dconst0))
> +      if (real_equal (&res, &dconst<0> ()))
>         {
>           info->factors[i] = true;
>           info->deepest = i + 1;
> @@ -1160,7 +1160,7 @@ representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
>        else
>         info->factors[i] = false;
>
> -      real_arithmetic (&factor, MULT_EXPR, &factor, &dconsthalf);
> +      real_arithmetic (&factor, MULT_EXPR, &factor, &dconst<1, 2> ());
>      }
>    return false;
>  }
> @@ -1320,8 +1320,8 @@ expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
>    real_arithmetic (&frac_part, MINUS_EXPR, &exp, &whole_part);
>
>
> -  REAL_VALUE_TYPE ceil_whole = dconst0;
> -  REAL_VALUE_TYPE ceil_fract = dconst0;
> +  REAL_VALUE_TYPE ceil_whole = dconst<0> ();
> +  REAL_VALUE_TYPE ceil_fract = dconst<0> ();
>
>    if (neg_exp)
>      {
> @@ -1367,7 +1367,7 @@ expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
>
>    memset (cache, 0, (max_depth + 1) * sizeof (tree));
>
> -  tree integer_res = n == 0 ? build_real (type, dconst1) : arg0;
> +  tree integer_res = n == 0 ? build_real (type, dconst<1> ()) : arg0;
>
>    /* Calculate the integer part of the exponent.  */
>    if (n > 1)
> @@ -1447,7 +1447,7 @@ expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
>             res = fract_res;
>
>           res = build_and_insert_binop (gsi, loc, "powrootrecip", RDIV_EXPR,
> -                                         build_real (type, dconst1), res);
> +                                       build_real (type, dconst<1> ()), res);
>         }
>        else
>         {
> @@ -1470,17 +1470,13 @@ static tree
>  gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>                            tree arg0, tree arg1)
>  {
> -  REAL_VALUE_TYPE c, cint, dconst1_3, dconst1_4, dconst1_6;
> -  REAL_VALUE_TYPE c2, dconst3;
> +  REAL_VALUE_TYPE c, c2, cint, dconst1_3, dconst1_6;
>    HOST_WIDE_INT n;
>    tree type, sqrtfn, cbrtfn, sqrt_arg0, result, cbrt_x, powi_cbrt_x;
>    machine_mode mode;
>    bool speed_p = optimize_bb_for_speed_p (gsi_bb (*gsi));
>    bool hw_sqrt_exists, c_is_int, c2_is_int;
>
> -  dconst1_4 = dconst1;
> -  SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2);
> -
>    /* If the exponent isn't a constant, there's nothing of interest
>       to be done.  */
>    if (TREE_CODE (arg1) != REAL_CST)
> @@ -1509,7 +1505,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>       unless signed zeros must be maintained.  pow(-0,0.5) = +0, while
>       sqrt(-0) = -0.  */
>    if (sqrtfn
> -      && real_equal (&c, &dconsthalf)
> +      && real_equal (&c, &dconst<1, 2> ())
>        && !HONOR_SIGNED_ZEROS (mode))
>      return build_and_insert_call (gsi, loc, sqrtfn, arg0);
>
> @@ -1522,7 +1518,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>       of 1./3. actually has an even denominator.  The correct value
>       of cbrt(x) is a negative real value.  */
>    cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
> -  dconst1_3 = real_value_truncate (mode, dconst_third ());
> +  dconst1_3 = real_value_truncate (mode, dconst<1, 3> ());
>
>    if (flag_unsafe_math_optimizations
>        && cbrtfn
> @@ -1556,7 +1552,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>    if (flag_unsafe_math_optimizations
>        && sqrtfn
>        && hw_sqrt_exists
> -      && (speed_p || real_equal (&c, &dconst1_4))
> +      && (speed_p || real_equal (&c, &dconst<1, 4> ()))
>        && !HONOR_SIGNED_ZEROS (mode))
>      {
>        unsigned int max_depth = speed_p
> @@ -1570,7 +1566,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>         return expand_with_sqrts;
>      }
>
> -  real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
> +  real_arithmetic (&c2, MULT_EXPR, &c, &dconst<2> ());
>    n = real_to_integer (&c2);
>    real_from_integer (&cint, VOIDmode, n, SIGNED);
>    c2_is_int = real_identical (&c2, &cint);
> @@ -1584,12 +1580,11 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>       different from pow(x, 1./3.) due to rounding and behavior with
>       negative x, we need to constrain this transformation to unsafe
>       math and positive x or finite math.  */
> -  real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
> -  real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
> +  real_arithmetic (&c2, MULT_EXPR, &c, &dconst<3> ());
>    real_round (&c2, mode, &c2);
>    n = real_to_integer (&c2);
>    real_from_integer (&cint, VOIDmode, n, SIGNED);
> -  real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
> +  real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst<3> ());
>    real_convert (&c2, mode, &c2);
>
>    if (flag_unsafe_math_optimizations
> @@ -1634,7 +1629,8 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
>        /* If n is negative, reciprocate the result.  */
>        if (n < 0)
>         result = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
> -                                        build_real (type, dconst1), result);
> +                                        build_real (type, dconst<1> ()),
> +                                        result);
>
>        return result;
>      }
> @@ -1793,8 +1789,8 @@ pass_cse_sincos::execute (function *fun)
>
>                       t0 = TREE_TYPE (arg0);
>                       t1 = TREE_TYPE (arg1);
> -                     one = build_real (t0, dconst1);
> -                     minus_one = build_real (t0, dconstm1);
> +                     one = build_real (t0, dconst<1> ());
> +                     minus_one = build_real (t0, dconst<-1> ());
>
>                       cond = make_temp_ssa_name (t1, NULL, "powi_cond");
>                       stmt = gimple_build_assign (cond, BIT_AND_EXPR,
> @@ -3591,7 +3587,7 @@ pass_optimize_widening_mul::execute (function *fun)
>                         if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
>                             && real_equal
>                                  (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
> -                                 &dconst2)
> +                                 &dconst<2> ())
>                             && convert_mult_to_fma (stmt,
>                                                     gimple_call_arg (stmt, 0),
>                                                     gimple_call_arg (stmt, 0)))
> diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
> index 0f16c50..c247db7 100644
> --- a/gcc/tree-ssa-uncprop.c
> +++ b/gcc/tree-ssa-uncprop.c
> @@ -153,7 +153,7 @@ associate_equivalences_with_edges (void)
>                      this value unless we know that the value is nonzero.  */
>                   if (HONOR_SIGNED_ZEROS (op0)
>                       && (TREE_CODE (op1) != REAL_CST
> -                         || real_equal (&dconst0, &TREE_REAL_CST (op1))))
> +                         || real_equal (&dconst<0> (), &TREE_REAL_CST (op1))))
>                     continue;
>
>                   equivalency = XNEW (struct edge_equivalency);
> diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
> index 63e29aa..7d23428 100644
> --- a/gcc/tree-vect-loop.c
> +++ b/gcc/tree-vect-loop.c
> @@ -3821,7 +3821,7 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val,
>    int i;
>    bool nested_in_vect_loop = false;
>    tree init_value;
> -  REAL_VALUE_TYPE real_init_val = dconst0;
> +  REAL_VALUE_TYPE real_init_val = dconst<0> ();
>    int int_init_val = 0;
>    gimple *def_stmt = NULL;
>
> @@ -3886,7 +3886,7 @@ get_initial_def_for_reduction (gimple *stmt, tree init_val,
>
>          if (code == MULT_EXPR)
>            {
> -            real_init_val = dconst1;
> +            real_init_val = dconst<1> ();
>              int_init_val = 1;
>            }
>
> diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
> index 48b5298..e78de75 100644
> --- a/gcc/tree-vect-patterns.c
> +++ b/gcc/tree-vect-patterns.c
> @@ -1084,7 +1084,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
>    if ((tree_fits_shwi_p (exp)
>         && tree_to_shwi (exp) == 2)
>        || (TREE_CODE (exp) == REAL_CST
> -          && real_equal (&TREE_REAL_CST (exp), &dconst2)))
> +         && real_equal (&TREE_REAL_CST (exp), &dconst<2> ())))
>      {
>        *type_in = TREE_TYPE (base);
>
> @@ -1095,7 +1095,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in,
>
>    /* Catch square root.  */
>    if (TREE_CODE (exp) == REAL_CST
> -      && real_equal (&TREE_REAL_CST (exp), &dconsthalf))
> +      && real_equal (&TREE_REAL_CST (exp), &dconst<1, 2> ()))
>      {
>        tree newfn = mathfn_built_in (TREE_TYPE (base), BUILT_IN_SQRT);
>        *type_in = get_vectype_for_scalar_type (TREE_TYPE (base));
> diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
> index 7a2d623..3b8e26b 100644
> --- a/gcc/tree-vect-slp.c
> +++ b/gcc/tree-vect-slp.c
> @@ -2617,7 +2617,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
>            case BIT_IOR_EXPR:
>            case BIT_XOR_EXPR:
>               if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (op)))
> -               neutral_op = build_real (TREE_TYPE (op), dconst0);
> +               neutral_op = build_real (TREE_TYPE (op), dconst<0> ());
>               else
>                 neutral_op = build_int_cst (TREE_TYPE (op), 0);
>
> @@ -2625,7 +2625,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
>
>            case MULT_EXPR:
>               if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (op)))
> -               neutral_op = build_real (TREE_TYPE (op), dconst1);
> +               neutral_op = build_real (TREE_TYPE (op), dconst<1> ());
>               else
>                 neutral_op = build_int_cst (TREE_TYPE (op), 1);
>
> diff --git a/gcc/tree.c b/gcc/tree.c
> index f78a2c2..ef70b03 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -1991,7 +1991,7 @@ build_one_cst (tree type)
>        return build_int_cst (type, 1);
>
>      case REAL_TYPE:
> -      return build_real (type, dconst1);
> +      return build_real (type, dconst<1> ());
>
>      case FIXED_POINT_TYPE:
>        /* We can only generate 1 for accum types.  */
> @@ -2044,7 +2044,7 @@ build_minus_one_cst (tree type)
>        return build_int_cst (type, -1);
>
>      case REAL_TYPE:
> -      return build_real (type, dconstm1);
> +      return build_real (type, dconst<-1> ());
>
>      case FIXED_POINT_TYPE:
>        /* We can only generate 1 for accum types.  */
> @@ -2084,7 +2084,7 @@ build_zero_cst (tree type)
>        return build_int_cst (type, 0);
>
>      case REAL_TYPE:
> -      return build_real (type, dconst0);
> +      return build_real (type, dconst<0> ());
>
>      case FIXED_POINT_TYPE:
>        return build_fixed (type, FCONST0 (TYPE_MODE (type)));
> @@ -2554,7 +2554,7 @@ real_zerop (const_tree expr)
>    switch (TREE_CODE (expr))
>      {
>      case REAL_CST:
> -      return real_equal (&TREE_REAL_CST (expr), &dconst0)
> +      return real_equal (&TREE_REAL_CST (expr), &dconst<0> ())
>              && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
>      case COMPLEX_CST:
>        return real_zerop (TREE_REALPART (expr))
> @@ -2584,7 +2584,7 @@ real_onep (const_tree expr)
>    switch (TREE_CODE (expr))
>      {
>      case REAL_CST:
> -      return real_equal (&TREE_REAL_CST (expr), &dconst1)
> +      return real_equal (&TREE_REAL_CST (expr), &dconst<1> ())
>              && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
>      case COMPLEX_CST:
>        return real_onep (TREE_REALPART (expr))
> @@ -2613,7 +2613,7 @@ real_minus_onep (const_tree expr)
>    switch (TREE_CODE (expr))
>      {
>      case REAL_CST:
> -      return real_equal (&TREE_REAL_CST (expr), &dconstm1)
> +      return real_equal (&TREE_REAL_CST (expr), &dconst<-1> ())
>              && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
>      case COMPLEX_CST:
>        return real_minus_onep (TREE_REALPART (expr))
> diff --git a/gcc/ubsan.c b/gcc/ubsan.c
> index af586e3..fe2491c 100644
> --- a/gcc/ubsan.c
> +++ b/gcc/ubsan.c
> @@ -1496,7 +1496,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
>          in EXPR_TYPE, e.g. if TYPE is 64-bit long long and
>          EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is
>          either representable or infinity.  */
> -      REAL_VALUE_TYPE maxval = dconst1;
> +      REAL_VALUE_TYPE maxval = dconst<1> ();
>        SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p);
>        real_convert (&maxval, mode, &maxval);
>        max = build_real (expr_type, maxval);
> @@ -1508,10 +1508,10 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
>         {
>           /* TYPE_MIN_VALUE is generally representable (or -inf),
>              but TYPE_MIN_VALUE - 1.0 might not be.  */
> -         REAL_VALUE_TYPE minval = dconstm1, minval2;
> +         REAL_VALUE_TYPE minval = dconst<-1> (), minval2;
>           SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1);
>           real_convert (&minval, mode, &minval);
> -         real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1);
> +         real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst<1> ());
>           real_convert (&minval2, mode, &minval2);
>           if (real_compare (EQ_EXPR, &minval, &minval2)
>               && !real_isinf (&minval))
> @@ -1522,7 +1522,7 @@ ubsan_instrument_float_cast (location_t loc, tree type, tree expr, tree arg)
>                  of base digits, we want to subtract a number that
>                  will be 1 << (REAL_MODE_FORMAT (mode)->p - 1)
>                  times smaller than minval.  */
> -             minval2 = dconst1;
> +             minval2 = dconst<1> ();
>               gcc_assert (prec > REAL_MODE_FORMAT (mode)->p);
>               SET_REAL_EXP (&minval2,
>                             REAL_EXP (&minval2) + prec - 1
>



More information about the Gcc-patches mailing list