On 6/24/26 02:52, Richard Biener wrote:
Vectorizer pattern recog eventually feeds range_of_expr with both
pattern def expressions and pattern context stmts.  While that's
IMO not OK the ranger code has some existing defenses against
defs that do not reside in the IL.  Just those are incomplete.

The following makes them more robust.  I will cleanup the vectorizer
side of things on trunk.

I have documented gimple_ranger::range_of_expr as to how I understand
it works (the different range_of_* APIs seem to behave slightly
different - I find this confusing).  Esp. range_of_expr requires
a valid 'r' input range and the return value isn't always reflecting
that something was done.

range_of_expr does not require a valid input range.. none of them do.  It just requires R to be the right class of range to handle the expression being passed in.  They should all be more or less consistent.

The return value indicates whether the R passed in has had a value set or not.  This applies to all range_of_* routines.  IF you get TRUE back, you can use it.

The only way something like range_of_expr can return false is if the expression is not a supported by any of the range types, ie, like a vec or complex.




Bootstrap and regtest running on x86_64-unknown-linux-gnu.

OK for trunk and branches?

The testcase (and the unreduced code) only ICEs on the 15 branch
on aarch64 when building firefox.

Thanks,
Richard.

        PR tree-optimization/125953
        * gimple-range.cc (gimple_ranger::range_of_expr): Document.
        Fall back to global ranges if 'stmt' is not in the IL.

        * gcc.dg/torture/pr125953.c: New testcase.
---
  gcc/gimple-range.cc                     |  9 +++++++--
  gcc/testsuite/gcc.dg/torture/pr125953.c | 14 ++++++++++++++
  2 files changed, 21 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/gcc.dg/torture/pr125953.c

diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index bc3eaf9efda..9aa281261a2 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -78,6 +78,10 @@ gimple_ranger::const_query ()
    return m_cache.const_query ();
  }
+// Calculate a range of EXPR on stmt STMT and improve R with it.
+// If STMT is not specified fall back to use global ranges.
+// Return false if R cannot be improved.
+
  bool
  gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
  {
@@ -98,8 +102,9 @@ gimple_ranger::range_of_expr (vrange &r, tree expr, gimple 
*stmt)
        fputs ("\n", dump_file);
      }
- // If there is no statement, just get the global value.
-  if (!stmt)
+  // If there is no statement or stmt happens to be not in the IL,
+  // just get the global value.
+  if (!stmt || !gimple_bb (stmt))
      {
        value_range tmp (TREE_TYPE (expr));
        // If there is no global range for EXPR yet, try to evaluate it.
diff --git a/gcc/testsuite/gcc.dg/torture/pr125953.c 
b/gcc/testsuite/gcc.dg/torture/pr125953.c
new file mode 100644
index 00000000000..3a34bc3d676
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr125953.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8.3-a+sve2" { target aarch64-*-* } } */
+
+unsigned char *begin(unsigned char *out)
+{
+  int size_0_0_0;
+  unsigned char *kRow = begin(out);
+  unsigned char *currentRow = kRow;
+  for (int x = 0; x < size_0_0_0; ++x) {
+    char k = kRow ? kRow[x] : 5;
+    out[2] = currentRow[2] * k / 255;
+  }
+  return out;
+}

Reply via email to