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  <rguent...@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;
  }

Reply via email to