]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/125953 - ICE with vector pattern stmts range query
authorRichard Biener <rguenther@suse.de>
Wed, 24 Jun 2026 06:45:37 +0000 (08:45 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 25 Jun 2026 07:26:50 +0000 (09:26 +0200)
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.

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
gcc/testsuite/gcc.dg/torture/pr125953.c [new file with mode: 0644]

index bc3eaf9efdaf03441b896527acf15ce85a87e797..b8b98dc8131fe0d005299a39b8317bdf2c8771c5 100644 (file)
@@ -78,6 +78,9 @@ gimple_ranger::const_query ()
   return m_cache.const_query ();
 }
 
+// Implement range of EXPR on stmt S, and return it in R.
+// Return false if no range can be calculated.
+
 bool
 gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
 {
@@ -98,8 +101,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 (file)
index 0000000..3a34bc3
--- /dev/null
@@ -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;
+}