From: ian Date: Tue, 24 Apr 2007 22:24:01 +0000 (+0000) Subject: ./: X-Git-Tag: upstream/4.9.2~49008 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b700987e7ca8dee04764cc3791de10564435dfcd;p=platform%2Fupstream%2Flinaro-gcc.git ./: PR tree-optimization/31605 * tree-vrp.c (set_value_range): Check that min and max are not both overflow infinities. (set_value_range_to_value): New static function. (extract_range_from_binary_expr): Call set_value_range_to_value. (extract_range_from_cond_expr): Likewise. (extract_range_from_expr): Likewise. (extract_range_from_unary_expr): Likewise. Don't create a range which overflows on both sides. (vrp_meet): Check for a useless range. (vrp_visit_phi_node): If we see a constant which looks like an overflow infinity, turn off the TREE_OVERFLOW flag. testsuite/: PR tree-optimizatoin/31605 * gcc.c-torture/execute/pr31605.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124128 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0826135..ba37f73 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,20 @@ 2007-04-24 Ian Lance Taylor + PR tree-optimization/31605 + * tree-vrp.c (set_value_range): Check that min and max are not + both overflow infinities. + (set_value_range_to_value): New static function. + (extract_range_from_binary_expr): Call set_value_range_to_value. + (extract_range_from_cond_expr): Likewise. + (extract_range_from_expr): Likewise. + (extract_range_from_unary_expr): Likewise. Don't create a range + which overflows on both sides. + (vrp_meet): Check for a useless range. + (vrp_visit_phi_node): If we see a constant which looks like an + overflow infinity, turn off the TREE_OVERFLOW flag. + +2007-04-24 Ian Lance Taylor + * flow.c (elim_reg_cond): Handle a comparison of a subreg. 2007-04-24 Simon Martin diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3195c15..cc0033e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-04-24 Ian Lance Taylor + + PR tree-optimizatoin/31605 + * gcc.c-torture/execute/pr31605.c: New test. + 2007-04-24 Francois-Xavier Coudert PR fortran/31587 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr31605.c b/gcc/testsuite/gcc.c-torture/execute/pr31605.c new file mode 100644 index 0000000..12a57ac --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr31605.c @@ -0,0 +1,13 @@ +void put_field (unsigned int start, unsigned int len) +{ + int cur_bitshift = ((start + len) % 8) - 8; + if (cur_bitshift > -8) + exit (0); +} + +int +main () +{ + put_field (0, 1); + abort (); +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index e35a6e9..78675e7 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -272,6 +272,10 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min, cmp = compare_values (min, max); gcc_assert (cmp == 0 || cmp == -1 || cmp == -2); + + if (needs_overflow_infinity (TREE_TYPE (min))) + gcc_assert (!is_overflow_infinity (min) + || !is_overflow_infinity (max)); } if (t == VR_UNDEFINED || t == VR_VARYING) @@ -320,6 +324,23 @@ set_value_range_to_varying (value_range_t *vr) bitmap_clear (vr->equiv); } +/* Set value range VR to a single value. This function is only called + with values we get from statements, and exists to clear the + TREE_OVERFLOW flag so that we don't think we have an overflow + infinity when we shouldn't. */ + +static inline void +set_value_range_to_value (value_range_t *vr, tree val) +{ + gcc_assert (is_gimple_min_invariant (val)); + if (is_overflow_infinity (val)) + { + val = copy_node (val); + TREE_OVERFLOW (val) = 0; + } + set_value_range (vr, VR_RANGE, val, val, NULL); +} + /* Set value range VR to a non-negative range of type TYPE. OVERFLOW_INFINITY indicates whether to use a overflow infinity rather than TYPE_MAX_VALUE; this should be true if we determine @@ -1646,7 +1667,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0)) - set_value_range (&vr0, VR_RANGE, op0, op0, NULL); + set_value_range_to_value (&vr0, op0); else set_value_range_to_varying (&vr0); @@ -1654,7 +1675,7 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) if (TREE_CODE (op1) == SSA_NAME) vr1 = *(get_value_range (op1)); else if (is_gimple_min_invariant (op1)) - set_value_range (&vr1, VR_RANGE, op1, op1, NULL); + set_value_range_to_value (&vr1, op1); else set_value_range_to_varying (&vr1); @@ -2053,7 +2074,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0)) - set_value_range (&vr0, VR_RANGE, op0, op0, NULL); + set_value_range_to_value (&vr0, op0); else set_value_range_to_varying (&vr0); @@ -2185,7 +2206,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max); else if (needs_overflow_infinity (TREE_TYPE (expr))) { - if (supports_overflow_infinity (TREE_TYPE (expr))) + if (supports_overflow_infinity (TREE_TYPE (expr)) + && !is_overflow_infinity (vr0.min) + && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr))) min = positive_overflow_infinity (TREE_TYPE (expr)); else { @@ -2361,6 +2384,18 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) if (needs_overflow_infinity (TREE_TYPE (expr))) { gcc_assert (code != NEGATE_EXPR && code != ABS_EXPR); + + /* If both sides have overflowed, we don't know + anything. */ + if ((is_overflow_infinity (vr0.min) + || TREE_OVERFLOW (min)) + && (is_overflow_infinity (vr0.max) + || TREE_OVERFLOW (max))) + { + set_value_range_to_varying (vr); + return; + } + if (is_overflow_infinity (vr0.min)) min = vr0.min; else if (TREE_OVERFLOW (min)) @@ -2422,7 +2457,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr) if (TREE_CODE (op0) == SSA_NAME) vr0 = *(get_value_range (op0)); else if (is_gimple_min_invariant (op0)) - set_value_range (&vr0, VR_RANGE, op0, op0, NULL); + set_value_range_to_value (&vr0, op0); else set_value_range_to_varying (&vr0); @@ -2430,7 +2465,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr) if (TREE_CODE (op1) == SSA_NAME) vr1 = *(get_value_range (op1)); else if (is_gimple_min_invariant (op1)) - set_value_range (&vr1, VR_RANGE, op1, op1, NULL); + set_value_range_to_value (&vr1, op1); else set_value_range_to_varying (&vr1); @@ -2494,7 +2529,7 @@ extract_range_from_expr (value_range_t *vr, tree expr) else if (TREE_CODE_CLASS (code) == tcc_comparison) extract_range_from_comparison (vr, expr); else if (is_gimple_min_invariant (expr)) - set_value_range (vr, VR_RANGE, expr, expr, NULL); + set_value_range_to_value (vr, expr); else set_value_range_to_varying (vr); @@ -5106,6 +5141,14 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) else goto give_up; + /* Check for useless ranges. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (min)) + && ((min == TYPE_MIN_VALUE (TREE_TYPE (min)) + || is_overflow_infinity (min)) + && (max == TYPE_MAX_VALUE (TREE_TYPE (max)) + || is_overflow_infinity (max)))) + goto give_up; + /* The resulting set of equivalences is the intersection of the two sets. */ if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv) @@ -5235,6 +5278,12 @@ vrp_visit_phi_node (tree phi) } else { + if (is_overflow_infinity (arg)) + { + arg = copy_node (arg); + TREE_OVERFLOW (arg) = 0; + } + vr_arg.type = VR_RANGE; vr_arg.min = arg; vr_arg.max = arg;