On Fri, Apr 29, 2016 at 2:32 PM, Richard Sandiford <richard.sandif...@arm.com> wrote: > As Richard says, we ought to have a convenient way of converting > an INTEGER_CST to a wide_int of a particular precision without > having to extract the sign of the INTEGER_CST's type each time. > This patch adds a wi::to_wide helper for that, alongside the > existing wi::to_offset and wi::to_widest. > > Tested on x86_64-linux-gnu and aarch64-linux-gnu. OK to install?
Ok. Thanks, Richard. > Thanks, > Richard > > > gcc/ > * tree.h (wi::to_wide): New function. > * expr.c (expand_expr_real_1): Use wi::to_wide. > * fold-const.c (int_const_binop_1): Likewise. > (extract_muldiv_1): Likewise. > > gcc/c-family/ > * c-common.c (shorten_compare): Use wi::to_wide. > > Index: gcc/tree.h > =================================================================== > --- gcc/tree.h > +++ gcc/tree.h > @@ -5211,6 +5211,8 @@ namespace wi > to_widest (const_tree); > > generic_wide_int <extended_tree <ADDR_MAX_PRECISION> > to_offset > (const_tree); > + > + wide_int to_wide (const_tree, unsigned int); > } > > inline unsigned int > @@ -5240,6 +5242,16 @@ wi::to_offset (const_tree t) > return t; > } > > +/* Convert INTEGER_CST T to a wide_int of precision PREC, extending or > + truncating as necessary. When extending, use sign extension if T's > + type is signed and zero extension if T's type is unsigned. */ > + > +inline wide_int > +wi::to_wide (const_tree t, unsigned int prec) > +{ > + return wide_int::from (t, prec, TYPE_SIGN (TREE_TYPE (t))); > +} > + > template <int N> > inline wi::extended_tree <N>::extended_tree (const_tree t) > : m_t (t) > Index: gcc/expr.c > =================================================================== > --- gcc/expr.c > +++ gcc/expr.c > @@ -9729,10 +9729,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode > tmode, > GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from > the former to the latter according to the signedness of the > type. */ > - temp = immed_wide_int_const (wide_int::from > + temp = immed_wide_int_const (wi::to_wide > (exp, > - GET_MODE_PRECISION (TYPE_MODE (type)), > - TYPE_SIGN (type)), > + GET_MODE_PRECISION (TYPE_MODE (type))), > TYPE_MODE (type)); > return temp; > > Index: gcc/fold-const.c > =================================================================== > --- gcc/fold-const.c > +++ gcc/fold-const.c > @@ -963,8 +963,7 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, > const_tree parg2, > signop sign = TYPE_SIGN (type); > bool overflow = false; > > - wide_int arg2 = wide_int::from (parg2, TYPE_PRECISION (type), > - TYPE_SIGN (TREE_TYPE (parg2))); > + wide_int arg2 = wi::to_wide (parg2, TYPE_PRECISION (type)); > > switch (code) > { > @@ -6394,10 +6393,8 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, > tree wide_type, > bool overflow_mul_p; > signop sign = TYPE_SIGN (ctype); > unsigned prec = TYPE_PRECISION (ctype); > - wide_int mul = wi::mul (wide_int::from (op1, prec, > - TYPE_SIGN (TREE_TYPE > (op1))), > - wide_int::from (c, prec, > - TYPE_SIGN (TREE_TYPE (c))), > + wide_int mul = wi::mul (wi::to_wide (op1, prec), > + wi::to_wide (c, prec), > sign, &overflow_mul_p); > overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1); > if (overflow_mul_p > Index: gcc/c-family/c-common.c > =================================================================== > --- gcc/c-family/c-common.c > +++ gcc/c-family/c-common.c > @@ -4012,10 +4012,9 @@ shorten_compare (location_t loc, tree *op0_ptr, tree > *op1_ptr, > /* Convert primop1 to target type, but do not introduce > additional overflow. We know primop1 is an int_cst. */ > primop1 = force_fit_type (*restype_ptr, > - wide_int::from > - (primop1, > - TYPE_PRECISION (*restype_ptr), > - TYPE_SIGN (TREE_TYPE (primop1))), > + wi::to_wide > + (primop1, > + TYPE_PRECISION (*restype_ptr)), > 0, TREE_OVERFLOW (primop1)); > } > if (type != *restype_ptr)