diff mbox

Move force_fit_type_double function from double-int.[ch] to tree.[ch]

Message ID 633567834.20100627193328@post.ru
State New
Headers show

Commit Message

Anatoly Sokolov June 27, 2010, 3:33 p.m. UTC
Hello.

  This patch move force_fit_type_double function from double-int.[ch] to
tree.[ch]. This should allow remove dependency double-int.[ch] from the
tree.h in future.

   Also, this patch change force_fit_type_double argument list. They receive
double int constant in double-int type, not as pair of HOST_WIDE_INT.

 Bootstrapped/regtested on x86_64-unknown-linux-gnu.

 OK for mainline?

        * double-int.h (force_fit_type_double): Remove declaration.
        * double-int.c (force_fit_type_double): Move to tree.c.
        * tree.h (force_fit_type_double): Declare.
        * tree.h (force_fit_type_double): Moved from double-int.c. Use
        double_int type for 'cst' argument. Use double_int_fits_to_tree_p and
        double_int_to_tree instead of fit_double_type and build_int_cst_wide.
        * convert.c (convert_to_pointer): Adjust call to
        force_fit_type_double.
        * tree-vrp.c (extract_range_from_assert,
        extract_range_from_unary_expr): Adjust call to force_fit_type_double.
        * fold-const.c: Update comment.
        (int_const_binop, fold_convert_const_int_from_int,
        fold_convert_const_int_from_real, fold_convert_const_int_from_fixed,
        extract_muldiv_1, fold_div_compare, fold_sign_changed_comparison,
        fold_unary_loc, fold_negate_const, fold_abs_const, fold_not_const,
        round_up_loc): Adjust call to force_fit_type_double.
        
/c-family       
        * c-common.c (shorten_compare): Adjust call to force_fit_type_double.





Anatoly.

Comments

Richard Biener June 28, 2010, 9:29 a.m. UTC | #1
2010/6/27 Anatoly Sokolov <aesok@post.ru>:
> Hello.
>
>  This patch move force_fit_type_double function from double-int.[ch] to
> tree.[ch]. This should allow remove dependency double-int.[ch] from the
> tree.h in future.
>
>   Also, this patch change force_fit_type_double argument list. They receive
> double int constant in double-int type, not as pair of HOST_WIDE_INT.
>
>  Bootstrapped/regtested on x86_64-unknown-linux-gnu.
>
>  OK for mainline?

Ok.

Thanks,
Richard.

