re PR tree-optimization/76490 (when use -O2 -fcheck-founds compiler appears to hang and consumes all memory)

2016-08-17  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/76490
	* tree-vrp.c (update_value_range): Preserve overflow infinities
	when intersecting with ranges from get_range_info.
	(operand_less_p): Handle overflow infinities correctly.
	(value_range_constant_singleton): Use vrp_operand_equal_p
	to handle overflow max/min correctly.
	(vrp_valueize): Likewise.
	(union_ranges): Likewise.
	(intersect_ranges): Likewise.
	(vrp_visit_phi_node): Improve iteration limitation to only
	apply when we'll possibly re-visit the PHI via a changed argument
	on the backedge.

	* gfortran.fortran-torture/compile/pr76490.f90: New testcase.
	* gcc.dg/pr52904.c: XFAIL.

From-SVN: r239529
This commit is contained in:
Richard Biener 2016-08-17 11:51:51 +00:00 committed by Richard Biener
parent 03c9d8596f
commit 661d6efd62
5 changed files with 75 additions and 17 deletions

View File

@ -1,3 +1,18 @@
2016-08-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/76490
* tree-vrp.c (update_value_range): Preserve overflow infinities
when intersecting with ranges from get_range_info.
(operand_less_p): Handle overflow infinities correctly.
(value_range_constant_singleton): Use vrp_operand_equal_p
to handle overflow max/min correctly.
(vrp_valueize): Likewise.
(union_ranges): Likewise.
(intersect_ranges): Likewise.
(vrp_visit_phi_node): Improve iteration limitation to only
apply when we'll possibly re-visit the PHI via a changed argument
on the backedge.
2016-08-17 Thomas Preud'homme <thomas.preudhomme@arm.com> 2016-08-17 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/arm/t-aprofile (MULTILIB_EXCEPTIONS): Rewrite into ... * config/arm/t-aprofile (MULTILIB_EXCEPTIONS): Rewrite into ...

View File

@ -1,3 +1,9 @@
2016-08-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/76490
* gfortran.fortran-torture/compile/pr76490.f90: New testcase.
* gcc.dg/pr52904.c: XFAIL.
2016-08-17 Richard Biener <rguenther@suse.de> 2016-08-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/23855 PR tree-optimization/23855

View File

@ -14,7 +14,7 @@ wait_reading_process_output (void)
nfds++; nfds++;
} }
if (nfds < 0) /* { dg-bogus "assuming signed overflow does not occur" } */ if (nfds < 0) /* { dg-bogus "assuming signed overflow does not occur" "" { xfail *-*-* } } */
return 1; return 1;
return 0; return 0;
} }

View File

@ -0,0 +1,23 @@
program membug
call bug1()
end program membug
subroutine unknown(x1,y1,ibig)
write(*,*)x1,y1,ibig
end subroutine unknown
subroutine bug1()
real arrayq(3000)
isize=0
ibig=-1
x2=0
10 continue
isize=isize+1
arrayq(isize)=x2
15 continue
call unknown(x1,y1,ibig)
if(ibig.eq.1)then
goto 10
elseif(ibig.eq.2)then
isize=max(1,isize-1)
goto 15
endif
end subroutine bug1

View File

