re PR tree-optimization/76490 (when use -O2 -fcheck-founds compiler appears to hang...
authorRichard Biener <rguenther@suse.de>
Wed, 17 Aug 2016 11:51:51 +0000 (11:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 17 Aug 2016 11:51:51 +0000 (11:51 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr52904.c
gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 [new file with mode: 0644]
gcc/tree-vrp.c

index 01ad7e28a79109d2e7de4a972b325f9e874ed94d..5142c920e8ee73bf795289174dc08c85aa8202e2 100644 (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>
 
        * config/arm/t-aprofile (MULTILIB_EXCEPTIONS): Rewrite into ...
index ffa81389d16c4707dc691f7311bd7218ede4e76d..ed2ce1c12b344d4fd42732a6918f0dbca3365ece 100644 (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>
 
        PR tree-optimization/23855
index 107d89ee7d35117dc1185a29d417082189750616..2818c247b0aa26456e5b4f1812576727abf623ad 100644 (file)
@@ -14,7 +14,7 @@ wait_reading_process_output (void)
        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 0;
 }
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/pr76490.f90
new file mode 100644 (file)
index 0000000..aeb0717
--- /dev/null
@@ -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
index 6934914c149297883256836c83bd57e34185f333..a8810134b317211f64f722b70cb0a894401da06a 100644 (file)
@@ -774,8 +774,20 @@ update_value_range (const_tree var, value_range *new_vr)
        {
          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);
+         /* 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);
        }
@@ -1138,7 +1150,10 @@ operand_less_p (tree val, tree val2)
 {
   /* 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);
+    {
+      if (! is_positive_overflow_infinity (val2))
+       return tree_int_cst_lt (val, val2);
+    }
   else
     {
       tree tcmp;
@@ -1422,7 +1437,7 @@ static tree
 value_range_constant_singleton (value_range *vr)
 {
   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))
     return vr->min;
 
@@ -7028,8 +7043,7 @@ vrp_valueize (tree name)
     {
       value_range *vr = get_value_range (name);
       if (vr->type == VR_RANGE
-         && (vr->min == vr->max
-             || operand_equal_p (vr->min, vr->max, 0)))
+         && vrp_operand_equal_p (vr->min, vr->max))
        return vr->min;
     }
   return name;
@@ -7995,8 +8009,8 @@ union_ranges (enum value_range_type *vr0type,
              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);
+  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)
@@ -8266,8 +8280,8 @@ intersect_ranges (enum value_range_type *vr0type,
                  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);
+  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)
@@ -8725,7 +8739,7 @@ vrp_visit_phi_node (gphi *phi)
       print_gimple_stmt (dump_file, phi, 0, dump_flags);
     }
 
-  bool may_simulate_again = false;
+  bool may_simulate_backedge_again = false;
   edges = 0;
   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.  */
              gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
              if (! gimple_nop_p (def_stmt)
-                 && prop_simulate_again_p (def_stmt))
-               may_simulate_again = true;
+                 && 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
@@ -8830,13 +8845,12 @@ vrp_visit_phi_node (gphi *phi)
      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.  */
+     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_again)
+      && may_simulate_backedge_again)
     {
       /* Compare old and new ranges, fall back to varying if the
          values are not comparable.  */