>        * double-int.h (force_fit_type_double): Remove declaration.
>        * double-int.c (force_fit_type_double): Move to tree.c.
>        * tree.h (force_fit_type_double): Declare.
>        * tree.h (force_fit_type_double): Moved from double-int.c. Use
>        double_int type for 'cst' argument. Use double_int_fits_to_tree_p and
>        double_int_to_tree instead of fit_double_type and build_int_cst_wide.
>        * convert.c (convert_to_pointer): Adjust call to
>        force_fit_type_double.
>        * tree-vrp.c (extract_range_from_assert,
>        extract_range_from_unary_expr): Adjust call to force_fit_type_double.
>        * fold-const.c: Update comment.
>        (int_const_binop, fold_convert_const_int_from_int,
>        fold_convert_const_int_from_real, fold_convert_const_int_from_fixed,
>        extract_muldiv_1, fold_div_compare, fold_sign_changed_comparison,
>        fold_unary_loc, fold_negate_const, fold_abs_const, fold_not_const,
>        round_up_loc): Adjust call to force_fit_type_double.
>
> /c-family
>        * c-common.c (shorten_compare): Adjust call to force_fit_type_double.
>
>
>
> Index: gcc/tree-vrp.c
> ===================================================================
> --- gcc/tree-vrp.c      (revision 161254)
> +++ gcc/tree-vrp.c      (working copy)
> @@ -1507,10 +1507,10 @@
>       /* Make sure to not set TREE_OVERFLOW on the final type
>         conversion.  We are willingly interpreting large positive
>         unsigned values as negative singed values here.  */
> -      min = force_fit_type_double (TREE_TYPE (var), TREE_INT_CST_LOW (min),
> -                                  TREE_INT_CST_HIGH (min), 0, false);
> -      max = force_fit_type_double (TREE_TYPE (var), TREE_INT_CST_LOW (max),
> -                                  TREE_INT_CST_HIGH (max), 0, false);
> +      min = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (min),
> +                                  0, false);
> +      max = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (max),
> +                                  0, false);
>
>       /* We can transform a max, min range to an anti-range or
>          vice-versa.  Use set_and_canonicalize_value_range which does
> @@ -2783,11 +2783,11 @@
>        {
>          tree new_min, new_max;
>          new_min = force_fit_type_double (outer_type,
> -                                          TREE_INT_CST_LOW (vr0.min),
> -                                          TREE_INT_CST_HIGH (vr0.min), 0, 0);
> +                                          tree_to_double_int (vr0.min),
> +                                          0, false);
>          new_max = force_fit_type_double (outer_type,
> -                                          TREE_INT_CST_LOW (vr0.max),
> -                                          TREE_INT_CST_HIGH (vr0.max), 0, 0);
> +                                          tree_to_double_int (vr0.max),
> +                                          0, false);
>          if (is_overflow_infinity (vr0.min))
>            new_min = negative_overflow_infinity (outer_type);
>          if (is_overflow_infinity (vr0.max))
> Index: gcc/c-family/c-common.c
> ===================================================================
> --- gcc/c-family/c-common.c     (revision 161254)
> +++ gcc/c-family/c-common.c     (working copy)
> @@ -3361,9 +3361,8 @@
>          /* Convert primop1 to target type, but do not introduce
>             additional overflow.  We know primop1 is an int_cst.  */
>          primop1 = force_fit_type_double (*restype_ptr,
> -                                          TREE_INT_CST_LOW (primop1),
> -                                          TREE_INT_CST_HIGH (primop1), 0,
> -                                          TREE_OVERFLOW (primop1));
> +                                          tree_to_double_int (primop1),
> +                                          0, TREE_OVERFLOW (primop1));
>        }
>       if (type != *restype_ptr)
>        {
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c  (revision 161254)
> +++ gcc/tree.c  (working copy)
> @@ -1092,6 +1092,52 @@
>   return double_int_equal_p (cst, ext);
>  }
>
> +/* We force the double_int CST to the range of the type TYPE by sign or
> +   zero extending it.  OVERFLOWABLE indicates if we are interested in
> +   overflow of the value, when >0 we are only interested in signed
> +   overflow, for <0 we are interested in any overflow.  OVERFLOWED
> +   indicates whether overflow has already occurred.  CONST_OVERFLOWED
> +   indicates whether constant overflow has already occurred.  We force
> +   T's value to be within range of T's type (by setting to 0 or 1 all
> +   the bits outside the type's range).  We set TREE_OVERFLOWED if,
> +        OVERFLOWED is nonzero,
> +        or OVERFLOWABLE is >0 and signed overflow occurs
> +        or OVERFLOWABLE is <0 and any overflow occurs
> +   We return a new tree node for the extended double_int.  The node
> +   is shared if no overflow flags are set.  */
> +
> +
> +tree
> +force_fit_type_double (tree type, double_int cst, int overflowable,
> +                      bool overflowed)
> +{
> +  bool sign_extended_type;
> +
> +  /* Size types *are* sign extended.  */
> +  sign_extended_type = (!TYPE_UNSIGNED (type)
> +                        || (TREE_CODE (type) == INTEGER_TYPE
> +                            && TYPE_IS_SIZETYPE (type)));
> +
> +  /* If we need to set overflow flags, return a new unshared node.  */
> +  if (overflowed || !double_int_fits_to_tree_p(type, cst))
> +    {
> +      if (overflowed
> +         || overflowable < 0
> +         || (overflowable > 0 && sign_extended_type))
> +       {
> +         tree t = make_node (INTEGER_CST);
> +         TREE_INT_CST (t) = double_int_ext (cst, TYPE_PRECISION (type),
> +                                            !sign_extended_type);
> +         TREE_TYPE (t) = type;
> +         TREE_OVERFLOW (t) = 1;
> +         return t;
> +       }
> +    }
> +
> +  /* Else build a shared node.  */
> +  return double_int_to_tree (type, cst);
> +}
> +
>  /* These are the hash table functions for the hash table of INTEGER_CST
>    nodes of a sizetype.  */
>
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h  (revision 161254)
> +++ gcc/tree.h  (working copy)
> @@ -4014,6 +4014,7 @@
>
>  extern tree double_int_to_tree (tree, double_int);
>  extern bool double_int_fits_to_tree_p (const_tree, double_int);
> +extern tree force_fit_type_double (tree, double_int, int, bool);
>
>  /* Create an INT_CST node with a CST value zero extended.  */
>
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c    (revision 161254)
> +++ gcc/fold-const.c    (working copy)
> @@ -27,8 +27,7 @@
>   @@ This would also make life easier when this technology is used
>   @@ for cross-compilers.  */
>
> -/* The entry points in this file are fold, size_int_wide, size_binop
> -   and force_fit_type_double.
> +/* The entry points in this file are fold, size_int_wide and size_binop.
>
>    fold takes a tree as argument and returns a simplified tree.
>
> @@ -39,10 +38,6 @@
>    size_int takes an integer value, and creates a tree constant
>    with type from `sizetype'.
>
> -   force_fit_type_double takes a constant, an overflowable flag and a
> -   prior overflow indicator.  It forces the value to fit the type and
> -   sets TREE_OVERFLOW.
> -
>    Note: Since the folders get called on non-gimple code as well as
>    gimple code, we need to handle GIMPLE tuples as well as their
>    corresponding tree equivalents.  */
> @@ -141,7 +136,7 @@
>  static tree fold_div_compare (location_t, enum tree_code, tree, tree, tree);
>  static bool reorder_operands_p (const_tree, const_tree);
>  static tree fold_negate_const (tree, tree);
> -static tree fold_not_const (tree, tree);
> +static tree fold_not_const (const_tree, tree);
>  static tree fold_relational_const (enum tree_code, tree, tree, tree);
>  static tree fold_convert_const (enum tree_code, tree, tree);
>
> @@ -1077,7 +1072,7 @@
>        }
>     }
>   else
> -    t = force_fit_type_double (TREE_TYPE (arg1), res.low, res.high, 1,
> +    t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
>                               ((!uns || is_sizetype) && overflow)
>                               | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
>
> @@ -1521,8 +1516,7 @@
>
>   /* Given an integer constant, make new constant with new type,
>      appropriately sign-extended or truncated.  */
> -  t = force_fit_type_double (type, TREE_INT_CST_LOW (arg1),
> -                            TREE_INT_CST_HIGH (arg1),
> +  t = force_fit_type_double (type, tree_to_double_int (arg1),
>                             !POINTER_TYPE_P (TREE_TYPE (arg1)),
>                             (TREE_INT_CST_HIGH (arg1) < 0
>                              && (TYPE_UNSIGNED (type)
> @@ -1602,8 +1596,7 @@
>   if (! overflow)
>     real_to_integer2 ((HOST_WIDE_INT *) &val.low, &val.high, &r);
>
> -  t = force_fit_type_double (type, val.low, val.high, -1,
> -                            overflow | TREE_OVERFLOW (arg1));
> +  t = force_fit_type_double (type, val, -1, overflow | TREE_OVERFLOW (arg1));
>   return t;
>  }
>
> @@ -1646,7 +1639,7 @@
>
>   /* Given a fixed-point constant, make new constant with new type,
>      appropriately sign-extended or truncated.  */
> -  t = force_fit_type_double (type, temp.low, temp.high, -1,
> +  t = force_fit_type_double (type, temp, -1,
>                             (double_int_negative_p (temp)
>                              && (TYPE_UNSIGNED (type)
>                                  < TYPE_UNSIGNED (TREE_TYPE (arg1))))
> @@ -5963,8 +5956,7 @@
>          && 0 != (t1 = int_const_binop (MULT_EXPR,
>                                         fold_convert (ctype, op1),
>                                         fold_convert (ctype, c), 1))
> -         && 0 != (t1 = force_fit_type_double (ctype, TREE_INT_CST_LOW (t1),
> -                                              TREE_INT_CST_HIGH (t1),
> +         && 0 != (t1 = force_fit_type_double (ctype, tree_to_double_int (t1),
>                                               (TYPE_UNSIGNED (ctype)
>                                                && tcode != MULT_EXPR) ? -1 : 1,
>                                               TREE_OVERFLOW (t1)))
> @@ -6368,8 +6360,7 @@
>   tree prod, tmp, hi, lo;
>   tree arg00 = TREE_OPERAND (arg0, 0);
>   tree arg01 = TREE_OPERAND (arg0, 1);
> -  unsigned HOST_WIDE_INT lpart;
> -  HOST_WIDE_INT hpart;
> +  double_int val;
>   bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
>   bool neg_overflow;
>   int overflow;
> @@ -6380,9 +6371,8 @@
>                                   TREE_INT_CST_HIGH (arg01),
>                                   TREE_INT_CST_LOW (arg1),
>                                   TREE_INT_CST_HIGH (arg1),
> -                                  &lpart, &hpart, unsigned_p);
> -  prod = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
> -                               -1, overflow);
> +                                  &val.low, &val.high, unsigned_p);
> +  prod = force_fit_type_double (TREE_TYPE (arg00), val, -1, overflow);
>   neg_overflow = false;
>
>   if (unsigned_p)
> @@ -6396,8 +6386,8 @@
>                                       TREE_INT_CST_HIGH (prod),
>                                       TREE_INT_CST_LOW (tmp),
>                                       TREE_INT_CST_HIGH (tmp),
> -                                      &lpart, &hpart, unsigned_p);
> -      hi = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
> +                                      &val.low, &val.high, unsigned_p);
> +      hi = force_fit_type_double (TREE_TYPE (arg00), val,
>                                  -1, overflow | TREE_OVERFLOW (prod));
>     }
>   else if (tree_int_cst_sgn (arg01) >= 0)
> @@ -6850,9 +6840,8 @@
>     return NULL_TREE;
>
>   if (TREE_CODE (arg1) == INTEGER_CST)
> -    arg1 = force_fit_type_double (inner_type, TREE_INT_CST_LOW (arg1),
> -                                 TREE_INT_CST_HIGH (arg1), 0,
> -                                 TREE_OVERFLOW (arg1));
> +    arg1 = force_fit_type_double (inner_type, tree_to_double_int (arg1),
> +                                 0, TREE_OVERFLOW (arg1));
>   else
>     arg1 = fold_convert_loc (loc, inner_type, arg1);
>
> @@ -7957,9 +7946,8 @@
>            }
>          if (change)
>            {
> -             tem = force_fit_type_double (type, TREE_INT_CST_LOW (and1),
> -                                          TREE_INT_CST_HIGH (and1), 0,
> -                                          TREE_OVERFLOW (and1));
> +             tem = force_fit_type_double (type, tree_to_double_int (and1),
> +                                          0, TREE_OVERFLOW (and1));
>              return fold_build2_loc (loc, BIT_AND_EXPR, type,
>                                  fold_convert_loc (loc, type, and0), tem);
>            }
> @@ -15155,12 +15143,10 @@
>     {
>     case INTEGER_CST:
>       {
> -       unsigned HOST_WIDE_INT low;
> -       HOST_WIDE_INT high;
> -       int overflow = neg_double (TREE_INT_CST_LOW (arg0),
> -                                  TREE_INT_CST_HIGH (arg0),
> -                                  &low, &high);
> -       t = force_fit_type_double (type, low, high, 1,
> +       double_int val = tree_to_double_int (arg0);
> +       int overflow = neg_double (val.low, val.high, &val.low, &val.high);
> +
> +       t = force_fit_type_double (type, val, 1,
>                                   (overflow | TREE_OVERFLOW (arg0))
>                                   && !TYPE_UNSIGNED (type));
>        break;
> @@ -15203,25 +15189,26 @@
>   switch (TREE_CODE (arg0))
>     {
>     case INTEGER_CST:
> -      /* If the value is unsigned, then the absolute value is
> -        the same as the ordinary value.  */
> -      if (TYPE_UNSIGNED (type))
> -       t = arg0;
> -      /* Similarly, if the value is non-negative.  */
> -      else if (INT_CST_LT (integer_minus_one_node, arg0))
> -       t = arg0;
> -      /* If the value is negative, then the absolute value is
> -        its negation.  */
> -      else
> -       {
> -         unsigned HOST_WIDE_INT low;
> -         HOST_WIDE_INT high;
> -         int overflow = neg_double (TREE_INT_CST_LOW (arg0),
> -                                    TREE_INT_CST_HIGH (arg0),
> -                                    &low, &high);
> -         t = force_fit_type_double (type, low, high, -1,
> -                                    overflow | TREE_OVERFLOW (arg0));
> -       }
> +      {
> +       double_int val = tree_to_double_int (arg0);
> +
> +        /* If the value is unsigned or non-negative, then the absolute value
> +          is the same as the ordinary value.  */
> +       if (TYPE_UNSIGNED (type)
> +           || !double_int_negative_p (val))
> +         t = arg0;
> +
> +       /* If the value is negative, then the absolute value is
> +          its negation.  */
> +       else
> +         {
> +           int overflow;
> +
> +           overflow = neg_double (val.low, val.high, &val.low, &val.high);
> +           t = force_fit_type_double (type, val, -1,
> +                                      overflow | TREE_OVERFLOW (arg0));
> +         }
> +      }
>       break;
>
>     case REAL_CST:
> @@ -15242,17 +15229,14 @@
>    constant.  TYPE is the type of the result.  */
>
>  static tree
> -fold_not_const (tree arg0, tree type)
> +fold_not_const (const_tree arg0, tree type)
>  {
> -  tree t = NULL_TREE;
> +  double_int val;
>
>   gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
>
> -  t = force_fit_type_double (type, ~TREE_INT_CST_LOW (arg0),
> -                            ~TREE_INT_CST_HIGH (arg0), 0,
> -                            TREE_OVERFLOW (arg0));
> -
> -  return t;
> +  val = double_int_not (tree_to_double_int (arg0));
> +  return force_fit_type_double (type, val, 0, TREE_OVERFLOW (arg0));
>  }
>
>  /* Given CODE, a relational operator, the target type, TYPE and two
> @@ -15650,25 +15634,23 @@
>     {
>       if (TREE_CODE (value) == INTEGER_CST)
>        {
> -         unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (value);
> -         unsigned HOST_WIDE_INT high;
> +         double_int val = tree_to_double_int (value);
>          bool overflow_p;
>
> -         if ((low & (divisor - 1)) == 0)
> +         if ((val.low & (divisor - 1)) == 0)
>            return value;
>
>          overflow_p = TREE_OVERFLOW (value);
> -         high = TREE_INT_CST_HIGH (value);
> -         low &= ~(divisor - 1);
> -         low += divisor;
> -         if (low == 0)
> +         val.low &= ~(divisor - 1);
> +         val.low += divisor;
> +         if (val.low == 0)
>            {
> -             high++;
> -             if (high == 0)
> +             val.high++;
> +             if (val.high == 0)
>                overflow_p = true;
>            }
>
> -         return force_fit_type_double (TREE_TYPE (value), low, high,
> +         return force_fit_type_double (TREE_TYPE (value), val,
>                                        -1, overflow_p);
>        }
>       else
> Index: gcc/double-int.c
> ===================================================================
> --- gcc/double-int.c    (revision 161254)
> +++ gcc/double-int.c    (working copy)
> @@ -134,56 +134,6 @@
>   return l1 != low0 || h1 != high0;
>  }
>
> -/* We force the double-int HIGH:LOW to the range of the type TYPE by
> -   sign or zero extending it.
> -   OVERFLOWABLE indicates if we are interested
> -   in overflow of the value, when >0 we are only interested in signed
> -   overflow, for <0 we are interested in any overflow.  OVERFLOWED
> -   indicates whether overflow has already occurred.  CONST_OVERFLOWED
> -   indicates whether constant overflow has already occurred.  We force
> -   T's value to be within range of T's type (by setting to 0 or 1 all
> -   the bits outside the type's range).  We set TREE_OVERFLOWED if,
> -       OVERFLOWED is nonzero,
> -       or OVERFLOWABLE is >0 and signed overflow occurs
> -       or OVERFLOWABLE is <0 and any overflow occurs
> -   We return a new tree node for the extended double-int.  The node
> -   is shared if no overflow flags are set.  */
> -
> -tree
> -force_fit_type_double (tree type, unsigned HOST_WIDE_INT low,
> -                      HOST_WIDE_INT high, int overflowable,
> -                      bool overflowed)
> -{
> -  int sign_extended_type;
> -  bool overflow;
> -
> -  /* Size types *are* sign extended.  */
> -  sign_extended_type = (!TYPE_UNSIGNED (type)
> -                       || (TREE_CODE (type) == INTEGER_TYPE
> -                           && TYPE_IS_SIZETYPE (type)));
> -
> -  overflow = fit_double_type (low, high, &low, &high, type);
> -
> -  /* If we need to set overflow flags, return a new unshared node.  */
> -  if (overflowed || overflow)
> -    {
> -      if (overflowed
> -         || overflowable < 0
> -         || (overflowable > 0 && sign_extended_type))
> -       {
> -          tree t = make_node (INTEGER_CST);
> -          TREE_INT_CST_LOW (t) = low;
> -          TREE_INT_CST_HIGH (t) = high;
> -          TREE_TYPE (t) = type;
> -         TREE_OVERFLOW (t) = 1;
> -         return t;
> -       }
> -    }
> -
> -  /* Else build a shared node.  */
> -  return build_int_cst_wide (type, low, high);
> -}
> -
>  /* Add two doubleword integers with doubleword result.
>    Return nonzero if the operation overflows according to UNSIGNED_P.
>    Each argument is given as two `HOST_WIDE_INT' pieces.
> Index: gcc/double-int.h
> ===================================================================
> --- gcc/double-int.h    (revision 161254)
> +++ gcc/double-int.h    (working copy)
> @@ -269,8 +269,6 @@
>
>  /* Legacy interface with decomposed high/low parts.  */
>
> -extern tree force_fit_type_double (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT,
> -                                  int, bool);
>  extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
>                            unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
>                            const_tree);
> Index: gcc/convert.c
> ===================================================================
> --- gcc/convert.c       (revision 161254)
> +++ gcc/convert.c       (working copy)
> @@ -46,7 +46,8 @@
>
>   /* Propagate overflow to the NULL pointer.  */
>   if (integer_zerop (expr))
> -    return force_fit_type_double (type, 0, 0, 0, TREE_OVERFLOW (expr));
> +    return force_fit_type_double (type, double_int_zero, 0,
> +                                 TREE_OVERFLOW (expr));
>
>   switch (TREE_CODE (TREE_TYPE (expr)))
>     {
>
>
> Anatoly.
>
>
diff mbox

Patch

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c      (revision 161254)
+++ gcc/tree-vrp.c      (working copy)
@@ -1507,10 +1507,10 @@ 
       /* Make sure to not set TREE_OVERFLOW on the final type
         conversion.  We are willingly interpreting large positive
         unsigned values as negative singed values here.  */
-      min = force_fit_type_double (TREE_TYPE (var), TREE_INT_CST_LOW (min),
-                                  TREE_INT_CST_HIGH (min), 0, false);
-      max = force_fit_type_double (TREE_TYPE (var), TREE_INT_CST_LOW (max),
-                                  TREE_INT_CST_HIGH (max), 0, false);
+      min = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (min),
+                                  0, false);
+      max = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (max),
+                                  0, false);
 
       /* We can transform a max, min range to an anti-range or
          vice-versa.  Use set_and_canonicalize_value_range which does
@@ -2783,11 +2783,11 @@ 
        {
          tree new_min, new_max;
          new_min = force_fit_type_double (outer_type,
-                                          TREE_INT_CST_LOW (vr0.min),
-                                          TREE_INT_CST_HIGH (vr0.min), 0, 0);
+                                          tree_to_double_int (vr0.min),
+                                          0, false);
          new_max = force_fit_type_double (outer_type,
-                                          TREE_INT_CST_LOW (vr0.max),
-                                          TREE_INT_CST_HIGH (vr0.max), 0, 0);
+                                          tree_to_double_int (vr0.max),
+                                          0, false);
          if (is_overflow_infinity (vr0.min))
            new_min = negative_overflow_infinity (outer_type);
          if (is_overflow_infinity (vr0.max))
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c     (revision 161254)
+++ gcc/c-family/c-common.c     (working copy)
@@ -3361,9 +3361,8 @@ 
          /* Convert primop1 to target type, but do not introduce
             additional overflow.  We know primop1 is an int_cst.  */
          primop1 = force_fit_type_double (*restype_ptr,
-                                          TREE_INT_CST_LOW (primop1),
-                                          TREE_INT_CST_HIGH (primop1), 0,
-                                          TREE_OVERFLOW (primop1));
+                                          tree_to_double_int (primop1),
+                                          0, TREE_OVERFLOW (primop1));
        }
       if (type != *restype_ptr)
        {
Index: gcc/tree.c
===================================================================
--- gcc/tree.c  (revision 161254)
+++ gcc/tree.c  (working copy)
@@ -1092,6 +1092,52 @@ 
   return double_int_equal_p (cst, ext);
 }
 
+/* We force the double_int CST to the range of the type TYPE by sign or
+   zero extending it.  OVERFLOWABLE indicates if we are interested in
+   overflow of the value, when >0 we are only interested in signed
+   overflow, for <0 we are interested in any overflow.  OVERFLOWED
+   indicates whether overflow has already occurred.  CONST_OVERFLOWED
+   indicates whether constant overflow has already occurred.  We force
+   T's value to be within range of T's type (by setting to 0 or 1 all
+   the bits outside the type's range).  We set TREE_OVERFLOWED if,
+        OVERFLOWED is nonzero,
+        or OVERFLOWABLE is >0 and signed overflow occurs
+        or OVERFLOWABLE is <0 and any overflow occurs
+   We return a new tree node for the extended double_int.  The node
+   is shared if no overflow flags are set.  */
+
+
+tree
+force_fit_type_double (tree type, double_int cst, int overflowable,
+                      bool overflowed)
+{
+  bool sign_extended_type;
+
+  /* Size types *are* sign extended.  */
+  sign_extended_type = (!TYPE_UNSIGNED (type)
+                        || (TREE_CODE (type) == INTEGER_TYPE
+                            && TYPE_IS_SIZETYPE (type)));
+
+  /* If we need to set overflow flags, return a new unshared node.  */
+  if (overflowed || !double_int_fits_to_tree_p(type, cst))
+    {
+      if (overflowed
+         || overflowable < 0
+         || (overflowable > 0 && sign_extended_type))
+       {
+         tree t = make_node (INTEGER_CST);
+         TREE_INT_CST (t) = double_int_ext (cst, TYPE_PRECISION (type),
+                                            !sign_extended_type);
+         TREE_TYPE (t) = type;
+         TREE_OVERFLOW (t) = 1;
+         return t;
+       }
+    }
+
+  /* Else build a shared node.  */
+  return double_int_to_tree (type, cst);
+}
+
 /* These are the hash table functions for the hash table of INTEGER_CST
    nodes of a sizetype.  */
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h  (revision 161254)
+++ gcc/tree.h  (working copy)
@@ -4014,6 +4014,7 @@ 
 
 extern tree double_int_to_tree (tree, double_int);
 extern bool double_int_fits_to_tree_p (const_tree, double_int);
+extern tree force_fit_type_double (tree, double_int, int, bool);
 
 /* Create an INT_CST node with a CST value zero extended.  */
 
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 161254)
+++ gcc/fold-const.c    (working copy)
@@ -27,8 +27,7 @@ 
   @@ This would also make life easier when this technology is used
   @@ for cross-compilers.  */
 
