[Patch] PR tree-optimization/68234 Improve range info for loop Phi node
authorRichard Biener <rguenth@gcc.gnu.org>
Wed, 11 Nov 2015 10:51:31 +0000 (10:51 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Wed, 11 Nov 2015 10:51:31 +0000 (10:51 +0000)
2015-11-11  Richard Biener  <rguenth@gcc.gnu.org>
    Jiong Wang      <jiong.wang@arm.com>
gcc/
  PR tree-optimization/68234
  * tree-vrp.c (vrp_visit_phi_node): Extend SCEV check to those loop PHI
  node which estimiated to be VR_VARYING initially.

gcc/testsuite/
  * gcc.dg/tree-ssa/pr68234.c: New testcase.

Co-Authored-By: Jiong Wang <jiong.wang@arm.com>
From-SVN: r230150

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr68234.c [new file with mode: 0644]
gcc/tree-vrp.c

index 21ea2f07d08ffd812374bfcdf694717eddd9eaf1..ad69a402d51da9b47b31e291cb4b44d4ee87dbe3 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-11  Richard Biener  <rguenth@gcc.gnu.org>
+           Jiong Wang      <jiong.wang@arm.com>
+
+       PR tree-optimization/68234
+       * tree-vrp.c (vrp_visit_phi_node): Extend SCEV check to those loop PHI
+       node which estimiated to be VR_VARYING initially.
+
 2015-11-11  Robert Suchanek  <robert.suchanek@imgtec.com>
 
        * regname.c (scan_rtx_reg): Check the matching number of consecutive
index 9778c940c256a0fbbb58d0458204a2549ccb6dbf..59cae93a19b572d674786eb10b1ea4d92966e05a 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-11  Richard Biener  <rguenth@gcc.gnu.org>
+           Jiong Wang      <jiong.wang@arm.com>
+
+       * gcc.dg/tree-ssa/pr68234.c: New testcase. 
+
 2015-11-10  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gcc.dg/goacc/nvptx-opt-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68234.c
new file mode 100644 (file)
index 0000000..e7c2a95
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp2" } */
+
+extern int nc;
+void ff (unsigned long long);
+
+void
+f (void)
+{
+  unsigned char resp[1024];
+  int c;
+  int bl = 0;
+  unsigned long long *dwords = (unsigned long long *) (resp + 5);
+  for (c = 0; c < nc; c++)
+    {
+      /* PR middle-end/68234, this signed division should be optimized into
+        right shift as vrp pass should deduct range info of 'bl' falls into
+        positive number.  */
+      ff (dwords[bl / 64]);
+      bl++;
+    }
+}
+
+/* { dg-final { scan-tree-dump ">> 6" "vrp2" } } */
index 87c02654c488e24b3a1539424bf65856ca3f2132..e2393e4d3a06c184ef5e4a27e9e931022e137cb9 100644 (file)
@@ -8810,20 +8810,11 @@ vrp_visit_phi_node (gphi *phi)
 
       /* If we dropped either bound to +-INF then if this is a loop
         PHI node SCEV may known more about its value-range.  */
-      if ((cmp_min > 0 || cmp_min < 0
+      if (cmp_min > 0 || cmp_min < 0
           || cmp_max < 0 || cmp_max > 0)
-         && (l = loop_containing_stmt (phi))
-         && l->header == gimple_bb (phi))
-       adjust_range_with_scev (&vr_result, l, phi, lhs);
-
-      /* If we will end up with a (-INF, +INF) range, set it to
-        VARYING.  Same if the previous max value was invalid for
-        the type and we end up with vr_result.min > vr_result.max.  */
-      if ((vrp_val_is_max (vr_result.max)
-          && vrp_val_is_min (vr_result.min))
-         || compare_values (vr_result.min,
-                            vr_result.max) > 0)
-       goto varying;
+       goto scev_check;
+
+      goto infinite_check;
     }
 
   /* If the new range is different than the previous value, keep
@@ -8849,8 +8840,28 @@ update_range:
   /* Nothing changed, don't add outgoing edges.  */
   return SSA_PROP_NOT_INTERESTING;
 
-  /* No match found.  Set the LHS to VARYING.  */
 varying:
+  set_value_range_to_varying (&vr_result);
+
+scev_check:
+  /* If this is a loop PHI node SCEV may known more about its value-range.
+     scev_check can be reached from two paths, one is a fall through from above
+     "varying" label, the other is direct goto from code block which tries to
+     avoid infinite simulation.  */
+  if ((l = loop_containing_stmt (phi))
+      && l->header == gimple_bb (phi))
+    adjust_range_with_scev (&vr_result, l, phi, lhs);
+
+infinite_check:
+  /* If we will end up with a (-INF, +INF) range, set it to
+     VARYING.  Same if the previous max value was invalid for
+     the type and we end up with vr_result.min > vr_result.max.  */
+  if ((vr_result.type == VR_RANGE || vr_result.type == VR_ANTI_RANGE)
+      && !((vrp_val_is_max (vr_result.max) && vrp_val_is_min (vr_result.min))
+          || compare_values (vr_result.min, vr_result.max) > 0))
+    goto update_range;
+
+  /* No match found.  Set the LHS to VARYING.  */
   set_value_range_to_varying (lhs_vr);
   return SSA_PROP_VARYING;
 }