This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix PR 22018
> Sure. Mind patching the comment with these added details?
I went a little further and dropped the reference to "growing", as it is
mathematically ambiguous.
Bootstrapped/regtested on x86_64-suse-linux, the results are not pretty but
the same as yours as of this morning (btw, you need to enable obj-c++).
OK for mainline?
2005-06-16 Eric Botcazou <ebotcazou@libertysurf.fr>
PR tree-optimization/22018
* tree-vrp.c (vrp_int_const_binop): Overhaul handling of overflow.
--
Eric Botcazou
Index: tree-vrp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vrp.c,v
retrieving revision 2.29
diff -c -p -r2.29 tree-vrp.c
*** tree-vrp.c 15 Jun 2005 15:19:51 -0000 2.29
--- tree-vrp.c 15 Jun 2005 21:27:48 -0000
*************** vrp_int_const_binop (enum tree_code code
*** 986,1015 ****
res = int_const_binop (code, val1, val2, 0);
/* If the operation overflowed but neither VAL1 nor VAL2 are
! overflown, return -INF or +INF depending on whether VAL1 CODE
! VAL2 is a growing function or not. */
if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2))
{
- bool grows = false;
int sgn1 = tree_int_cst_sgn (val1);
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
! operations handled by extract_range_from_binary_expr:
!
! VAL1 + VAL2 grows if VAL2 is >= 0.
! VAL1 * VAL2 grows if both VAL1 and VAL2 have the same sign.
! VAL1 - VAL2 grows if VAL2 is < 0 (because it becomes an addition).
! */
! if ((code == PLUS_EXPR && sgn2 >= 0)
! || (code == MULT_EXPR && sgn1 == sgn2)
! || (code == MINUS_EXPR && sgn2 < 0))
! grows = true;
!
! if (grows)
return TYPE_MAX_VALUE (TREE_TYPE (res));
else
return TYPE_MIN_VALUE (TREE_TYPE (res));
--- 986,1026 ----
res = int_const_binop (code, val1, val2, 0);
/* If the operation overflowed but neither VAL1 nor VAL2 are
! overflown, return -INF or +INF depending on the operation
! and the combination of signs of the operands. */
if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)
&& !TREE_OVERFLOW (val2))
{
int sgn1 = tree_int_cst_sgn (val1);
int sgn2 = tree_int_cst_sgn (val2);
! /* Notice that we only need to handle the restricted set of
! operations handled by extract_range_from_binary_expr.
! Among them, only multiplication, addition and subtraction
! can yield overflow without overflown operands because we
! are working with integral types only... except in the
! case VAL1 = -INF and VAL2 = -1 which overflows to +INF
! for division too. */
!
! /* For multiplication, the sign of the overflow is given
! by the comparison of the signs of the operands. */
! if ((code == MULT_EXPR && sgn1 == sgn2)
! /* For addition, the operands must be of the same sign
! to yield an overflow. Its sign is therefore that
! 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));
else
return TYPE_MIN_VALUE (TREE_TYPE (res));