diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b53080e54cb..e708c8ea9f5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,9 @@ -2011-08-02 Romain Geissler +2011-08-12 Richard Guenther + + * tree-vrp.c (extract_range_from_unary_expr_1): Implement + -X as 0 - X. + +2011-08-12 Romain Geissler * Makefile.in (PLUGIN_HEADERS): Add C_TREE_H. diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 6944b42e3d1..df7a9a251ca 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -2946,67 +2946,14 @@ extract_range_from_unary_expr_1 (value_range_t *vr, /* Apply the operation to each end of the range and see what we end up with. */ - if (code == NEGATE_EXPR - && !TYPE_UNSIGNED (type)) + if (code == NEGATE_EXPR) { - /* NEGATE_EXPR flips the range around. We need to treat - TYPE_MIN_VALUE specially. */ - if (is_positive_overflow_infinity (vr0.max)) - min = negative_overflow_infinity (type); - else if (is_negative_overflow_infinity (vr0.max)) - min = positive_overflow_infinity (type); - else if (!vrp_val_is_min (vr0.max)) - min = fold_unary_to_constant (code, type, vr0.max); - else if (needs_overflow_infinity (type)) - { - if (supports_overflow_infinity (type) - && !is_overflow_infinity (vr0.min) - && !vrp_val_is_min (vr0.min)) - min = positive_overflow_infinity (type); - else - { - set_value_range_to_varying (vr); - return; - } - } - else - min = TYPE_MIN_VALUE (type); - - if (is_positive_overflow_infinity (vr0.min)) - max = negative_overflow_infinity (type); - else if (is_negative_overflow_infinity (vr0.min)) - max = positive_overflow_infinity (type); - else if (!vrp_val_is_min (vr0.min)) - max = fold_unary_to_constant (code, type, vr0.min); - else if (needs_overflow_infinity (type)) - { - if (supports_overflow_infinity (type)) - max = positive_overflow_infinity (type); - else - { - set_value_range_to_varying (vr); - return; - } - } - else - max = TYPE_MIN_VALUE (type); - } - else if (code == NEGATE_EXPR - && TYPE_UNSIGNED (type)) - { - if (!range_includes_zero_p (&vr0)) - { - max = fold_unary_to_constant (code, type, vr0.min); - min = fold_unary_to_constant (code, type, vr0.max); - } - else - { - if (range_is_null (&vr0)) - set_value_range_to_null (vr, type); - else - set_value_range_to_varying (vr); - return; - } + /* -X is simply 0 - X, so re-use existing code that also handles + anti-ranges fine. */ + value_range_t zero = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }; + set_value_range_to_value (&zero, build_int_cst (type, 0), NULL); + extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0); + return; } else if (code == ABS_EXPR && !TYPE_UNSIGNED (type))