@ -774,7 +774,19 @@ update_value_range (const_tree var, value_range *new_vr)
{ {
value_range nr; value_range nr;
nr.type = rtype; nr.type = rtype;
/* 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;
else
nr.min = wide_int_to_tree (TREE_TYPE (var), min); 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;
else
nr.max = wide_int_to_tree (TREE_TYPE (var), max); nr.max = wide_int_to_tree (TREE_TYPE (var), max);
nr.equiv = NULL; nr.equiv = NULL;
vrp_intersect_ranges (new_vr, &nr); vrp_intersect_ranges (new_vr, &nr);
@ -1138,7 +1150,10 @@ operand_less_p (tree val, tree val2)
{ {
/* LT is folded faster than GE and others. Inline the common case. */ /* LT is folded faster than GE and others. Inline the common case. */
if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
{
if (! is_positive_overflow_infinity (val2))
return tree_int_cst_lt (val, val2); return tree_int_cst_lt (val, val2);
}
else else
{ {
tree tcmp; tree tcmp;
@ -1422,7 +1437,7 @@ static tree
value_range_constant_singleton (value_range *vr) value_range_constant_singleton (value_range *vr)
{ {
if (vr->type == VR_RANGE if (vr->type == VR_RANGE
&& operand_equal_p (vr->min, vr->max, 0) && vrp_operand_equal_p (vr->min, vr->max)
&& is_gimple_min_invariant (vr->min)) && is_gimple_min_invariant (vr->min))
return vr->min; return vr->min;
@ -7028,8 +7043,7 @@ vrp_valueize (tree name)
{ {
value_range *vr = get_value_range (name); value_range *vr = get_value_range (name);
if (vr->type == VR_RANGE if (vr->type == VR_RANGE
&& (vr->min == vr->max && vrp_operand_equal_p (vr->min, vr->max))
|| operand_equal_p (vr->min, vr->max, 0)))
return vr->min; return vr->min;
} }
return name; return name;
@ -7995,8 +8009,8 @@ union_ranges (enum value_range_type *vr0type,
enum value_range_type vr1type, enum value_range_type vr1type,
tree vr1min, tree vr1max) tree vr1min, tree vr1max)
{ {
bool mineq = operand_equal_p (*vr0min, vr1min, 0); bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
bool maxeq = operand_equal_p (*vr0max, vr1max, 0); bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
/* [] is vr0, () is vr1 in the following classification comments. */ /* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq) if (mineq && maxeq)
@ -8266,8 +8280,8 @@ intersect_ranges (enum value_range_type *vr0type,
enum value_range_type vr1type, enum value_range_type vr1type,
tree vr1min, tree vr1max) tree vr1min, tree vr1max)
{ {
bool mineq = operand_equal_p (*vr0min, vr1min, 0); bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
bool maxeq = operand_equal_p (*vr0max, vr1max, 0); bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
/* [] is vr0, () is vr1 in the following classification comments. */ /* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq) if (mineq && maxeq)
@ -8725,7 +8739,7 @@ vrp_visit_phi_node (gphi *phi)
print_gimple_stmt (dump_file, phi, 0, dump_flags); print_gimple_stmt (dump_file, phi, 0, dump_flags);
} }
bool may_simulate_again = false; bool may_simulate_backedge_again = false;
edges = 0; edges = 0;
for (i = 0; i < gimple_phi_num_args (phi); i++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
@ -8751,8 +8765,9 @@ vrp_visit_phi_node (gphi *phi)
/* See if we are eventually going to change one of the args. */ /* See if we are eventually going to change one of the args. */
gimple *def_stmt = SSA_NAME_DEF_STMT (arg); gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
if (! gimple_nop_p (def_stmt) if (! gimple_nop_p (def_stmt)
&& prop_simulate_again_p (def_stmt)) && prop_simulate_again_p (def_stmt)
may_simulate_again = true; && e->flags & EDGE_DFS_BACK)
may_simulate_backedge_again = true;
vr_arg = *(get_value_range (arg)); vr_arg = *(get_value_range (arg));
/* Do not allow equivalences or symbolic ranges to leak in from /* Do not allow equivalences or symbolic ranges to leak in from
@ -8830,13 +8845,12 @@ vrp_visit_phi_node (gphi *phi)
edge; this helps us avoid an overflow infinity for conditionals edge; this helps us avoid an overflow infinity for conditionals
which are not in a loop. If the old value-range was VR_UNDEFINED which are not in a loop. If the old value-range was VR_UNDEFINED
use the updated range and iterate one more time. If we will not use the updated range and iterate one more time. If we will not
simulate this PHI again with the same number of edges then iterate simulate this PHI again via the backedge allow us to iterate. */
one more time. */
if (edges > 0 if (edges > 0
&& gimple_phi_num_args (phi) > 1 && gimple_phi_num_args (phi) > 1
&& edges == old_edges && edges == old_edges
&& lhs_vr->type != VR_UNDEFINED && lhs_vr->type != VR_UNDEFINED
&& may_simulate_again) && may_simulate_backedge_again)
{ {
/* Compare old and new ranges, fall back to varying if the /* Compare old and new ranges, fall back to varying if the
values are not comparable. */ values are not comparable. */