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>
PR other/82784
......@@ -1602,21 +1602,20 @@ extract_range_from_ssa_name (value_range *vr, tree var)
}
/* Wrapper around int_const_binop. If the operation overflows and
overflow is undefined, then adjust the result to be
-INF or +INF depending on CODE, VAL1 and VAL2. Sets *OVERFLOW_P
to whether the operation overflowed. For division by zero
the result is indeterminate but *OVERFLOW_P is set. */
/* Wrapper around int_const_binop. Return true if we can compute the
result; i.e. if the operation doesn't overflow or if the overflow is
undefined. In the latter case (if the operation overflows and
overflow is undefined), then adjust the result to be -INF or +INF
depending on CODE, VAL1 and VAL2. Return the value in *RES.
static wide_int
vrp_int_const_binop (enum tree_code code, tree val1, tree val2,
bool *overflow_p)
Return false for division by zero, for which the result is
indeterminate. */
static bool
vrp_int_const_binop (enum tree_code code, tree val1, tree val2, wide_int *res)
{
bool overflow = false;
signop sign = TYPE_SIGN (TREE_TYPE (val1));
wide_int res;
*overflow_p = false;
switch (code)
{
......@@ -1637,56 +1636,44 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2,
/* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */
res = wi::rshift (wi::to_wide (val1), wval2, sign);
*res = wi::rshift (wi::to_wide (val1), wval2, sign);
else
res = wi::lshift (wi::to_wide (val1), wval2);
*res = wi::lshift (wi::to_wide (val1), wval2);
break;
}
case MULT_EXPR:
res = wi::mul (wi::to_wide (val1),
*res = wi::mul (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break;
case TRUNC_DIV_EXPR:
case EXACT_DIV_EXPR:
if (val2 == 0)
{
*overflow_p = true;
return res;
}
return false;
else
res = wi::div_trunc (wi::to_wide (val1),
*res = wi::div_trunc (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break;
case FLOOR_DIV_EXPR:
if (val2 == 0)
{
*overflow_p = true;
return res;
}
res = wi::div_floor (wi::to_wide (val1),
return false;
*res = wi::div_floor (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break;
case CEIL_DIV_EXPR:
if (val2 == 0)
{
*overflow_p = true;
return res;
}
res = wi::div_ceil (wi::to_wide (val1),
return false;
*res = wi::div_ceil (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break;
case ROUND_DIV_EXPR:
if (val2 == 0)
{
*overflow_p = 0;
return res;
}
res = wi::div_round (wi::to_wide (val1),
return false;
*res = wi::div_round (wi::to_wide (val1),
wi::to_wide (val2), sign, &overflow);
break;
......@@ -1730,16 +1717,15 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2,
|| code == CEIL_DIV_EXPR
|| code == EXACT_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)));
else
return wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)),
*res = wi::min_value (TYPE_PRECISION (TREE_TYPE (val1)),
TYPE_SIGN (TREE_TYPE (val1)));
return true;
}
*overflow_p = overflow;
return res;
return !overflow;
}
......@@ -1835,7 +1821,6 @@ extract_range_from_multiplicative_op_1 (value_range *vr,
{
enum value_range_type rtype;
wide_int val, min, max;
bool sop;
tree type;
/* Multiplications, divisions and shifts are a bit tricky to handle,
......@@ -1866,59 +1851,51 @@ extract_range_from_multiplicative_op_1 (value_range *vr,
signop sgn = TYPE_SIGN (type);
/* Compute the 4 cross operations and their minimum and maximum value. */
sop = false;
val = vrp_int_const_binop (code, vr0->min, vr1->min, &sop);
if (! sop)
if (!vrp_int_const_binop (code, vr0->min, vr1->min, &val))
{
set_value_range_to_varying (vr);
return;
}
min = max = val;
if (vr1->max == vr1->min)
;
else if (! sop)
if (vr1->max != vr1->min)
{
val = vrp_int_const_binop (code, vr0->min, vr1->max, &sop);
if (! sop)
if (!vrp_int_const_binop (code, vr0->min, vr1->max, &val))
{
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 (vr0->max == vr0->min)
;
else if (! sop)
if (vr0->max != vr0->min)
{
val = vrp_int_const_binop (code, vr0->max, vr1->min, &sop);
if (! sop)
if (!vrp_int_const_binop (code, vr0->max, vr1->min, &val))
{
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 (vr0->min == vr0->max || vr1->min == vr1->max)
;
else if (! sop)
if (vr0->min != vr0->max && vr1->min != vr1->max)
{
val = vrp_int_const_binop (code, vr0->max, vr1->max, &sop);
if (! sop)
if (!vrp_int_const_binop (code, vr0->max, vr1->max, &val))
{
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 either operation overflowed, drop to VARYING. */
if (sop)
{
set_value_range_to_varying (vr);
return;
}
/* If the new range has its limits swapped around (MIN > MAX),
then the operation caused one of them to wrap around, mark
......
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