-/* The entry points in this file are fold, size_int_wide, size_binop
-   and force_fit_type_double.
+/* The entry points in this file are fold, size_int_wide and size_binop.
 
    fold takes a tree as argument and returns a simplified tree.
 
@@ -39,10 +38,6 @@ 
    size_int takes an integer value, and creates a tree constant
    with type from `sizetype'.
 
-   force_fit_type_double takes a constant, an overflowable flag and a
-   prior overflow indicator.  It forces the value to fit the type and
-   sets TREE_OVERFLOW.
-
    Note: Since the folders get called on non-gimple code as well as
    gimple code, we need to handle GIMPLE tuples as well as their
    corresponding tree equivalents.  */
@@ -141,7 +136,7 @@ 
 static tree fold_div_compare (location_t, enum tree_code, tree, tree, tree);
 static bool reorder_operands_p (const_tree, const_tree);
 static tree fold_negate_const (tree, tree);
-static tree fold_not_const (tree, tree);
+static tree fold_not_const (const_tree, tree);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
 static tree fold_convert_const (enum tree_code, tree, tree);
 
@@ -1077,7 +1072,7 @@ 
        }
     }
   else
-    t = force_fit_type_double (TREE_TYPE (arg1), res.low, res.high, 1,
+    t = force_fit_type_double (TREE_TYPE (arg1), res, 1,
                               ((!uns || is_sizetype) && overflow)
                               | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
 
@@ -1521,8 +1516,7 @@ 
 
   /* Given an integer constant, make new constant with new type,
      appropriately sign-extended or truncated.  */
-  t = force_fit_type_double (type, TREE_INT_CST_LOW (arg1),
-                            TREE_INT_CST_HIGH (arg1),
+  t = force_fit_type_double (type, tree_to_double_int (arg1),
                             !POINTER_TYPE_P (TREE_TYPE (arg1)),
                             (TREE_INT_CST_HIGH (arg1) < 0
                              && (TYPE_UNSIGNED (type)
@@ -1602,8 +1596,7 @@ 
   if (! overflow)
     real_to_integer2 ((HOST_WIDE_INT *) &val.low, &val.high, &r);
 
-  t = force_fit_type_double (type, val.low, val.high, -1,
-                            overflow | TREE_OVERFLOW (arg1));
+  t = force_fit_type_double (type, val, -1, overflow | TREE_OVERFLOW (arg1));
   return t;
 }
 
@@ -1646,7 +1639,7 @@ 
 
   /* Given a fixed-point constant, make new constant with new type,
      appropriately sign-extended or truncated.  */
-  t = force_fit_type_double (type, temp.low, temp.high, -1,
+  t = force_fit_type_double (type, temp, -1,
                             (double_int_negative_p (temp)
                              && (TYPE_UNSIGNED (type)
                                  < TYPE_UNSIGNED (TREE_TYPE (arg1))))
@@ -5963,8 +5956,7 @@ 
          && 0 != (t1 = int_const_binop (MULT_EXPR,
                                         fold_convert (ctype, op1),
                                         fold_convert (ctype, c), 1))
-         && 0 != (t1 = force_fit_type_double (ctype, TREE_INT_CST_LOW (t1),
-                                              TREE_INT_CST_HIGH (t1),
+         && 0 != (t1 = force_fit_type_double (ctype, tree_to_double_int (t1),
                                               (TYPE_UNSIGNED (ctype)
                                                && tcode != MULT_EXPR) ? -1 : 1,
                                               TREE_OVERFLOW (t1)))
@@ -6368,8 +6360,7 @@ 
   tree prod, tmp, hi, lo;
   tree arg00 = TREE_OPERAND (arg0, 0);
   tree arg01 = TREE_OPERAND (arg0, 1);
-  unsigned HOST_WIDE_INT lpart;
-  HOST_WIDE_INT hpart;
+  double_int val;
   bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
   bool neg_overflow;
   int overflow;
@@ -6380,9 +6371,8 @@ 
                                   TREE_INT_CST_HIGH (arg01),
                                   TREE_INT_CST_LOW (arg1),
                                   TREE_INT_CST_HIGH (arg1),
-                                  &lpart, &hpart, unsigned_p);
-  prod = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
-                               -1, overflow);
+                                  &val.low, &val.high, unsigned_p);
+  prod = force_fit_type_double (TREE_TYPE (arg00), val, -1, overflow);
   neg_overflow = false;
 
   if (unsigned_p)
@@ -6396,8 +6386,8 @@ 
                                       TREE_INT_CST_HIGH (prod),
                                       TREE_INT_CST_LOW (tmp),
                                       TREE_INT_CST_HIGH (tmp),
-                                      &lpart, &hpart, unsigned_p);
-      hi = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
+                                      &val.low, &val.high, unsigned_p);
+      hi = force_fit_type_double (TREE_TYPE (arg00), val,
                                  -1, overflow | TREE_OVERFLOW (prod));
     }
   else if (tree_int_cst_sgn (arg01) >= 0)
@@ -6850,9 +6840,8 @@ 
     return NULL_TREE;
 
   if (TREE_CODE (arg1) == INTEGER_CST)
-    arg1 = force_fit_type_double (inner_type, TREE_INT_CST_LOW (arg1),
-                                 TREE_INT_CST_HIGH (arg1), 0,
-                                 TREE_OVERFLOW (arg1));
+    arg1 = force_fit_type_double (inner_type, tree_to_double_int (arg1),
+                                 0, TREE_OVERFLOW (arg1));
   else
     arg1 = fold_convert_loc (loc, inner_type, arg1);
 
@@ -7957,9 +7946,8 @@ 
            }
          if (change)
            {
-             tem = force_fit_type_double (type, TREE_INT_CST_LOW (and1),
-                                          TREE_INT_CST_HIGH (and1), 0,
-                                          TREE_OVERFLOW (and1));
+             tem = force_fit_type_double (type, tree_to_double_int (and1),
+                                          0, TREE_OVERFLOW (and1));
              return fold_build2_loc (loc, BIT_AND_EXPR, type,
                                  fold_convert_loc (loc, type, and0), tem);
            }
@@ -15155,12 +15143,10 @@ 
     {
     case INTEGER_CST:
       {
-       unsigned HOST_WIDE_INT low;
-       HOST_WIDE_INT high;
-       int overflow = neg_double (TREE_INT_CST_LOW (arg0),
-                                  TREE_INT_CST_HIGH (arg0),
-                                  &low, &high);
-       t = force_fit_type_double (type, low, high, 1,
+       double_int val = tree_to_double_int (arg0);
+       int overflow = neg_double (val.low, val.high, &val.low, &val.high);
+
+       t = force_fit_type_double (type, val, 1,
                                   (overflow | TREE_OVERFLOW (arg0))
                                   && !TYPE_UNSIGNED (type));
        break;
@@ -15203,25 +15189,26 @@ 
   switch (TREE_CODE (arg0))
     {
     case INTEGER_CST:
-      /* If the value is unsigned, then the absolute value is
-        the same as the ordinary value.  */
-      if (TYPE_UNSIGNED (type))
-       t = arg0;
-      /* Similarly, if the value is non-negative.  */
-      else if (INT_CST_LT (integer_minus_one_node, arg0))
-       t = arg0;
-      /* If the value is negative, then the absolute value is
-        its negation.  */
-      else
-       {
-         unsigned HOST_WIDE_INT low;
-         HOST_WIDE_INT high;
-         int overflow = neg_double (TREE_INT_CST_LOW (arg0),
-                                    TREE_INT_CST_HIGH (arg0),
-                                    &low, &high);
-         t = force_fit_type_double (type, low, high, -1,
-                                    overflow | TREE_OVERFLOW (arg0));
-       }
+      {
+       double_int val = tree_to_double_int (arg0);
+
+        /* If the value is unsigned or non-negative, then the absolute value
+          is the same as the ordinary value.  */
+       if (TYPE_UNSIGNED (type)
+           || !double_int_negative_p (val))
+         t = arg0;
+
+       /* If the value is negative, then the absolute value is
+          its negation.  */
+       else
+         {
+           int overflow;
+
+           overflow = neg_double (val.low, val.high, &val.low, &val.high);
+           t = force_fit_type_double (type, val, -1,
+                                      overflow | TREE_OVERFLOW (arg0));
+         }
+      }
       break;
 
     case REAL_CST:
@@ -15242,17 +15229,14 @@ 
    constant.  TYPE is the type of the result.  */
 
 static tree
-fold_not_const (tree arg0, tree type)
+fold_not_const (const_tree arg0, tree type)
 {
-  tree t = NULL_TREE;
+  double_int val;  
 
   gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
 
-  t = force_fit_type_double (type, ~TREE_INT_CST_LOW (arg0),
-                            ~TREE_INT_CST_HIGH (arg0), 0,
-                            TREE_OVERFLOW (arg0));
-
-  return t;
+  val = double_int_not (tree_to_double_int (arg0));
+  return force_fit_type_double (type, val, 0, TREE_OVERFLOW (arg0));
 }
 
 /* Given CODE, a relational operator, the target type, TYPE and two
@@ -15650,25 +15634,23 @@ 
     {
       if (TREE_CODE (value) == INTEGER_CST)
        {
-         unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (value);
-         unsigned HOST_WIDE_INT high;
+         double_int val = tree_to_double_int (value);
          bool overflow_p;
 
-         if ((low & (divisor - 1)) == 0)
+         if ((val.low & (divisor - 1)) == 0)
            return value;
 
          overflow_p = TREE_OVERFLOW (value);
-         high = TREE_INT_CST_HIGH (value);
-         low &= ~(divisor - 1);
-         low += divisor;
-         if (low == 0)
+         val.low &= ~(divisor - 1);
+         val.low += divisor;
+         if (val.low == 0)
            {
-             high++;
-             if (high == 0)
+             val.high++;
+             if (val.high == 0)
                overflow_p = true;
            }
 
-         return force_fit_type_double (TREE_TYPE (value), low, high,
+         return force_fit_type_double (TREE_TYPE (value), val,
                                        -1, overflow_p);
        }
       else
Index: gcc/double-int.c
===================================================================
--- gcc/double-int.c    (revision 161254)
+++ gcc/double-int.c    (working copy)
@@ -134,56 +134,6 @@ 
   return l1 != low0 || h1 != high0;
 }
 
-/* We force the double-int HIGH:LOW to the range of the type TYPE by
-   sign or zero extending it.
-   OVERFLOWABLE indicates if we are interested
-   in overflow of the value, when >0 we are only interested in signed
-   overflow, for <0 we are interested in any overflow.  OVERFLOWED
-   indicates whether overflow has already occurred.  CONST_OVERFLOWED
-   indicates whether constant overflow has already occurred.  We force
-   T's value to be within range of T's type (by setting to 0 or 1 all
-   the bits outside the type's range).  We set TREE_OVERFLOWED if,
-       OVERFLOWED is nonzero,
-       or OVERFLOWABLE is >0 and signed overflow occurs
-       or OVERFLOWABLE is <0 and any overflow occurs
-   We return a new tree node for the extended double-int.  The node
-   is shared if no overflow flags are set.  */
-
-tree
-force_fit_type_double (tree type, unsigned HOST_WIDE_INT low,
-                      HOST_WIDE_INT high, int overflowable,
-                      bool overflowed)
-{
-  int sign_extended_type;
-  bool overflow;
-
-  /* Size types *are* sign extended.  */
-  sign_extended_type = (!TYPE_UNSIGNED (type)
-                       || (TREE_CODE (type) == INTEGER_TYPE
-                           && TYPE_IS_SIZETYPE (type)));
-
-  overflow = fit_double_type (low, high, &low, &high, type);
-
-  /* If we need to set overflow flags, return a new unshared node.  */
-  if (overflowed || overflow)
-    {
-      if (overflowed
-         || overflowable < 0
-         || (overflowable > 0 && sign_extended_type))
-       {
-          tree t = make_node (INTEGER_CST);
-          TREE_INT_CST_LOW (t) = low;
-          TREE_INT_CST_HIGH (t) = high;
-          TREE_TYPE (t) = type;
-         TREE_OVERFLOW (t) = 1;
-         return t;
-       }
-    }
-
-  /* Else build a shared node.  */
-  return build_int_cst_wide (type, low, high);
-}
-
 /* Add two doubleword integers with doubleword result.
    Return nonzero if the operation overflows according to UNSIGNED_P.
    Each argument is given as two `HOST_WIDE_INT' pieces.
Index: gcc/double-int.h
===================================================================
--- gcc/double-int.h    (revision 161254)
+++ gcc/double-int.h    (working copy)
@@ -269,8 +269,6 @@ 
 
 /* Legacy interface with decomposed high/low parts.  */
 
-extern tree force_fit_type_double (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT,
-                                  int, bool);
 extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
                            unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
                            const_tree);
Index: gcc/convert.c
===================================================================
--- gcc/convert.c       (revision 161254)
+++ gcc/convert.c       (working copy)
@@ -46,7 +46,8 @@ 
 
   /* Propagate overflow to the NULL pointer.  */
   if (integer_zerop (expr))
-    return force_fit_type_double (type, 0, 0, 0, TREE_OVERFLOW (expr));
+    return force_fit_type_double (type, double_int_zero, 0,
+                                 TREE_OVERFLOW (expr));
 
   switch (TREE_CODE (TREE_TYPE (expr)))
     {