X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree-vrp.c;h=d487df62caa36c882c5a0e7b09044188f0b2f4cd;hb=13774f7b28a842c75a76bb2f08c448fca3bb9ca5;hp=9733a3669fb8f8ad15c9f81e1b78a51703fd7c71;hpb=820860910545844dfef72ad380727e3f3b38e196;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 9733a3669fb..d487df62caa 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) @@ -3242,6 +3264,7 @@ remove_range_assertions (void) for (si = bsi_start (bb); !bsi_end_p (si);) { tree stmt = bsi_stmt (si); + tree use_stmt; if (TREE_CODE (stmt) == MODIFY_EXPR && TREE_CODE (TREE_OPERAND (stmt, 1)) == ASSERT_EXPR) @@ -3255,11 +3278,12 @@ remove_range_assertions (void) /* Propagate the RHS into every use of the LHS. */ var = ASSERT_EXPR_VAR (rhs); - FOR_EACH_IMM_USE_SAFE (use_p, iter, TREE_OPERAND (stmt, 0)) - { - SET_USE (use_p, var); - gcc_assert (TREE_CODE (var) == SSA_NAME); - } + FOR_EACH_IMM_USE_STMT (use_stmt, iter, TREE_OPERAND (stmt, 0)) + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + { + SET_USE (use_p, var); + gcc_assert (TREE_CODE (var) == SSA_NAME); + } /* And finally, remove the copy, it is not needed. */ bsi_remove (&si, true);