Commit 9589f23e by Anatoly Sokolov Committed by Anatoly Sokolov

double-int.h (force_fit_type_double): Remove declaration.

	* 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.

From-SVN: r161509
parent dfecaf59
2010-06-28 Anatoly Sokolov <aesok@post.ru>
* 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.
2010-06-28 Philipp Tomsich <philipp.tomsich@theobroma-systems.com> 2010-06-28 Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
* config/rs6000/rs6000.h (PROCESSOR_TITAN): Declare. * config/rs6000/rs6000.h (PROCESSOR_TITAN): Declare.
......
2010-06-28 Anatoly Sokolov <aesok@post.ru>
* c-common.c (shorten_compare): Adjust call to force_fit_type_double.
2010-06-28 Steven Bosscher <steven@gcc.gnu.org> 2010-06-28 Steven Bosscher <steven@gcc.gnu.org>
* c-cppbuiltin.c: Do not include except.h. * c-cppbuiltin.c: Do not include except.h.
......
...@@ -3361,9 +3361,8 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, ...@@ -3361,9 +3361,8 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_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_double (*restype_ptr, primop1 = force_fit_type_double (*restype_ptr,
TREE_INT_CST_LOW (primop1), tree_to_double_int (primop1),
TREE_INT_CST_HIGH (primop1), 0, 0, TREE_OVERFLOW (primop1));
TREE_OVERFLOW (primop1));
} }
if (type != *restype_ptr) if (type != *restype_ptr)
{ {
......
...@@ -46,7 +46,8 @@ convert_to_pointer (tree type, tree expr) ...@@ -46,7 +46,8 @@ convert_to_pointer (tree type, tree expr)
/* Propagate overflow to the NULL pointer. */ /* Propagate overflow to the NULL pointer. */
if (integer_zerop (expr)) 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))) switch (TREE_CODE (TREE_TYPE (expr)))
{ {
......
...@@ -134,56 +134,6 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, ...@@ -134,56 +134,6 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
return l1 != low0 || h1 != high0; 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. /* Add two doubleword integers with doubleword result.
Return nonzero if the operation overflows according to UNSIGNED_P. Return nonzero if the operation overflows according to UNSIGNED_P.
Each argument is given as two `HOST_WIDE_INT' pieces. Each argument is given as two `HOST_WIDE_INT' pieces.
......
...@@ -269,8 +269,6 @@ double_int_equal_p (double_int cst1, double_int cst2) ...@@ -269,8 +269,6 @@ double_int_equal_p (double_int cst1, double_int cst2)
/* Legacy interface with decomposed high/low parts. */ /* 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, extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *,
const_tree); const_tree);
......
...@@ -27,8 +27,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -27,8 +27,7 @@ along with GCC; see the file COPYING3. If not see
@@ This would also make life easier when this technology is used @@ This would also make life easier when this technology is used
@@ for cross-compilers. */ @@ for cross-compilers. */
/* The entry points in this file are fold, size_int_wide, size_binop /* The entry points in this file are fold, size_int_wide and size_binop.
and force_fit_type_double.
fold takes a tree as argument and returns a simplified tree. fold takes a tree as argument and returns a simplified tree.
...@@ -39,10 +38,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -39,10 +38,6 @@ along with GCC; see the file COPYING3. If not see
size_int takes an integer value, and creates a tree constant size_int takes an integer value, and creates a tree constant
with type from `sizetype'. 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 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 gimple code, we need to handle GIMPLE tuples as well as their
corresponding tree equivalents. */ corresponding tree equivalents. */
...@@ -141,7 +136,7 @@ static tree fold_inf_compare (location_t, enum tree_code, tree, tree, tree); ...@@ -141,7 +136,7 @@ static tree fold_inf_compare (location_t, enum tree_code, tree, tree, tree);
static tree fold_div_compare (location_t, enum tree_code, tree, tree, tree); static tree fold_div_compare (location_t, enum tree_code, tree, tree, tree);
static bool reorder_operands_p (const_tree, const_tree); static bool reorder_operands_p (const_tree, const_tree);
static tree fold_negate_const (tree, 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_relational_const (enum tree_code, tree, tree, tree);
static tree fold_convert_const (enum tree_code, tree, tree); static tree fold_convert_const (enum tree_code, tree, tree);
...@@ -1077,7 +1072,7 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notr ...@@ -1077,7 +1072,7 @@ int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2, int notr
} }
} }
else 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) ((!uns || is_sizetype) && overflow)
| TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)); | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
...@@ -1510,8 +1505,7 @@ fold_convert_const_int_from_int (tree type, const_tree arg1) ...@@ -1510,8 +1505,7 @@ fold_convert_const_int_from_int (tree type, const_tree arg1)
/* Given an integer constant, make new constant with new type, /* Given an integer constant, make new constant with new type,
appropriately sign-extended or truncated. */ appropriately sign-extended or truncated. */
t = force_fit_type_double (type, TREE_INT_CST_LOW (arg1), t = force_fit_type_double (type, tree_to_double_int (arg1),
TREE_INT_CST_HIGH (arg1),
!POINTER_TYPE_P (TREE_TYPE (arg1)), !POINTER_TYPE_P (TREE_TYPE (arg1)),
(TREE_INT_CST_HIGH (arg1) < 0 (TREE_INT_CST_HIGH (arg1) < 0
&& (TYPE_UNSIGNED (type) && (TYPE_UNSIGNED (type)
...@@ -1591,8 +1585,7 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg ...@@ -1591,8 +1585,7 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, const_tree arg
if (! overflow) if (! overflow)
real_to_integer2 ((HOST_WIDE_INT *) &val.low, &val.high, &r); real_to_integer2 ((HOST_WIDE_INT *) &val.low, &val.high, &r);
t = force_fit_type_double (type, val.low, val.high, -1, t = force_fit_type_double (type, val, -1, overflow | TREE_OVERFLOW (arg1));
overflow | TREE_OVERFLOW (arg1));
return t; return t;
} }
...@@ -1635,7 +1628,7 @@ fold_convert_const_int_from_fixed (tree type, const_tree arg1) ...@@ -1635,7 +1628,7 @@ fold_convert_const_int_from_fixed (tree type, const_tree arg1)
/* Given a fixed-point constant, make new constant with new type, /* Given a fixed-point constant, make new constant with new type,
appropriately sign-extended or truncated. */ 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) (double_int_negative_p (temp)
&& (TYPE_UNSIGNED (type) && (TYPE_UNSIGNED (type)
< TYPE_UNSIGNED (TREE_TYPE (arg1)))) < TYPE_UNSIGNED (TREE_TYPE (arg1))))
...@@ -5947,8 +5940,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type, ...@@ -5947,8 +5940,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
&& 0 != (t1 = int_const_binop (MULT_EXPR, && 0 != (t1 = int_const_binop (MULT_EXPR,
fold_convert (ctype, op1), fold_convert (ctype, op1),
fold_convert (ctype, c), 1)) fold_convert (ctype, c), 1))
&& 0 != (t1 = force_fit_type_double (ctype, TREE_INT_CST_LOW (t1), && 0 != (t1 = force_fit_type_double (ctype, tree_to_double_int (t1),
TREE_INT_CST_HIGH (t1),
(TYPE_UNSIGNED (ctype) (TYPE_UNSIGNED (ctype)
&& tcode != MULT_EXPR) ? -1 : 1, && tcode != MULT_EXPR) ? -1 : 1,
TREE_OVERFLOW (t1))) TREE_OVERFLOW (t1)))
...@@ -6352,8 +6344,7 @@ fold_div_compare (location_t loc, ...@@ -6352,8 +6344,7 @@ fold_div_compare (location_t loc,
tree prod, tmp, hi, lo; tree prod, tmp, hi, lo;
tree arg00 = TREE_OPERAND (arg0, 0); tree arg00 = TREE_OPERAND (arg0, 0);
tree arg01 = TREE_OPERAND (arg0, 1); tree arg01 = TREE_OPERAND (arg0, 1);
unsigned HOST_WIDE_INT lpart; double_int val;
HOST_WIDE_INT hpart;
bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0)); bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
bool neg_overflow; bool neg_overflow;
int overflow; int overflow;
...@@ -6364,9 +6355,8 @@ fold_div_compare (location_t loc, ...@@ -6364,9 +6355,8 @@ fold_div_compare (location_t loc,
TREE_INT_CST_HIGH (arg01), TREE_INT_CST_HIGH (arg01),
TREE_INT_CST_LOW (arg1), TREE_INT_CST_LOW (arg1),
TREE_INT_CST_HIGH (arg1), TREE_INT_CST_HIGH (arg1),
&lpart, &hpart, unsigned_p); &val.low, &val.high, unsigned_p);
prod = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart, prod = force_fit_type_double (TREE_TYPE (arg00), val, -1, overflow);
-1, overflow);
neg_overflow = false; neg_overflow = false;
if (unsigned_p) if (unsigned_p)
...@@ -6380,8 +6370,8 @@ fold_div_compare (location_t loc, ...@@ -6380,8 +6370,8 @@ fold_div_compare (location_t loc,
TREE_INT_CST_HIGH (prod), TREE_INT_CST_HIGH (prod),
TREE_INT_CST_LOW (tmp), TREE_INT_CST_LOW (tmp),
TREE_INT_CST_HIGH (tmp), TREE_INT_CST_HIGH (tmp),
&lpart, &hpart, unsigned_p); &val.low, &val.high, unsigned_p);
hi = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart, hi = force_fit_type_double (TREE_TYPE (arg00), val,
-1, overflow | TREE_OVERFLOW (prod)); -1, overflow | TREE_OVERFLOW (prod));
} }
else if (tree_int_cst_sgn (arg01) >= 0) else if (tree_int_cst_sgn (arg01) >= 0)
...@@ -6834,9 +6824,8 @@ fold_sign_changed_comparison (location_t loc, enum tree_code code, tree type, ...@@ -6834,9 +6824,8 @@ fold_sign_changed_comparison (location_t loc, enum tree_code code, tree type,
return NULL_TREE; return NULL_TREE;
if (TREE_CODE (arg1) == INTEGER_CST) if (TREE_CODE (arg1) == INTEGER_CST)
arg1 = force_fit_type_double (inner_type, TREE_INT_CST_LOW (arg1), arg1 = force_fit_type_double (inner_type, tree_to_double_int (arg1),
TREE_INT_CST_HIGH (arg1), 0, 0, TREE_OVERFLOW (arg1));
TREE_OVERFLOW (arg1));
else else
arg1 = fold_convert_loc (loc, inner_type, arg1); arg1 = fold_convert_loc (loc, inner_type, arg1);
...@@ -7941,9 +7930,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0) ...@@ -7941,9 +7930,8 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
} }
if (change) if (change)
{ {
tem = force_fit_type_double (type, TREE_INT_CST_LOW (and1), tem = force_fit_type_double (type, tree_to_double_int (and1),
TREE_INT_CST_HIGH (and1), 0, 0, TREE_OVERFLOW (and1));
TREE_OVERFLOW (and1));
return fold_build2_loc (loc, BIT_AND_EXPR, type, return fold_build2_loc (loc, BIT_AND_EXPR, type,
fold_convert_loc (loc, type, and0), tem); fold_convert_loc (loc, type, and0), tem);
} }
...@@ -15139,12 +15127,10 @@ fold_negate_const (tree arg0, tree type) ...@@ -15139,12 +15127,10 @@ fold_negate_const (tree arg0, tree type)
{ {
case INTEGER_CST: case INTEGER_CST:
{ {
unsigned HOST_WIDE_INT low; double_int val = tree_to_double_int (arg0);
HOST_WIDE_INT high; int overflow = neg_double (val.low, val.high, &val.low, &val.high);
int overflow = neg_double (TREE_INT_CST_LOW (arg0),
TREE_INT_CST_HIGH (arg0), t = force_fit_type_double (type, val, 1,
&low, &high);
t = force_fit_type_double (type, low, high, 1,
(overflow | TREE_OVERFLOW (arg0)) (overflow | TREE_OVERFLOW (arg0))
&& !TYPE_UNSIGNED (type)); && !TYPE_UNSIGNED (type));
break; break;
...@@ -15187,25 +15173,26 @@ fold_abs_const (tree arg0, tree type) ...@@ -15187,25 +15173,26 @@ fold_abs_const (tree arg0, tree type)
switch (TREE_CODE (arg0)) switch (TREE_CODE (arg0))
{ {
case INTEGER_CST: case INTEGER_CST:
/* If the value is unsigned, then the absolute value is {
the same as the ordinary value. */ double_int val = tree_to_double_int (arg0);
if (TYPE_UNSIGNED (type))
t = arg0; /* If the value is unsigned or non-negative, then the absolute value
/* Similarly, if the value is non-negative. */ is the same as the ordinary value. */
else if (INT_CST_LT (integer_minus_one_node, arg0)) if (TYPE_UNSIGNED (type)
t = arg0; || !double_int_negative_p (val))
/* If the value is negative, then the absolute value is t = arg0;
its negation. */
else /* If the value is negative, then the absolute value is
{ its negation. */
unsigned HOST_WIDE_INT low; else
HOST_WIDE_INT high; {
int overflow = neg_double (TREE_INT_CST_LOW (arg0), int overflow;
TREE_INT_CST_HIGH (arg0),
&low, &high); overflow = neg_double (val.low, val.high, &val.low, &val.high);
t = force_fit_type_double (type, low, high, -1, t = force_fit_type_double (type, val, -1,
overflow | TREE_OVERFLOW (arg0)); overflow | TREE_OVERFLOW (arg0));
} }
}
break; break;
case REAL_CST: case REAL_CST:
...@@ -15226,17 +15213,14 @@ fold_abs_const (tree arg0, tree type) ...@@ -15226,17 +15213,14 @@ fold_abs_const (tree arg0, tree type)
constant. TYPE is the type of the result. */ constant. TYPE is the type of the result. */
static tree 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); gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
t = force_fit_type_double (type, ~TREE_INT_CST_LOW (arg0), val = double_int_not (tree_to_double_int (arg0));
~TREE_INT_CST_HIGH (arg0), 0, return force_fit_type_double (type, val, 0, TREE_OVERFLOW (arg0));
TREE_OVERFLOW (arg0));
return t;
} }
/* Given CODE, a relational operator, the target type, TYPE and two /* Given CODE, a relational operator, the target type, TYPE and two
...@@ -15634,25 +15618,23 @@ round_up_loc (location_t loc, tree value, int divisor) ...@@ -15634,25 +15618,23 @@ round_up_loc (location_t loc, tree value, int divisor)
{ {
if (TREE_CODE (value) == INTEGER_CST) if (TREE_CODE (value) == INTEGER_CST)
{ {
unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (value); double_int val = tree_to_double_int (value);
unsigned HOST_WIDE_INT high;
bool overflow_p; bool overflow_p;
if ((low & (divisor - 1)) == 0) if ((val.low & (divisor - 1)) == 0)
return value; return value;
overflow_p = TREE_OVERFLOW (value); overflow_p = TREE_OVERFLOW (value);
high = TREE_INT_CST_HIGH (value); val.low &= ~(divisor - 1);
low &= ~(divisor - 1); val.low += divisor;
low += divisor; if (val.low == 0)
if (low == 0)
{ {
high++; val.high++;
if (high == 0) if (val.high == 0)
overflow_p = true; 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); -1, overflow_p);
} }
else else
......
...@@ -1511,10 +1511,10 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) ...@@ -1511,10 +1511,10 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
/* Make sure to not set TREE_OVERFLOW on the final type /* Make sure to not set TREE_OVERFLOW on the final type
conversion. We are willingly interpreting large positive conversion. We are willingly interpreting large positive
unsigned values as negative singed values here. */ unsigned values as negative singed values here. */
min = force_fit_type_double (TREE_TYPE (var), TREE_INT_CST_LOW (min), min = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (min),
TREE_INT_CST_HIGH (min), 0, false); 0, false);
max = force_fit_type_double (TREE_TYPE (var), TREE_INT_CST_LOW (max), max = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (max),
TREE_INT_CST_HIGH (max), 0, false); 0, false);
/* We can transform a max, min range to an anti-range or /* We can transform a max, min range to an anti-range or
vice-versa. Use set_and_canonicalize_value_range which does vice-versa. Use set_and_canonicalize_value_range which does
...@@ -2787,11 +2787,11 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code, ...@@ -2787,11 +2787,11 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
{ {
tree new_min, new_max; tree new_min, new_max;
new_min = force_fit_type_double (outer_type, new_min = force_fit_type_double (outer_type,
TREE_INT_CST_LOW (vr0.min), tree_to_double_int (vr0.min),
TREE_INT_CST_HIGH (vr0.min), 0, 0); 0, false);
new_max = force_fit_type_double (outer_type, new_max = force_fit_type_double (outer_type,
TREE_INT_CST_LOW (vr0.max), tree_to_double_int (vr0.max),
TREE_INT_CST_HIGH (vr0.max), 0, 0); 0, false);
if (is_overflow_infinity (vr0.min)) if (is_overflow_infinity (vr0.min))
new_min = negative_overflow_infinity (outer_type); new_min = negative_overflow_infinity (outer_type);
if (is_overflow_infinity (vr0.max)) if (is_overflow_infinity (vr0.max))
......
...@@ -1092,6 +1092,52 @@ double_int_fits_to_tree_p (const_tree type, double_int cst) ...@@ -1092,6 +1092,52 @@ double_int_fits_to_tree_p (const_tree type, double_int cst)
return double_int_equal_p (cst, ext); 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 /* These are the hash table functions for the hash table of INTEGER_CST
nodes of a sizetype. */ nodes of a sizetype. */
......
...@@ -4014,6 +4014,7 @@ tree_to_double_int (const_tree cst) ...@@ -4014,6 +4014,7 @@ tree_to_double_int (const_tree cst)
extern tree double_int_to_tree (tree, double_int); extern tree double_int_to_tree (tree, double_int);
extern bool double_int_fits_to_tree_p (const_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. */ /* Create an INT_CST node with a CST value zero extended. */
......
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