From: rguenth Date: Fri, 13 Jul 2012 11:21:39 +0000 (+0000) Subject: 2012-07-13 Richard Guenther X-Git-Tag: upstream/4.9.2~11691 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7d48cd66509d868ed161e41878839802f552027d;p=platform%2Fupstream%2Flinaro-gcc.git 2012-07-13 Richard Guenther PR tree-optimization/53922 * tree-vrp.c (value_inside_range): Change prototype to take min/max instead of value-range. (range_includes_zero_p): Likewise. Return the result from value_inside_range. (extract_range_from_binary_expr_1): Adjust to handle dont-know return value from range_includes_zero_p. (extract_range_from_unary_expr_1): Likewise. (compare_range_with_value): Likewise. (vrp_meet_1): Likewise. * gcc.dg/torture/pr53922.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@189461 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e900a2a..f7b303a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2012-07-13 Richard Guenther + + PR tree-optimization/53922 + * tree-vrp.c (value_inside_range): Change prototype to take + min/max instead of value-range. + (range_includes_zero_p): Likewise. Return the result from + value_inside_range. + (extract_range_from_binary_expr_1): Adjust to handle dont-know + return value from range_includes_zero_p. + (extract_range_from_unary_expr_1): Likewise. + (compare_range_with_value): Likewise. + (vrp_meet_1): Likewise. + 2012-07-13 Bill Schmidt * doc/tm.texi: Regenerate. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0e2b8f3..c628663 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-07-13 Richard Guenther + + PR tree-optimization/53922 + * gcc.dg/torture/pr53922.c: New testcase. + 2012-07-13 Hans-Peter Nilsson PR rtl-optimization/53908 diff --git a/gcc/testsuite/gcc.dg/torture/pr53922.c b/gcc/testsuite/gcc.dg/torture/pr53922.c new file mode 100644 index 0000000..e42d1c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr53922.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-require-weak "" } */ + +int x(int a) +{ + return a; +} +int y(int a) __attribute__ ((weak)); +int g = 0; +int main() +{ + int (*scan_func)(int); + if (g) + scan_func = x; + else + scan_func = y; + + if (scan_func) + g = scan_func(10); + + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 32c5afa..0ce9a74 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -1339,41 +1339,25 @@ compare_values (tree val1, tree val2) } -/* Return 1 if VAL is inside value range VR (VR->MIN <= VAL <= VR->MAX), - 0 if VAL is not inside VR, +/* Return 1 if VAL is inside value range MIN <= VAL <= MAX, + 0 if VAL is not inside [MIN, MAX], -2 if we cannot tell either way. - FIXME, the current semantics of this functions are a bit quirky - when taken in the context of VRP. In here we do not care - about VR's type. If VR is the anti-range ~[3, 5] the call - value_inside_range (4, VR) will return 1. - - This is counter-intuitive in a strict sense, but the callers - currently expect this. They are calling the function - merely to determine whether VR->MIN <= VAL <= VR->MAX. The - callers are applying the VR_RANGE/VR_ANTI_RANGE semantics - themselves. - - This also applies to value_ranges_intersect_p and - range_includes_zero_p. The semantics of VR_RANGE and - VR_ANTI_RANGE should be encoded here, but that also means - adapting the users of these functions to the new semantics. - Benchmark compile/20001226-1.c compilation time after changing this function. */ static inline int -value_inside_range (tree val, value_range_t * vr) +value_inside_range (tree val, tree min, tree max) { int cmp1, cmp2; - cmp1 = operand_less_p (val, vr->min); + cmp1 = operand_less_p (val, min); if (cmp1 == -2) return -2; if (cmp1 == 1) return 0; - cmp2 = operand_less_p (vr->max, val); + cmp2 = operand_less_p (max, val); if (cmp2 == -2) return -2; @@ -1402,23 +1386,14 @@ value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1) } -/* Return true if VR includes the value zero, false otherwise. FIXME, - currently this will return false for an anti-range like ~[-4, 3]. - This will be wrong when the semantics of value_inside_range are - modified (currently the users of this function expect these - semantics). */ +/* Return 1 if [MIN, MAX] includes the value zero, 0 if it does not + include the value zero, -2 if we cannot tell. */ -static inline bool -range_includes_zero_p (value_range_t *vr) +static inline int +range_includes_zero_p (tree min, tree max) { - tree zero; - - gcc_assert (vr->type != VR_UNDEFINED - && vr->type != VR_VARYING - && !symbolic_range_p (vr)); - - zero = build_int_cst (TREE_TYPE (vr->min), 0); - return (value_inside_range (zero, vr) == 1); + tree zero = build_int_cst (TREE_TYPE (min), 0); + return value_inside_range (zero, min, max); } /* Return true if *VR is know to only contain nonnegative values. */ @@ -2641,7 +2616,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr, gives [min / 4, max / 4] range. */ if (vr1.type == VR_RANGE && !symbolic_range_p (&vr1) - && !range_includes_zero_p (&vr1)) + && range_includes_zero_p (vr1.min, vr1.max) == 0) { vr0.type = type = VR_RANGE; vr0.min = vrp_val_min (expr_type); @@ -2658,8 +2633,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr, not eliminate a division by zero. */ if (cfun->can_throw_non_call_exceptions && (vr1.type != VR_RANGE - || symbolic_range_p (&vr1) - || range_includes_zero_p (&vr1))) + || range_includes_zero_p (vr1.min, vr1.max) != 0)) { set_value_range_to_varying (vr); return; @@ -2670,8 +2644,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr, include 0. */ if (vr0.type == VR_RANGE && (vr1.type != VR_RANGE - || symbolic_range_p (&vr1) - || range_includes_zero_p (&vr1))) + || range_includes_zero_p (vr1.min, vr1.max) != 0)) { tree zero = build_int_cst (TREE_TYPE (vr0.min), 0); int cmp; @@ -2723,8 +2696,7 @@ extract_range_from_binary_expr_1 (value_range_t *vr, else if (code == TRUNC_MOD_EXPR) { if (vr1.type != VR_RANGE - || symbolic_range_p (&vr1) - || range_includes_zero_p (&vr1) + || range_includes_zero_p (vr1.min, vr1.max) != 0 || vrp_val_is_min (vr1.min)) { set_value_range_to_varying (vr); @@ -3159,7 +3131,7 @@ extract_range_from_unary_expr_1 (value_range_t *vr, ~[-INF, min(MIN, MAX)]. */ if (vr0.type == VR_ANTI_RANGE) { - if (range_includes_zero_p (&vr0)) + if (range_includes_zero_p (vr0.min, vr0.max) == 1) { /* Take the lower of the two values. */ if (cmp != 1) @@ -3210,7 +3182,7 @@ extract_range_from_unary_expr_1 (value_range_t *vr, /* If the range contains zero then we know that the minimum value in the range will be zero. */ - else if (range_includes_zero_p (&vr0)) + else if (range_includes_zero_p (vr0.min, vr0.max) == 1) { if (cmp == 1) max = min; @@ -3812,7 +3784,7 @@ compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val, return NULL_TREE; /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2. */ - if (value_inside_range (val, vr) == 1) + if (value_inside_range (val, vr->min, vr->max) == 1) return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node; return NULL_TREE; @@ -7548,12 +7520,14 @@ vrp_meet_1 (value_range_t *vr0, value_range_t *vr1) anti-range. FIXME, all this nonsense about distinguishing anti-ranges from ranges is necessary because of the odd semantics of range_includes_zero_p and friends. */ - if (!symbolic_range_p (&saved) - && ((saved.type == VR_RANGE && !range_includes_zero_p (&saved)) - || (saved.type == VR_ANTI_RANGE && range_includes_zero_p (&saved))) - && !symbolic_range_p (vr1) - && ((vr1->type == VR_RANGE && !range_includes_zero_p (vr1)) - || (vr1->type == VR_ANTI_RANGE && range_includes_zero_p (vr1)))) + if (((saved.type == VR_RANGE + && range_includes_zero_p (saved.min, saved.max) == 0) + || (saved.type == VR_ANTI_RANGE + && range_includes_zero_p (saved.min, saved.max) == 1)) + && ((vr1->type == VR_RANGE + && range_includes_zero_p (vr1->min, vr1->max) == 0) + || (vr1->type == VR_ANTI_RANGE + && range_includes_zero_p (vr1->min, vr1->max) == 1))) { set_value_range_to_nonnull (vr0, TREE_TYPE (saved.min));