re PR bootstrap/87640 (internal compiler error: in check, at tree-vrp.c:155)

2018-10-22  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/87640
	* tree-vrp.c (set_value_range_with_overflow): Decompose
	incomplete result.
	(extract_range_from_binary_expr_1): Adjust.

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

From-SVN: r265375
This commit is contained in:
Richard Biener 2018-10-22 10:22:48 +00:00 committed by Richard Biener
parent 9470d3ecf3
commit 893ade8b74
4 changed files with 47 additions and 21 deletions

View File

@ -1,3 +1,10 @@
2018-10-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/87640
* tree-vrp.c (set_value_range_with_overflow): Decompose
incomplete result.
(extract_range_from_binary_expr_1): Adjust.
2018-10-22 Martin Jambor <mjambor@suse.cz> 2018-10-22 Martin Jambor <mjambor@suse.cz>
* tree-eh.h (stmt_could_throw_p): Add function parameter. * tree-eh.h (stmt_could_throw_p): Add function parameter.

View File

@ -1,3 +1,8 @@
2018-10-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/87640
* gcc.dg/torture/pr87640.c: New testcase.
2018-10-22 Ilya Leoshkevich <iii@linux.ibm.com> 2018-10-22 Ilya Leoshkevich <iii@linux.ibm.com>
* gcc.target/s390/litpool-int.c: New test. * gcc.target/s390/litpool-int.c: New test.

View File

@ -0,0 +1,11 @@
/* { dg-do compile } */
int main ()
{
unsigned b = 0;
int c, d = -8;
for (; b < 2; b++)
for (c = 1; c; c--)
d++;
return 0;
}

View File

@ -1328,7 +1328,7 @@ combine_bound (enum tree_code code, wide_int &wi, wi::overflow_type &ovf,
underflow. +1 indicates overflow. 0 indicates neither. */ underflow. +1 indicates overflow. 0 indicates neither. */
static void static void
set_value_range_with_overflow (value_range &vr, set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max,
tree type, tree type,
const wide_int &wmin, const wide_int &wmax, const wide_int &wmin, const wide_int &wmax,
wi::overflow_type min_ovf, wi::overflow_type min_ovf,
@ -1341,7 +1341,7 @@ set_value_range_with_overflow (value_range &vr,
range covers all values. */ range covers all values. */
if (prec == 1 && wi::lt_p (wmax, wmin, sgn)) if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
{ {
set_value_range_to_varying (&vr); kind = VR_VARYING;
return; return;
} }
@ -1357,13 +1357,15 @@ set_value_range_with_overflow (value_range &vr,
the entire range. We have a similar check at the end of the entire range. We have a similar check at the end of
extract_range_from_binary_expr_1. */ extract_range_from_binary_expr_1. */
if (wi::gt_p (tmin, tmax, sgn)) if (wi::gt_p (tmin, tmax, sgn))
vr.set_varying (); kind = VR_VARYING;
else else
/* No overflow or both overflow or underflow. The {
range kind stays VR_RANGE. */ kind = VR_RANGE;
vr = value_range (VR_RANGE, /* No overflow or both overflow or underflow. The
wide_int_to_tree (type, tmin), range kind stays VR_RANGE. */
wide_int_to_tree (type, tmax)); min = wide_int_to_tree (type, tmin);
max = wide_int_to_tree (type, tmax);
}
return; return;
} }
else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE) else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
@ -1384,18 +1386,18 @@ set_value_range_with_overflow (value_range &vr,
types values. */ types values. */
if (covers || wi::cmp (tmin, tmax, sgn) > 0) if (covers || wi::cmp (tmin, tmax, sgn) > 0)
{ {
set_value_range_to_varying (&vr); kind = VR_VARYING;
return; return;
} }
vr = value_range (VR_ANTI_RANGE, kind = VR_ANTI_RANGE;
wide_int_to_tree (type, tmin), min = wide_int_to_tree (type, tmin);
wide_int_to_tree (type, tmax)); max = wide_int_to_tree (type, tmax);
return; return;
} }
else else
{ {
/* Other underflow and/or overflow, drop to VR_VARYING. */ /* Other underflow and/or overflow, drop to VR_VARYING. */
set_value_range_to_varying (&vr); kind = VR_VARYING;
return; return;
} }
} }
@ -1405,7 +1407,7 @@ set_value_range_with_overflow (value_range &vr,
value. */ value. */
wide_int type_min = wi::min_value (prec, sgn); wide_int type_min = wi::min_value (prec, sgn);
wide_int type_max = wi::max_value (prec, sgn); wide_int type_max = wi::max_value (prec, sgn);
tree min, max; kind = VR_RANGE;
if (min_ovf == wi::OVF_UNDERFLOW) if (min_ovf == wi::OVF_UNDERFLOW)
min = wide_int_to_tree (type, type_min); min = wide_int_to_tree (type, type_min);
else if (min_ovf == wi::OVF_OVERFLOW) else if (min_ovf == wi::OVF_OVERFLOW)
@ -1419,7 +1421,6 @@ set_value_range_with_overflow (value_range &vr,
max = wide_int_to_tree (type, type_max); max = wide_int_to_tree (type, type_max);
else else
max = wide_int_to_tree (type, wmax); max = wide_int_to_tree (type, wmax);
vr = value_range (VR_RANGE, min, max);
} }
} }
@ -1676,21 +1677,23 @@ extract_range_from_binary_expr_1 (value_range *vr,
} }
/* Adjust the range for possible overflow. */ /* Adjust the range for possible overflow. */
set_value_range_with_overflow (*vr, expr_type, min = NULL_TREE;
max = NULL_TREE;
set_value_range_with_overflow (type, min, max, expr_type,
wmin, wmax, min_ovf, max_ovf); wmin, wmax, min_ovf, max_ovf);
if (vr->varying_p ()) if (type == VR_VARYING)
return; {
set_value_range_to_varying (vr);
return;
}
/* Build the symbolic bounds if needed. */ /* Build the symbolic bounds if needed. */
min = vr->min ();
max = vr->max ();
adjust_symbolic_bound (min, code, expr_type, adjust_symbolic_bound (min, code, expr_type,
sym_min_op0, sym_min_op1, sym_min_op0, sym_min_op1,
neg_min_op0, neg_min_op1); neg_min_op0, neg_min_op1);
adjust_symbolic_bound (max, code, expr_type, adjust_symbolic_bound (max, code, expr_type,
sym_max_op0, sym_max_op1, sym_max_op0, sym_max_op1,
neg_max_op0, neg_max_op1); neg_max_op0, neg_max_op1);
type = vr->kind ();
} }
else else
{ {