diff mbox

Add a wi::to_wide helper function

Message ID 87h9ekfvec.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford April 29, 2016, 12:32 p.m. UTC
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?

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.

Comments

Richard Biener May 2, 2016, 8:51 a.m. UTC | #1
On Fri, Apr 29, 2016 at 2:32 PM, Richard Sandiford
<richard.sandiford@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)
diff mbox

Patch

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)