Commit 96644aba by Richard Guenther Committed by Richard Biener

re PR tree-optimization/29446 (VRP ICE in compare_names)

2006-10-13  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/29446
	* tree-vrp.c (fix_equivalence_set): Remove.
	(extract_range_from_assert): Do not call fix_equivalence_set.
	(debug_value_range): Print a newline.
	(compare_name_with_value): For equivalence sets with
	inconsistent value ranges conservatively bail out.
	(compare_names): Likewise.

	* gcc.dg/torture/pr29446.c: New testcase.

From-SVN: r117705
parent 4010308c
2006-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/29446
* tree-vrp.c (fix_equivalence_set): Remove.
(extract_range_from_assert): Do not call fix_equivalence_set.
(debug_value_range): Print a newline.
(compare_name_with_value): For equivalence sets with
inconsistent value ranges conservatively bail out.
(compare_names): Likewise.
2006-10-13 David Edelsohn <edelsohn@gnu.org>
* doc/install.texi (*-ibm-aix*): Add comment about 32-bit GMP
......
2006-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/29446
* gcc.dg/torture/pr29446.c: New testcase.
2006-10-13 Bill Wendling <wendling@apple.com>
* g++.old-deja/g++.brendan/scope5.C: Changed "Class" to "Klasse".
/* { dg-do compile } */
void f(_Bool D917, int j0, int ubound1, int ubound5)
{
int i, j = j0;
int (*abc)[3];
i = 1;
while (1)
{
if (j <= 3)
while (1)
{
if (i != j)
{
if (ubound1 <= 0)
return;
(*abc)[1] = 0;
}
else
{
if (j > ubound1)
return;
if (ubound5 <= 0)
return;
}
j = j + 1;
if (D917)
break;
}
i = i + 1;
}
}
......@@ -724,86 +724,6 @@ ssa_name_nonzero_p (tree t)
}
/* When extracting ranges from X_i = ASSERT_EXPR <Y_j, pred>, we will
initially consider X_i and Y_j equivalent, so the equivalence set
of Y_j is added to the equivalence set of X_i. However, it is
possible to have a chain of ASSERT_EXPRs whose predicates are
actually incompatible. This is usually the result of nesting of
contradictory if-then-else statements. For instance, in PR 24670:
count_4 has range [-INF, 63]
if (count_4 != 0)
{
count_19 = ASSERT_EXPR <count_4, count_4 != 0>
if (count_19 > 63)
{
count_18 = ASSERT_EXPR <count_19, count_19 > 63>
if (count_18 <= 63)
...
}
}
Notice that 'if (count_19 > 63)' is trivially false and will be
folded out at the end. However, during propagation, the flowgraph
is not cleaned up and so, VRP will evaluate predicates more
predicates than necessary, so it must support these
inconsistencies. The problem here is that because of the chaining
of ASSERT_EXPRs, the equivalency set for count_18 includes count_4.
Since count_4 has an incompatible range, we ICE when evaluating the
ranges in the equivalency set. So, we need to remove count_4 from
it. */
static void
fix_equivalence_set (value_range_t *vr_p)
{
bitmap_iterator bi;
unsigned i;
bitmap e = vr_p->equiv;
bitmap to_remove;
/* Only detect inconsistencies on numeric ranges. */
if (vr_p->type == VR_VARYING
|| vr_p->type == VR_UNDEFINED
|| symbolic_range_p (vr_p))
return;
to_remove = BITMAP_ALLOC (NULL);
EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
{
value_range_t *equiv_vr = vr_value[i];
if (equiv_vr->type == VR_VARYING
|| equiv_vr->type == VR_UNDEFINED)
continue;
if (vr_p->type == VR_RANGE
&& equiv_vr->type == VR_RANGE)
{
/* Two ranges have an empty intersection if their end points
are outside of the other range. */
if (compare_values (equiv_vr->min, vr_p->max) == 1
|| compare_values (equiv_vr->max, vr_p->min) == -1)
bitmap_set_bit (to_remove, i);
}
else if ((equiv_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
|| (equiv_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
{
/* A range and an anti-range have an empty intersection if
their end points are the same. FIXME,
value_ranges_intersect_p should handle this
automatically. */
if (compare_values (equiv_vr->min, vr_p->min) == 0
&& compare_values (equiv_vr->max, vr_p->max) == 0)
bitmap_set_bit (to_remove, i);
}
}
bitmap_and_compl_into (vr_p->equiv, to_remove);
BITMAP_FREE (to_remove);
}
/* Extract value range information from an ASSERT_EXPR EXPR and store
it in *VR_P. */
......@@ -1056,7 +976,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
|| var_vr->type == VR_UNDEFINED
|| symbolic_range_p (vr_p)
|| symbolic_range_p (var_vr))
goto done;
return;
if (var_vr->type == VR_RANGE && vr_p->type == VR_RANGE)
{
......@@ -1191,11 +1111,6 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
}
}
}
/* Remove names from the equivalence set that have ranges
incompatible with VR_P. */
done:
fix_equivalence_set (vr_p);
}
......@@ -2438,6 +2353,7 @@ void
debug_value_range (value_range_t *vr)
{
dump_value_range (stderr, vr);
fprintf (stderr, "\n");
}
......@@ -3555,8 +3471,16 @@ compare_name_with_value (enum tree_code comp, tree var, tree val)
t = compare_range_with_value (comp, &equiv_vr, val);
if (t)
{
/* All the ranges should compare the same against VAL. */
gcc_assert (retval == NULL || t == retval);
/* If we get different answers from different members
of the equivalence set this check must be in a dead
code region. Folding it to a trap representation
would be correct here. For now just return don't-know. */
if (retval != NULL
&& t != retval)
{
retval = NULL_TREE;
break;
}
retval = t;
}
}
......@@ -3638,9 +3562,17 @@ compare_names (enum tree_code comp, tree n1, tree n2)
t = compare_ranges (comp, &vr1, &vr2);
if (t)
{
/* All the ranges in the equivalent sets should compare
the same. */
gcc_assert (retval == NULL || t == retval);
/* If we get different answers from different members
of the equivalence set this check must be in a dead
code region. Folding it to a trap representation
would be correct here. For now just return don't-know. */
if (retval != NULL
&& t != retval)
{
bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
return NULL_TREE;
}
retval = 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