diff options
author | Jeff Law <law@redhat.com> | 2006-05-02 13:54:20 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2006-05-02 13:54:20 -0600 |
commit | 26ef43017a241c551c893b3d0da3282c68b989fe (patch) | |
tree | fb6626d3659e936c2efbe650999f417c6e9eb12a /gcc/tree-vrp.c | |
parent | e6cbdf26b4b126b1271818399b4069fa9d40d850 (diff) | |
download | gcc-26ef43017a241c551c893b3d0da3282c68b989fe.zip gcc-26ef43017a241c551c893b3d0da3282c68b989fe.tar.gz gcc-26ef43017a241c551c893b3d0da3282c68b989fe.tar.bz2 |
re PR tree-optimization/27364 (VRP miscompiles some unsigned math)
PR tree-optimization/27364
* tree-vrp.c (vrp_int_const_binop): Fix detection of overflow from
multiply expressions.
* gcc.c-torture/execute/pr27364.c: New test.
From-SVN: r113481
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 7c6fe6e..d487df6 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1191,17 +1191,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) |