On July 11, 2020 10:01:41 AM GMT+02:00, Richard Sandiford 
<richard.sandif...@arm.com> wrote:
>The range infrastructure has code to decompose POLY_INT_CST ranges
>to worst-case integer bounds.  However, it had the fundamental flaw
>(obvious in hindsight) that it applied to anti-ranges too, meaning
>that a range 2+2X would end up with a range of ~[2, +INF], i.e.
>[-INF, 1].  This patch decays to varying in that case instead.
>
>I'm still a bit uneasy about this.  ISTM that in terms of
>generality:
>
>  SSA_NAME => POLY_INT_CST => INTEGER_CST
>           => ADDR_EXPR
>
>I.e. an SSA_NAME could store a POLY_INT_CST and a POLY_INT_CST
>could store an INTEGER_CST (before canonicalisation).  POLY_INT_CST
>is also “as constant as” ADDR_EXPR (well, OK, only some ADDR_EXPRs
>are run-time rather than link-time constants, whereas all POLY_INT_CSTs
>are, but still).  So it seems like we should at least be able to treat
>POLY_INT_CST as symbolic.  On the other hand, I don't have any examples
>in which that would be useful.
>
>Tested on aarch64-linux-gnu and x86_64-linux-gnu.  OK for trunk and
>GCC 10?

OK. 

Thanks, 
Richard. 

>Richard
>
>
>gcc/
>       PR tree-optimization/96146
>       * value-range.cc (value_range::set): Only decompose POLY_INT_CST
>       bounds to integers for VR_RANGE.  Decay to VR_VARYING for anti-ranges
>       involving POLY_INT_CSTs.
>
>gcc/testsuite/
>       PR tree-optimization/96146
>       * gcc.target/aarch64/sve/acle/general/pr96146.c: New test.
>---
> .../aarch64/sve/acle/general/pr96146.c        | 20 ++++++++
> gcc/value-range.cc                            | 47 +++++++++++--------
> 2 files changed, 48 insertions(+), 19 deletions(-)
>create mode 100644
>gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr96146.c
>
>diff --git
>a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr96146.c
>b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr96146.c
>new file mode 100644
>index 00000000000..b05fac4918d
>--- /dev/null
>+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr96146.c
>@@ -0,0 +1,20 @@
>+/* { dg-do run { target aarch64_sve_hw } } */
>+/* { dg-options "-O3" } */
>+
>+#include <arm_sve.h>
>+
>+void __attribute__ ((noipa))
>+f (volatile int *x)
>+{
>+  int i;
>+  for (int i = 0; i < svcntd (); ++i)
>+    *x = i;
>+}
>+
>+int
>+main (void)
>+{
>+  volatile int x;
>+  f (&x);
>+  return 0;
>+}
>diff --git a/gcc/value-range.cc b/gcc/value-range.cc
>index 929a6b59aaf..bc4b061da57 100644
>--- a/gcc/value-range.cc
>+++ b/gcc/value-range.cc
>@@ -86,7 +86,34 @@ value_range::set (tree min, tree max,
>value_range_kind kind)
>       set_undefined ();
>       return;
>     }
>-  else if (kind == VR_VARYING)
>+
>+  if (kind == VR_RANGE)
>+    {
>+      /* Convert POLY_INT_CST bounds into worst-case INTEGER_CST
>bounds.  */
>+      if (POLY_INT_CST_P (min))
>+      {
>+        tree type_min = vrp_val_min (TREE_TYPE (min));
>+        widest_int lb
>+          = constant_lower_bound_with_limit (wi::to_poly_widest (min),
>+                                             wi::to_widest (type_min));
>+        min = wide_int_to_tree (TREE_TYPE (min), lb);
>+      }
>+      if (POLY_INT_CST_P (max))
>+      {
>+        tree type_max = vrp_val_max (TREE_TYPE (max));
>+        widest_int ub
>+          = constant_upper_bound_with_limit (wi::to_poly_widest (max),
>+                                             wi::to_widest (type_max));
>+        max = wide_int_to_tree (TREE_TYPE (max), ub);
>+      }
>+    }
>+  else if (kind != VR_VARYING)
>+    {
>+      if (POLY_INT_CST_P (min) || POLY_INT_CST_P (max))
>+      kind = VR_VARYING;
>+    }
>+
>+  if (kind == VR_VARYING)
>     {
>       gcc_assert (TREE_TYPE (min) == TREE_TYPE (max));
>       tree typ = TREE_TYPE (min);
>@@ -99,24 +126,6 @@ value_range::set (tree min, tree max,
>value_range_kind kind)
>       return;
>     }
> 
>-  /* Convert POLY_INT_CST bounds into worst-case INTEGER_CST bounds. 
>*/
>-  if (POLY_INT_CST_P (min))
>-    {
>-      tree type_min = vrp_val_min (TREE_TYPE (min));
>-      widest_int lb
>-      = constant_lower_bound_with_limit (wi::to_poly_widest (min),
>-                                         wi::to_widest (type_min));
>-      min = wide_int_to_tree (TREE_TYPE (min), lb);
>-    }
>-  if (POLY_INT_CST_P (max))
>-    {
>-      tree type_max = vrp_val_max (TREE_TYPE (max));
>-      widest_int ub
>-      = constant_upper_bound_with_limit (wi::to_poly_widest (max),
>-                                         wi::to_widest (type_max));
>-      max = wide_int_to_tree (TREE_TYPE (max), ub);
>-    }
>-
>   /* Nothing to canonicalize for symbolic ranges.  */
>   if (TREE_CODE (min) != INTEGER_CST
>       || TREE_CODE (max) != INTEGER_CST)

Reply via email to