re PR tree-optimization/77479 (Compile time hog w/ -O2 (-Os))

2016-09-06  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/77479
	* tree-vrp.c (update_value_range): Extend overflow handling to
	VARYING.

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

From-SVN: r240007
This commit is contained in:
Richard Biener 2016-09-06 12:51:01 +00:00 committed by Richard Biener
parent b772a56562
commit 209b636edd
4 changed files with 55 additions and 13 deletions

View file

@ -1,3 +1,9 @@
2016-09-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77479
* tree-vrp.c (update_value_range): Extend overflow handling to
VARYING.
2016-09-05 Jakub Jelinek <jakub@redhat.com>
PR target/77476

View file

@ -1,3 +1,8 @@
2016-09-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/77479
* gcc.dg/torture/pr77479.c: New testcase.
2016-09-06 Richard Biener <rguenther@suse.de>
PR c/77450

View file

@ -0,0 +1,25 @@
/* { dg-do compile } */
/* { dg-additional-options "-fstrict-overflow -ftree-vrp" } */
void
vr (int of, unsigned char bw)
{
int d1;
int lm = 0;
for (d1 = 0; d1 < 3; ++d1)
{
const int vl = 2;
while (bw < vl)
{
}
if (bw != vl)
lm -= vl;
}
while (++of < 1)
{
lm /= bw;
of += lm;
}
}

View file

@ -744,23 +744,29 @@ update_value_range (const_tree var, value_range *new_vr)
value_range_type rtype = get_range_info (var, &min, &max);
if (rtype == VR_RANGE || rtype == VR_ANTI_RANGE)
{
value_range nr;
nr.type = rtype;
tree nr_min, nr_max;
/* Range info on SSA names doesn't carry overflow information
so make sure to preserve the overflow bit on the lattice. */
if (new_vr->type == VR_RANGE
&& is_negative_overflow_infinity (new_vr->min)
&& wi::eq_p (new_vr->min, min))
nr.min = new_vr->min;
if (rtype == VR_RANGE
&& needs_overflow_infinity (TREE_TYPE (var))
&& (new_vr->type == VR_VARYING
|| (new_vr->type == VR_RANGE
&& is_negative_overflow_infinity (new_vr->min)))
&& wi::eq_p (vrp_val_min (TREE_TYPE (var)), min))
nr_min = negative_overflow_infinity (TREE_TYPE (var));
else
nr.min = wide_int_to_tree (TREE_TYPE (var), min);
if (new_vr->type == VR_RANGE
&& is_positive_overflow_infinity (new_vr->max)
&& wi::eq_p (new_vr->max, max))
nr.max = new_vr->max;
nr_min = wide_int_to_tree (TREE_TYPE (var), min);
if (rtype == VR_RANGE
&& needs_overflow_infinity (TREE_TYPE (var))
&& (new_vr->type == VR_VARYING
|| (new_vr->type == VR_RANGE
&& is_positive_overflow_infinity (new_vr->max)))
&& wi::eq_p (vrp_val_max (TREE_TYPE (var)), max))
nr_max = positive_overflow_infinity (TREE_TYPE (var));
else
nr.max = wide_int_to_tree (TREE_TYPE (var), max);
nr.equiv = NULL;
nr_max = wide_int_to_tree (TREE_TYPE (var), max);
value_range nr = VR_INITIALIZER;
set_and_canonicalize_value_range (&nr, rtype, nr_min, nr_max, NULL);
vrp_intersect_ranges (new_vr, &nr);
}
}