Commit 3232f052 by Richard Sandiford Committed by Richard Sandiford

Rework vrp_int_const_binop interface

...to avoid a warning about uninitialised wide_ints.

2017-11-06  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* tree-vrp.c (vrp_int_const_binop): Return true on success and
	return the value by pointer.
	(extract_range_from_multiplicative_op_1): Update accordingly.
	Return as soon as an operation fails.

From-SVN: r254436
parent 469f5da7
2017-11-06 Richard Sandiford <richard.sandiford@linaro.org>
* tree-vrp.c (vrp_int_const_binop): Return true on success and
return the value by pointer.
(extract_range_from_multiplicative_op_1): Update accordingly.
Return as soon as an operation fails.
2017-11-05 Tom de Vries <tom@codesourcery.com> 2017-11-05 Tom de Vries <tom@codesourcery.com>
PR other/82784 PR other/82784
...@@ -1602,21 +1602,20 @@ extract_range_from_ssa_name (value_range *vr, tree var) ...@@ -1602,21 +1602,20 @@ extract_range_from_ssa_name (value_range *vr, tree var)
} }
/* Wrapper around int_const_binop. If the operation overflows and /* Wrapper around int_const_binop. Return true if we can compute the
overflow is undefined, then adjust the result to be result; i.e. if the operation doesn't overflow or if the overflow is
-INF or +INF depending on CODE, VAL1 and VAL2. Sets *OVERFLOW_P undefined. In the latter case (if the operation overflows and
to whether the operation overflowed. For division by zero overflow is undefined), then adjust the result to be -INF or +INF
the result is indeterminate but *OVERFLOW_P is set. */ depending on CODE, VAL1 and VAL2. Return the value in *RES.
static wide_int Return false for division by zero, for which the result is
vrp_int_const_binop (enum tree_code code, tree val1, tree val2, indeterminate. */
bool *overflow_p)
static bool
vrp_int_const_binop (enum tree_code code, tree val1, tree val2, wide_int *res)
{ {
bool overflow = false; bool overflow = false;
signop sign = TYPE_SIGN (TREE_TYPE (val1)); signop sign = TYPE_SIGN (TREE_TYPE (val1));
wide_int res;
*overflow_p = false;
switch (code) switch (code)
{ {
...@@ -1637,57 +1636,45 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2, ...@@ -1637,57 +1636,45 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2,
/* It's unclear from the C standard whether shifts can overflow. /* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */ interpretation ruling is needed. */
res = wi::rshift (wi::to_wide (val1), wval2, sign); *res = wi::rshift (wi::to_wide (val1), wval2, sign);
else else
res = wi::lshift (wi::to_wide (val1), wval2); *res = wi::lshift (wi::to_wide (val1), wval2);
break; break;
} }
case MULT_EXPR: case MULT_EXPR:
res = wi::mul (wi::to_wide (val1), *res = wi::mul (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow); wi::to_wide (val2), sign, &overflow);
break; break;
case TRUNC_DIV_EXPR: case TRUNC_DIV_EXPR:
case EXACT_DIV_EXPR: case EXACT_DIV_EXPR:
if (val2 == 0) if (val2 == 0)
{ return false;
*overflow_p = true;
return res;
}
else else
res = wi::div_trunc (wi::to_wide (val1), *res = wi::div_trunc (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow); wi::to_wide (val2), sign, &overflow);
break; break;
case FLOOR_DIV_EXPR: case FLOOR_DIV_EXPR:
if (val2 == 0) if (val2 == 0)
{ return false;
*overflow_p = true; *res = wi::div_floor (wi::to_wide (val1),
return res; wi::to_wide (val2), sign, &overflow);
}
res = wi::div_floor (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break; break;
case CEIL_DIV_EXPR: case CEIL_DIV_EXPR:
if (val2 == 0) if (val2 == 0)
{ return false;
*overflow_p = true; *res = wi::div_ceil (wi::to_wide (val1),
return res; wi::to_wide (val2), sign, &overflow);
}
res = wi::div_ceil (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break; break;
case ROUND_DIV_EXPR: case ROUND_DIV_EXPR:
if (val2 == 0) if (val2 == 0)
{ return false;
*overflow_p = 0; *res = wi::div_round (wi::to_wide (val1),
return res; wi::to_wide (val2), sign, &overflow);
}
res = wi::div_round (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break; break;
default: default:
...@@ -1730,16 +1717,15 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2, ...@@ -1730,16 +1717,15 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2,
|| code == CEIL_DIV_EXPR || code == CEIL_DIV_EXPR
|| code == EXACT_DIV_EXPR || code == EXACT_DIV_EXPR
|| code == ROUND_DIV_EXPR) || code == ROUND_DIV_EXPR)
return wi::max_value (TYPE_PRECISION (TREE_TYPE (val1)), *res = wi::max_value (TYPE_PRECISION (TREE_TYPE (val1)),
TYPE_SIGN (TREE_TYPE (val1))); TYPE_SIGN (TREE_TYPE (val1)));
else else
return wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)), *res = wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)),
TYPE_SIGN (TREE_TYPE (val1))); TYPE_SIGN (TREE_TYPE (val1)));
return true;
} }
*overflow_p = overflow; return !overflow;
return res;
} }
...@@ -1835,7 +1821,6 @@ extract_range_from_multiplicative_op_1 (value_range *vr, ...@@ -1835,7 +1821,6 @@ extract_range_from_multiplicative_op_1 (value_range *vr,
{ {
enum value_range_type rtype; enum value_range_type rtype;
wide_int val, min, max; wide_int val, min, max;
bool sop;
tree type; tree type;
/* Multiplications, divisions and shifts are a bit tricky to handle, /* Multiplications, divisions and shifts are a bit tricky to handle,
...@@ -1866,58 +1851,50 @@ extract_range_from_multiplicative_op_1 (value_range *vr, ...@@ -1866,58 +1851,50 @@ extract_range_from_multiplicative_op_1 (value_range *vr,
signop sgn = TYPE_SIGN (type); signop sgn = TYPE_SIGN (type);
/* Compute the 4 cross operations and their minimum and maximum value. */ /* Compute the 4 cross operations and their minimum and maximum value. */
sop = false; if (!vrp_int_const_binop (code, vr0->min, vr1->min, &val))
val = vrp_int_const_binop (code, vr0->min, vr1->min, &sop);
if (! sop)
min = max = val;
if (vr1->max == vr1->min)
;
else if (! sop)
{ {
val = vrp_int_const_binop (code, vr0->min, vr1->max, &sop); set_value_range_to_varying (vr);
if (! sop) return;
{
if (wi::lt_p (val, min, sgn))
min = val;
else if (wi::gt_p (val, max, sgn))
max = val;
}
} }
min = max = val;
if (vr0->max == vr0->min) if (vr1->max != vr1->min)
;
else if (! sop)
{ {
val = vrp_int_const_binop (code, vr0->max, vr1->min, &sop); if (!vrp_int_const_binop (code, vr0->min, vr1->max, &val))
if (! sop)
{ {
if (wi::lt_p (val, min, sgn)) set_value_range_to_varying (vr);
min = val; return;
else if (wi::gt_p (val, max, sgn))
max = val;
} }
if (wi::lt_p (val, min, sgn))
min = val;
else if (wi::gt_p (val, max, sgn))
max = val;
} }
if (vr0->min == vr0->max || vr1->min == vr1->max) if (vr0->max != vr0->min)
;
else if (! sop)
{ {
val = vrp_int_const_binop (code, vr0->max, vr1->max, &sop); if (!vrp_int_const_binop (code, vr0->max, vr1->min, &val))
if (! sop)
{ {
if (wi::lt_p (val, min, sgn)) set_value_range_to_varying (vr);
min = val; return;
else if (wi::gt_p (val, max, sgn))
max = val;
} }
if (wi::lt_p (val, min, sgn))
min = val;
else if (wi::gt_p (val, max, sgn))
max = val;
} }
/* If either operation overflowed, drop to VARYING. */ if (vr0->min != vr0->max && vr1->min != vr1->max)
if (sop)
{ {
set_value_range_to_varying (vr); if (!vrp_int_const_binop (code, vr0->max, vr1->max, &val))
return; {
set_value_range_to_varying (vr);
return;
}
if (wi::lt_p (val, min, sgn))
min = val;
else if (wi::gt_p (val, max, sgn))
max = val;
} }
/* If the new range has its limits swapped around (MIN > MAX), /* If the new range has its limits swapped around (MIN > MAX),
......
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