aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2006-07-13 18:07:40 +0000
committerPaul Brook <paul@codesourcery.com>2006-07-13 18:07:40 +0000
commita8b20def26f8819020ace682479bdf978f0cd49a (patch)
tree681df20e561672c8cdda690cdbc48d509157afa3 /gcc/tree-vrp.c
parent6e53ac993d70b42a4ac831c37ce23ef636c33181 (diff)
Merge from gcc-4_1-branch revision 114100 (gcc-4_1_1-release)
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl/sourcerygxx-4_1@115418 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index c00d7456fc6..84724c52e2c 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1101,17 +1101,39 @@ vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
if (TYPE_UNSIGNED (TREE_TYPE (val1)))
{
int checkz = compare_values (res, val1);
+ bool overflow = false;
/* Ensure that res = val1 [+*] val2 >= val1
or that res = val1 - val2 <= val1. */
- if (((code == PLUS_EXPR || code == MULT_EXPR)
+ if ((code == PLUS_EXPR
&& !(checkz == 1 || checkz == 0))
|| (code == MINUS_EXPR
&& !(checkz == 0 || checkz == -1)))
{
+ overflow = true;
+ }
+ /* Checking for multiplication overflow is done by dividing the
+ output of the multiplication by the first input of the
+ multiplication. If the result of that division operation is
+ not equal to the second input of the multiplication, then the
+ multiplication overflowed. */
+ else if (code == MULT_EXPR && !integer_zerop (val1))
+ {
+ tree tmp = int_const_binop (TRUNC_DIV_EXPR,
+ TYPE_MAX_VALUE (TREE_TYPE (val1)),
+ val1, 0);
+ int check = compare_values (tmp, val2);
+
+ if (check != 0)
+ overflow = true;
+ }
+
+ if (overflow)
+ {
res = copy_node (res);
TREE_OVERFLOW (res) = 1;
}
+
}
else if (TREE_OVERFLOW (res)
&& !TREE_OVERFLOW (val1)