This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR76490
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 17 Aug 2016 13:43:04 +0200 (CEST)
- Subject: Re: [PATCH] Fix PR76490
- Authentication-results: sourceware.org; auth=none
- References: <alpine.LSU.2.11.1608151506420.26629@t29.fhfr.qr>
On Mon, 15 Aug 2016, Richard Biener wrote:
>
> The following fixes PR76490 which happens because how VRP expects
> +INF vs. +INF(OVF) to behave wrt comparisons. I fixed all
> operand_equal_p cases that matter.
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
The following is what I applied - it adds more similar fixes and
has to XFAIL gcc.dg/pr52904.c because that was only "fixed" when
the bug was introduced.
Boostrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c.orig 2016-08-17 10:30:24.164280986 +0200
--- gcc/tree-vrp.c 2016-08-17 10:59:12.416332674 +0200
*************** update_value_range (const_tree var, valu
*** 775,782 ****
{
value_range nr;
nr.type = rtype;
! nr.min = wide_int_to_tree (TREE_TYPE (var), min);
! nr.max = wide_int_to_tree (TREE_TYPE (var), max);
nr.equiv = NULL;
vrp_intersect_ranges (new_vr, &nr);
}
--- 775,794 ----
{
value_range nr;
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);
! 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.equiv = NULL;
vrp_intersect_ranges (new_vr, &nr);
}
*************** operand_less_p (tree val, tree val2)
*** 1139,1145 ****
{
/* LT is folded faster than GE and others. Inline the common case. */
if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
! return tree_int_cst_lt (val, val2);
else
{
tree tcmp;
--- 1151,1160 ----
{
/* LT is folded faster than GE and others. Inline the common case. */
if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
! {
! if (! is_positive_overflow_infinity (val2))
! return tree_int_cst_lt (val, val2);
! }
else
{
tree tcmp;
*************** static tree
*** 1423,1429 ****
value_range_constant_singleton (value_range *vr)
{
if (vr->type == VR_RANGE
! && operand_equal_p (vr->min, vr->max, 0)
&& is_gimple_min_invariant (vr->min))
return vr->min;
--- 1438,1444 ----
value_range_constant_singleton (value_range *vr)
{
if (vr->type == VR_RANGE
! && vrp_operand_equal_p (vr->min, vr->max)
&& is_gimple_min_invariant (vr->min))
return vr->min;
*************** vrp_valueize (tree name)
*** 7006,7013 ****
{
value_range *vr = get_value_range (name);
if (vr->type == VR_RANGE
! && (vr->min == vr->max
! || operand_equal_p (vr->min, vr->max, 0)))
return vr->min;
}
return name;
--- 7021,7027 ----
{
value_range *vr = get_value_range (name);
if (vr->type == VR_RANGE
! && vrp_operand_equal_p (vr->min, vr->max))
return vr->min;
}
return name;
*************** union_ranges (enum value_range_type *vr0
*** 7973,7980 ****
enum value_range_type vr1type,
tree vr1min, tree vr1max)
{
! bool mineq = operand_equal_p (*vr0min, vr1min, 0);
! bool maxeq = operand_equal_p (*vr0max, vr1max, 0);
/* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq)
--- 7987,7994 ----
enum value_range_type vr1type,
tree vr1min, tree vr1max)
{
! bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
! bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
/* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq)
*************** intersect_ranges (enum value_range_type
*** 8244,8251 ****
enum value_range_type vr1type,
tree vr1min, tree vr1max)
{
! bool mineq = operand_equal_p (*vr0min, vr1min, 0);
! bool maxeq = operand_equal_p (*vr0max, vr1max, 0);
/* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq)
--- 8258,8265 ----
enum value_range_type vr1type,
tree vr1min, tree vr1max)
{
! bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
! bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
/* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq)
*************** vrp_visit_phi_node (gphi *phi)
*** 8703,8709 ****
print_gimple_stmt (dump_file, phi, 0, dump_flags);
}
! bool may_simulate_again = false;
edges = 0;
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
--- 8717,8723 ----
print_gimple_stmt (dump_file, phi, 0, dump_flags);
}
! bool may_simulate_backedge_again = false;
edges = 0;
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
*************** vrp_visit_phi_node (gphi *phi)
*** 8729,8736 ****
/* See if we are eventually going to change one of the args. */
gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
if (! gimple_nop_p (def_stmt)
! && prop_simulate_again_p (def_stmt))
! may_simulate_again = true;
vr_arg = *(get_value_range (arg));
/* Do not allow equivalences or symbolic ranges to leak in from
--- 8743,8751 ----
/* See if we are eventually going to change one of the args. */
gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
if (! gimple_nop_p (def_stmt)
! && prop_simulate_again_p (def_stmt)
! && e->flags & EDGE_DFS_BACK)
! may_simulate_backedge_again = true;
vr_arg = *(get_value_range (arg));
/* Do not allow equivalences or symbolic ranges to leak in from
*************** vrp_visit_phi_node (gphi *phi)
*** 8808,8820 ****
edge; this helps us avoid an overflow infinity for conditionals
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
! simulate this PHI again with the same number of edges then iterate
! one more time. */
if (edges > 0
&& gimple_phi_num_args (phi) > 1
&& edges == old_edges
&& lhs_vr->type != VR_UNDEFINED
! && may_simulate_again)
{
/* Compare old and new ranges, fall back to varying if the
values are not comparable. */
--- 8823,8834 ----
edge; this helps us avoid an overflow infinity for conditionals
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
! simulate this PHI again via the backedge allow us to iterate. */
if (edges > 0
&& gimple_phi_num_args (phi) > 1
&& edges == old_edges
&& lhs_vr->type != VR_UNDEFINED
! && may_simulate_backedge_again)
{
/* Compare old and new ranges, fall back to varying if the
values are not comparable. */
Index: gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 2016-08-17 11:11:06.016569077 +0200
***************
*** 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
Index: gcc/testsuite/gcc.dg/pr52904.c
===================================================================
*** gcc/testsuite/gcc.dg/pr52904.c.orig 2016-08-17 11:09:58.667791403 +0200
--- gcc/testsuite/gcc.dg/pr52904.c 2016-08-17 11:10:11.279937030 +0200
*************** wait_reading_process_output (void)
*** 14,20 ****
nfds++;
}
! if (nfds < 0) /* { dg-bogus "assuming signed overflow does not occur" } */
return 1;
return 0;
}
--- 14,20 ----
nfds++;
}
! if (nfds < 0) /* { dg-bogus "assuming signed overflow does not occur" "" { xfail *-*-* } } */
return 1;
return 0;
}