Commit 697e0b28 by Richard Sandiford Committed by Richard Sandiford

Add a wi::to_wide helper function

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.

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.

From-SVN: r235721
parent 8de73453
2016-05-02 Richard Sandiford <richard.sandiford@arm.com> 2016-05-02 Richard Sandiford <richard.sandiford@arm.com>
* 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.
2016-05-02 Richard Sandiford <richard.sandiford@arm.com>
* wide-int.h: Update offset_int and widest_int documentation. * wide-int.h: Update offset_int and widest_int documentation.
(WI_SIGNED_SHIFT_RESULT): New macro. (WI_SIGNED_SHIFT_RESULT): New macro.
(wi::binary_shift): Define signed_shift_result_type for (wi::binary_shift): Define signed_shift_result_type for
......
2016-05-02 Richard Sandiford <richard.sandiford@arm.com>
* c-common.c (shorten_compare): Use wi::to_wide.
2016-04-29 Cesar Philippidis <cesar@codesourcery.com> 2016-04-29 Cesar Philippidis <cesar@codesourcery.com>
PR middle-end/70626 PR middle-end/70626
......
...@@ -4012,10 +4012,9 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr, ...@@ -4012,10 +4012,9 @@ shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr,
/* Convert primop1 to target type, but do not introduce /* Convert primop1 to target type, but do not introduce
additional overflow. We know primop1 is an int_cst. */ additional overflow. We know primop1 is an int_cst. */
primop1 = force_fit_type (*restype_ptr, primop1 = force_fit_type (*restype_ptr,
wide_int::from wi::to_wide
(primop1, (primop1,
TYPE_PRECISION (*restype_ptr), TYPE_PRECISION (*restype_ptr)),
TYPE_SIGN (TREE_TYPE (primop1))),
0, TREE_OVERFLOW (primop1)); 0, TREE_OVERFLOW (primop1));
} }
if (type != *restype_ptr) if (type != *restype_ptr)
......
...@@ -9729,10 +9729,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, ...@@ -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 GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
the former to the latter according to the signedness of the the former to the latter according to the signedness of the
type. */ type. */
temp = immed_wide_int_const (wide_int::from temp = immed_wide_int_const (wi::to_wide
(exp, (exp,
GET_MODE_PRECISION (TYPE_MODE (type)), GET_MODE_PRECISION (TYPE_MODE (type))),
TYPE_SIGN (type)),
TYPE_MODE (type)); TYPE_MODE (type));
return temp; return temp;
......
...@@ -963,8 +963,7 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree parg2, ...@@ -963,8 +963,7 @@ int_const_binop_1 (enum tree_code code, const_tree arg1, const_tree parg2,
signop sign = TYPE_SIGN (type); signop sign = TYPE_SIGN (type);
bool overflow = false; bool overflow = false;
wide_int arg2 = wide_int::from (parg2, TYPE_PRECISION (type), wide_int arg2 = wi::to_wide (parg2, TYPE_PRECISION (type));
TYPE_SIGN (TREE_TYPE (parg2)));
switch (code) switch (code)
{ {
...@@ -6397,10 +6396,8 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, ...@@ -6397,10 +6396,8 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
bool overflow_mul_p; bool overflow_mul_p;
signop sign = TYPE_SIGN (ctype); signop sign = TYPE_SIGN (ctype);
unsigned prec = TYPE_PRECISION (ctype); unsigned prec = TYPE_PRECISION (ctype);
wide_int mul = wi::mul (wide_int::from (op1, prec, wide_int mul = wi::mul (wi::to_wide (op1, prec),
TYPE_SIGN (TREE_TYPE (op1))), wi::to_wide (c, prec),
wide_int::from (c, prec,
TYPE_SIGN (TREE_TYPE (c))),
sign, &overflow_mul_p); sign, &overflow_mul_p);
overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1); overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1);
if (overflow_mul_p if (overflow_mul_p
......
...@@ -5211,6 +5211,8 @@ namespace wi ...@@ -5211,6 +5211,8 @@ namespace wi
to_widest (const_tree); to_widest (const_tree);
generic_wide_int <extended_tree <ADDR_MAX_PRECISION> > to_offset (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 inline unsigned int
...@@ -5240,6 +5242,16 @@ wi::to_offset (const_tree t) ...@@ -5240,6 +5242,16 @@ wi::to_offset (const_tree t)
return 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> template <int N>
inline wi::extended_tree <N>::extended_tree (const_tree t) inline wi::extended_tree <N>::extended_tree (const_tree t)
: m_t (t) : m_t (t)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment