diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d28442991bc..4d52f1959bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2007-05-01 Ian Lance Taylor + + PR tree-optimization/31739 + * tree-vrp.c (vrp_val_is_max): New static function. + (vrp_val_is_min): New static function. + (set_value_range_to_value): Use TYPE_{MAX,MIN}_VALUE rather than + copying the node. + (set_value_range): Use vrp_val_is_{max,min}. + (extract_range_from_assert): Likewise. + (extract_range_from_binary_expr): Likewise. + (extract_range_from_unary_expr): Likewise. + (dump_value_range, vrp_meet): Likewise. + (vrp_visit_phi_node): Likewise. + * tree.c (build_distinct_type_copy): Revert change of 2007-04-27. + 2007-05-01 Mark Mitchell * config/i386/gmon-sol2.c (size_t): New type. diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index b165418b367..a9141d76ed2 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -202,6 +202,36 @@ is_overflow_infinity (tree val) } +/* Return whether VAL is equal to the maximum value of its type. This + will be true for a positive overflow infinity. We can't do a + simple equality comparison with TYPE_MAX_VALUE because C typedefs + and Ada subtypes can produce types whose TYPE_MAX_VALUE is not == + to the integer constant with the same value in the type. */ + +static inline bool +vrp_val_is_max (tree val) +{ + tree type_max = TYPE_MAX_VALUE (TREE_TYPE (val)); + + return (val == type_max + || (type_max != NULL_TREE + && operand_equal_p (val, type_max, 0))); +} + +/* Return whether VAL is equal to the minimum value of its type. This + will be true for a negative overflow infinity. */ + +static inline bool +vrp_val_is_min (tree val) +{ + tree type_min = TYPE_MIN_VALUE (TREE_TYPE (val)); + + return (val == type_min + || (type_min != NULL_TREE + && operand_equal_p (val, type_min, 0))); +} + + /* Return true if ARG is marked with the nonnull attribute in the current function signature. */ @@ -265,10 +295,7 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min, gcc_assert (min && max); if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE) - gcc_assert ((min != TYPE_MIN_VALUE (TREE_TYPE (min)) - && !is_negative_overflow_infinity (min)) - || (max != TYPE_MAX_VALUE (TREE_TYPE (max)) - && !is_positive_overflow_infinity (max))); + gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max)); cmp = compare_values (min, max); gcc_assert (cmp == 0 || cmp == -1 || cmp == -2); @@ -336,8 +363,16 @@ 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; + if (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0)) + val = TYPE_MAX_VALUE (TREE_TYPE (val)); + else + { +#ifdef ENABLE_CHECKING + gcc_assert (operand_equal_p (val, + TYPE_MIN_VALUE (TREE_TYPE (val)), 0)); +#endif + val = TYPE_MIN_VALUE (TREE_TYPE (val)); + } } set_value_range (vr, VR_RANGE, val, val, NULL); } @@ -1173,10 +1208,8 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) /* If MIN and MAX cover the whole range for their type, then just use the original LIMIT. */ if (INTEGRAL_TYPE_P (type) - && (min == TYPE_MIN_VALUE (type) - || is_negative_overflow_infinity (min)) - && (max == TYPE_MAX_VALUE (type) - || is_positive_overflow_infinity (max))) + && vrp_val_is_min (min) + && vrp_val_is_max (max)) min = max = limit; set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv); @@ -1411,7 +1444,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) { gcc_assert (!is_positive_overflow_infinity (anti_max)); if (needs_overflow_infinity (TREE_TYPE (anti_max)) - && anti_max == TYPE_MAX_VALUE (TREE_TYPE (anti_max))) + && vrp_val_is_max (anti_max)) { if (!supports_overflow_infinity (TREE_TYPE (var_vr->min))) { @@ -1436,7 +1469,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) { gcc_assert (!is_negative_overflow_infinity (anti_min)); if (needs_overflow_infinity (TREE_TYPE (anti_min)) - && anti_min == TYPE_MIN_VALUE (TREE_TYPE (anti_min))) + && vrp_val_is_min (anti_min)) { if (!supports_overflow_infinity (TREE_TYPE (var_vr->min))) { @@ -2025,10 +2058,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) We learn nothing when we have INF and INF(OVF) on both sides. Note that we do accept [-INF, -INF] and [+INF, +INF] without overflow. */ - if ((min == TYPE_MIN_VALUE (TREE_TYPE (min)) - || is_overflow_infinity (min)) - && (max == TYPE_MAX_VALUE (TREE_TYPE (max)) - || is_overflow_infinity (max))) + if ((vrp_val_is_min (min) || is_overflow_infinity (min)) + && (vrp_val_is_max (max) || is_overflow_infinity (max))) { set_value_range_to_varying (vr); return; @@ -2204,13 +2235,13 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) min = negative_overflow_infinity (TREE_TYPE (expr)); else if (is_negative_overflow_infinity (vr0.max)) min = positive_overflow_infinity (TREE_TYPE (expr)); - else if (vr0.max != TYPE_MIN_VALUE (TREE_TYPE (expr))) + else if (!vrp_val_is_min (vr0.max)) 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)) && !is_overflow_infinity (vr0.min) - && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr))) + && !vrp_val_is_min (vr0.min)) min = positive_overflow_infinity (TREE_TYPE (expr)); else { @@ -2225,7 +2256,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) max = negative_overflow_infinity (TREE_TYPE (expr)); else if (is_negative_overflow_infinity (vr0.min)) max = positive_overflow_infinity (TREE_TYPE (expr)); - else if (vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr))) + else if (!vrp_val_is_min (vr0.min)) max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min); else if (needs_overflow_infinity (TREE_TYPE (expr))) { @@ -2264,9 +2295,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) useful range. */ if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr)) && ((vr0.type == VR_RANGE - && vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr))) + && vrp_val_is_min (vr0.min)) || (vr0.type == VR_ANTI_RANGE - && vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)) + && !vrp_val_is_min (vr0.min) && !range_includes_zero_p (&vr0)))) { set_value_range_to_varying (vr); @@ -2277,7 +2308,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) included negative values. */ if (is_overflow_infinity (vr0.min)) min = positive_overflow_infinity (TREE_TYPE (expr)); - else if (vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr))) + else if (!vrp_val_is_min (vr0.min)) min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min); else if (!needs_overflow_infinity (TREE_TYPE (expr))) min = TYPE_MAX_VALUE (TREE_TYPE (expr)); @@ -2291,7 +2322,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) if (is_overflow_infinity (vr0.max)) max = positive_overflow_infinity (TREE_TYPE (expr)); - else if (vr0.max != TYPE_MIN_VALUE (TREE_TYPE (expr))) + else if (!vrp_val_is_min (vr0.max)) max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max); else if (!needs_overflow_infinity (TREE_TYPE (expr))) max = TYPE_MAX_VALUE (TREE_TYPE (expr)); @@ -2987,24 +3018,22 @@ dump_value_range (FILE *file, value_range_t *vr) fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : ""); - if (INTEGRAL_TYPE_P (type) - && !TYPE_UNSIGNED (type) - && vr->min == TYPE_MIN_VALUE (type)) - fprintf (file, "-INF"); - else if (needs_overflow_infinity (type) - && is_negative_overflow_infinity (vr->min)) + if (is_negative_overflow_infinity (vr->min)) fprintf (file, "-INF(OVF)"); + else if (INTEGRAL_TYPE_P (type) + && !TYPE_UNSIGNED (type) + && vrp_val_is_min (vr->min)) + fprintf (file, "-INF"); else print_generic_expr (file, vr->min, 0); fprintf (file, ", "); - if (INTEGRAL_TYPE_P (type) - && vr->max == TYPE_MAX_VALUE (type)) - fprintf (file, "+INF"); - else if (needs_overflow_infinity (type) - && is_positive_overflow_infinity (vr->max)) + if (is_positive_overflow_infinity (vr->max)) fprintf (file, "+INF(OVF)"); + else if (INTEGRAL_TYPE_P (type) + && vrp_val_is_max (vr->max)) + fprintf (file, "+INF"); else print_generic_expr (file, vr->max, 0); @@ -5157,10 +5186,8 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) /* 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)))) + && ((vrp_val_is_min (min) || is_overflow_infinity (min)) + && (vrp_val_is_max (max) || is_overflow_infinity (max)))) goto give_up; /* The resulting set of equivalences is the intersection of @@ -5348,9 +5375,7 @@ vrp_visit_phi_node (tree phi) { /* If we will end up with a (-INF, +INF) range, set it to VARYING. */ - if (is_positive_overflow_infinity (vr_result.max) - || (vr_result.max - == TYPE_MAX_VALUE (TREE_TYPE (vr_result.max)))) + if (vrp_val_is_max (vr_result.max)) goto varying; if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))) @@ -5368,9 +5393,7 @@ vrp_visit_phi_node (tree phi) { /* If we will end up with a (-INF, +INF) range, set it to VARYING. */ - if (is_negative_overflow_infinity (vr_result.min) - || (vr_result.min - == TYPE_MIN_VALUE (TREE_TYPE (vr_result.min)))) + if (vrp_val_is_min (vr_result.min)) goto varying; if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))) diff --git a/gcc/tree.c b/gcc/tree.c index 472477c49ae..b636de61384 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4173,15 +4173,10 @@ build_distinct_type_copy (tree type) /* Make it its own variant. */ TYPE_MAIN_VARIANT (t) = t; TYPE_NEXT_VARIANT (t) = 0; - - /* VRP assumes that TREE_TYPE (TYPE_MIN_VALUE (type)) == type. */ - if (INTEGRAL_TYPE_P (t) || SCALAR_FLOAT_TYPE_P (t)) - { - if (TYPE_MIN_VALUE (t) != NULL_TREE) - TYPE_MIN_VALUE (t) = fold_convert (t, TYPE_MIN_VALUE (t)); - if (TYPE_MAX_VALUE (t) != NULL_TREE) - TYPE_MAX_VALUE (t) = fold_convert (t, TYPE_MAX_VALUE (t)); - } + + /* Note that it is now possible for TYPE_MIN_VALUE to be a value + whose TREE_TYPE is not t. This can also happen in the Ada + frontend when using subtypes. */ return t; }