aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-05-01 17:51:56 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2007-05-01 17:51:56 +0000
commite1f28918efd6b999478fa903e355115aa6e2bff8 (patch)
treef7a8af69e45e5ad8e7e93f96d73f79730bedcfd9
parent1d87d70dd03280f2bf8d30a2695a3828152607cc (diff)
downloadgcc-e1f28918efd6b999478fa903e355115aa6e2bff8.zip
gcc-e1f28918efd6b999478fa903e355115aa6e2bff8.tar.gz
gcc-e1f28918efd6b999478fa903e355115aa6e2bff8.tar.bz2
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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/tree-vrp.c111
-rw-r--r--gcc/tree.c13
3 files changed, 86 insertions, 53 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d284429..4d52f19 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+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>
* config/i386/gmon-sol2.c (size_t): New type.
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b165418..a9141d7 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 472477c..b636de6 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;
}