Commit e1f28918 by Ian Lance Taylor Committed by Ian Lance Taylor

re PR tree-optimization/31739 (ICE at tree.c:902 compiling g-regexp.adb)

	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.

From-SVN: r124334
parent 1d87d70d
2007-05-01 Ian Lance Taylor <iant@google.com>
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 <mark@codesourcery.com> 2007-05-01 Mark Mitchell <mark@codesourcery.com>
* config/i386/gmon-sol2.c (size_t): New type. * config/i386/gmon-sol2.c (size_t): New type.
......
...@@ -202,6 +202,36 @@ is_overflow_infinity (tree val) ...@@ -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 /* Return true if ARG is marked with the nonnull attribute in the
current function signature. */ current function signature. */
...@@ -265,10 +295,7 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min, ...@@ -265,10 +295,7 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min,
gcc_assert (min && max); gcc_assert (min && max);
if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE) if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
gcc_assert ((min != TYPE_MIN_VALUE (TREE_TYPE (min)) gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
&& !is_negative_overflow_infinity (min))
|| (max != TYPE_MAX_VALUE (TREE_TYPE (max))
&& !is_positive_overflow_infinity (max)));
cmp = compare_values (min, max); cmp = compare_values (min, max);
gcc_assert (cmp == 0 || cmp == -1 || cmp == -2); gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
...@@ -336,8 +363,16 @@ set_value_range_to_value (value_range_t *vr, tree val) ...@@ -336,8 +363,16 @@ set_value_range_to_value (value_range_t *vr, tree val)
gcc_assert (is_gimple_min_invariant (val)); gcc_assert (is_gimple_min_invariant (val));
if (is_overflow_infinity (val)) if (is_overflow_infinity (val))
{ {
val = copy_node (val); if (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0))
TREE_OVERFLOW (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); set_value_range (vr, VR_RANGE, val, val, NULL);
} }
...@@ -1173,10 +1208,8 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) ...@@ -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 /* If MIN and MAX cover the whole range for their type, then
just use the original LIMIT. */ just use the original LIMIT. */
if (INTEGRAL_TYPE_P (type) if (INTEGRAL_TYPE_P (type)
&& (min == TYPE_MIN_VALUE (type) && vrp_val_is_min (min)
|| is_negative_overflow_infinity (min)) && vrp_val_is_max (max))
&& (max == TYPE_MAX_VALUE (type)
|| is_positive_overflow_infinity (max)))
min = max = limit; min = max = limit;
set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv); 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) ...@@ -1411,7 +1444,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
{ {
gcc_assert (!is_positive_overflow_infinity (anti_max)); gcc_assert (!is_positive_overflow_infinity (anti_max));
if (needs_overflow_infinity (TREE_TYPE (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))) if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
{ {
...@@ -1436,7 +1469,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) ...@@ -1436,7 +1469,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
{ {
gcc_assert (!is_negative_overflow_infinity (anti_min)); gcc_assert (!is_negative_overflow_infinity (anti_min));
if (needs_overflow_infinity (TREE_TYPE (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))) if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
{ {
...@@ -2025,10 +2058,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr) ...@@ -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. We learn nothing when we have INF and INF(OVF) on both sides.
Note that we do accept [-INF, -INF] and [+INF, +INF] without Note that we do accept [-INF, -INF] and [+INF, +INF] without
overflow. */ overflow. */
if ((min == TYPE_MIN_VALUE (TREE_TYPE (min)) if ((vrp_val_is_min (min) || is_overflow_infinity (min))
|| is_overflow_infinity (min)) && (vrp_val_is_max (max) || is_overflow_infinity (max)))
&& (max == TYPE_MAX_VALUE (TREE_TYPE (max))
|| is_overflow_infinity (max)))
{ {
set_value_range_to_varying (vr); set_value_range_to_varying (vr);
return; return;
...@@ -2204,13 +2235,13 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -2204,13 +2235,13 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
min = negative_overflow_infinity (TREE_TYPE (expr)); min = negative_overflow_infinity (TREE_TYPE (expr));
else if (is_negative_overflow_infinity (vr0.max)) else if (is_negative_overflow_infinity (vr0.max))
min = positive_overflow_infinity (TREE_TYPE (expr)); 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); min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
else if (needs_overflow_infinity (TREE_TYPE (expr))) 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) && !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)); min = positive_overflow_infinity (TREE_TYPE (expr));
else else
{ {
...@@ -2225,7 +2256,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -2225,7 +2256,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
max = negative_overflow_infinity (TREE_TYPE (expr)); max = negative_overflow_infinity (TREE_TYPE (expr));
else if (is_negative_overflow_infinity (vr0.min)) else if (is_negative_overflow_infinity (vr0.min))
max = positive_overflow_infinity (TREE_TYPE (expr)); 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); max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
else if (needs_overflow_infinity (TREE_TYPE (expr))) else if (needs_overflow_infinity (TREE_TYPE (expr)))
{ {
...@@ -2264,9 +2295,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -2264,9 +2295,9 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
useful range. */ useful range. */
if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr)) if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr))
&& ((vr0.type == VR_RANGE && ((vr0.type == VR_RANGE
&& vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr))) && vrp_val_is_min (vr0.min))
|| (vr0.type == VR_ANTI_RANGE || (vr0.type == VR_ANTI_RANGE
&& vr0.min != TYPE_MIN_VALUE (TREE_TYPE (expr)) && !vrp_val_is_min (vr0.min)
&& !range_includes_zero_p (&vr0)))) && !range_includes_zero_p (&vr0))))
{ {
set_value_range_to_varying (vr); set_value_range_to_varying (vr);
...@@ -2277,7 +2308,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr) ...@@ -2277,7 +2308,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
included negative values. */ included negative values. */
if (is_overflow_infinity (vr0.min)) if (is_overflow_infinity (vr0.min))
min = positive_overflow_infinity (TREE_TYPE (expr)); 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); min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
else if (!needs_overflow_infinity (TREE_TYPE (expr))) else if (!needs_overflow_infinity (TREE_TYPE (expr)))
min = TYPE_MAX_VALUE (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) ...@@ -2291,7 +2322,7 @@ extract_range_from_unary_expr (value_range_t *vr, tree expr)
if (is_overflow_infinity (vr0.max)) if (is_overflow_infinity (vr0.max))
max = positive_overflow_infinity (TREE_TYPE (expr)); 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); max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
else if (!needs_overflow_infinity (TREE_TYPE (expr))) else if (!needs_overflow_infinity (TREE_TYPE (expr)))
max = TYPE_MAX_VALUE (TREE_TYPE (expr)); max = TYPE_MAX_VALUE (TREE_TYPE (expr));
...@@ -2987,24 +3018,22 @@ dump_value_range (FILE *file, value_range_t *vr) ...@@ -2987,24 +3018,22 @@ dump_value_range (FILE *file, value_range_t *vr)
fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : ""); fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
if (INTEGRAL_TYPE_P (type) if (is_negative_overflow_infinity (vr->min))
&& !TYPE_UNSIGNED (type)
&& vr->min == TYPE_MIN_VALUE (type))
fprintf (file, "-INF");
else if (needs_overflow_infinity (type)
&& is_negative_overflow_infinity (vr->min))
fprintf (file, "-INF(OVF)"); fprintf (file, "-INF(OVF)");
else if (INTEGRAL_TYPE_P (type)
&& !TYPE_UNSIGNED (type)
&& vrp_val_is_min (vr->min))
fprintf (file, "-INF");
else else
print_generic_expr (file, vr->min, 0); print_generic_expr (file, vr->min, 0);
fprintf (file, ", "); fprintf (file, ", ");
if (INTEGRAL_TYPE_P (type) if (is_positive_overflow_infinity (vr->max))
&& vr->max == TYPE_MAX_VALUE (type))
fprintf (file, "+INF");
else if (needs_overflow_infinity (type)
&& is_positive_overflow_infinity (vr->max))
fprintf (file, "+INF(OVF)"); fprintf (file, "+INF(OVF)");
else if (INTEGRAL_TYPE_P (type)
&& vrp_val_is_max (vr->max))
fprintf (file, "+INF");
else else
print_generic_expr (file, vr->max, 0); print_generic_expr (file, vr->max, 0);
...@@ -5157,10 +5186,8 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -5157,10 +5186,8 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
/* Check for useless ranges. */ /* Check for useless ranges. */
if (INTEGRAL_TYPE_P (TREE_TYPE (min)) if (INTEGRAL_TYPE_P (TREE_TYPE (min))
&& ((min == TYPE_MIN_VALUE (TREE_TYPE (min)) && ((vrp_val_is_min (min) || is_overflow_infinity (min))
|| is_overflow_infinity (min)) && (vrp_val_is_max (max) || is_overflow_infinity (max))))
&& (max == TYPE_MAX_VALUE (TREE_TYPE (max))
|| is_overflow_infinity (max))))
goto give_up; goto give_up;
/* The resulting set of equivalences is the intersection of /* The resulting set of equivalences is the intersection of
...@@ -5348,9 +5375,7 @@ vrp_visit_phi_node (tree phi) ...@@ -5348,9 +5375,7 @@ vrp_visit_phi_node (tree phi)
{ {
/* If we will end up with a (-INF, +INF) range, set it /* If we will end up with a (-INF, +INF) range, set it
to VARYING. */ to VARYING. */
if (is_positive_overflow_infinity (vr_result.max) if (vrp_val_is_max (vr_result.max))
|| (vr_result.max
== TYPE_MAX_VALUE (TREE_TYPE (vr_result.max))))
goto varying; goto varying;
if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))) if (!needs_overflow_infinity (TREE_TYPE (vr_result.min)))
...@@ -5368,9 +5393,7 @@ vrp_visit_phi_node (tree phi) ...@@ -5368,9 +5393,7 @@ vrp_visit_phi_node (tree phi)
{ {
/* If we will end up with a (-INF, +INF) range, set it /* If we will end up with a (-INF, +INF) range, set it
to VARYING. */ to VARYING. */
if (is_negative_overflow_infinity (vr_result.min) if (vrp_val_is_min (vr_result.min))
|| (vr_result.min
== TYPE_MIN_VALUE (TREE_TYPE (vr_result.min))))
goto varying; goto varying;
if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))) if (!needs_overflow_infinity (TREE_TYPE (vr_result.max)))
......
...@@ -4173,15 +4173,10 @@ build_distinct_type_copy (tree type) ...@@ -4173,15 +4173,10 @@ build_distinct_type_copy (tree type)
/* Make it its own variant. */ /* Make it its own variant. */
TYPE_MAIN_VARIANT (t) = t; TYPE_MAIN_VARIANT (t) = t;
TYPE_NEXT_VARIANT (t) = 0; TYPE_NEXT_VARIANT (t) = 0;
/* VRP assumes that TREE_TYPE (TYPE_MIN_VALUE (type)) == type. */ /* Note that it is now possible for TYPE_MIN_VALUE to be a value
if (INTEGRAL_TYPE_P (t) || SCALAR_FLOAT_TYPE_P (t)) whose TREE_TYPE is not t. This can also happen in the Ada
{ frontend when using subtypes. */
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));
}
return t; return t;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment