Commit 0d22e81f by Eric Botcazou Committed by Eric Botcazou

re PR tree-optimization/22018 (VRP miscompiles multiply)

	PR tree-optimization/22018
	* tree-vrp.c (vrp_int_const_binop): Overhaul handling of overflow.

From-SVN: r101097
parent 9b9c745e
2005-06-16 Eric Botcazou <ebotcazou@libertysurf.fr>
PR tree-optimization/22018
* tree-vrp.c (vrp_int_const_binop): Overhaul handling of overflow.
2005-06-16 Richard Henderson <rth@redhat.com> 2005-06-16 Richard Henderson <rth@redhat.com>
PR tree-opt/22035 PR tree-opt/22035
......
...@@ -986,30 +986,41 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2) ...@@ -986,30 +986,41 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
res = int_const_binop (code, val1, val2, 0); res = int_const_binop (code, val1, val2, 0);
/* If the operation overflowed but neither VAL1 nor VAL2 are /* If the operation overflowed but neither VAL1 nor VAL2 are
overflown, return -INF or +INF depending on whether VAL1 CODE overflown, return -INF or +INF depending on the operation
VAL2 is a growing function or not. */ and the combination of signs of the operands. */
if (TREE_OVERFLOW (res) if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1) && !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2)) && !TREE_OVERFLOW (val2))
{ {
bool grows = false;
int sgn1 = tree_int_cst_sgn (val1); int sgn1 = tree_int_cst_sgn (val1);
int sgn2 = tree_int_cst_sgn (val2); int sgn2 = tree_int_cst_sgn (val2);
/* Determine whether VAL1 CODE VAL2 yields a growing value. /* Notice that we only need to handle the restricted set of
Notice that we only need to handle the restricted set of operations handled by extract_range_from_binary_expr.
operations handled by extract_range_from_binary_expr: Among them, only multiplication, addition and subtraction
can yield overflow without overflown operands because we
VAL1 + VAL2 grows if VAL2 is >= 0. are working with integral types only... except in the
VAL1 * VAL2 grows if both VAL1 and VAL2 have the same sign. case VAL1 = -INF and VAL2 = -1 which overflows to +INF
VAL1 - VAL2 grows if VAL2 is < 0 (because it becomes an addition). for division too. */
*/
if ((code == PLUS_EXPR && sgn2 >= 0) /* For multiplication, the sign of the overflow is given
|| (code == MULT_EXPR && sgn1 == sgn2) by the comparison of the signs of the operands. */
|| (code == MINUS_EXPR && sgn2 < 0)) if ((code == MULT_EXPR && sgn1 == sgn2)
grows = true; /* For addition, the operands must be of the same sign
to yield an overflow. Its sign is therefore that
if (grows) of one of the operands, for example the first. */
|| (code == PLUS_EXPR && sgn1 > 0)
/* For subtraction, the operands must be of different
signs to yield an overflow. Its sign is therefore
that of the first operand or the opposite of that
of the second operand. */
|| (code == MINUS_EXPR && sgn1 > 0)
/* For division, the only case is -INF / -1 = +INF. */
|| code == TRUNC_DIV_EXPR
|| code == FLOOR_DIV_EXPR
|| code == CEIL_DIV_EXPR
|| code == EXACT_DIV_EXPR
|| code == ROUND_DIV_EXPR)
return TYPE_MAX_VALUE (TREE_TYPE (res)); return TYPE_MAX_VALUE (TREE_TYPE (res));
else else
return TYPE_MIN_VALUE (TREE_TYPE (res)); return TYPE_MIN_VALUE (TREE_TYPE (res));
......
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