This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR76490


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;
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]