]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[RISC-V][PR target/120137][PR target/120154] Don't create out-of-range permutation...
authorJeff Law <jlaw@ventanamicro.com>
Wed, 7 May 2025 21:06:58 +0000 (15:06 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 7 May 2025 21:06:58 +0000 (15:06 -0600)
To make hashing sensible we canonicalize constant vectors in the hash table so
that their first entry always has the value zero.  That normalization can
result in a value that can't be represented in the element mode.

So before entering anything into the hash table we need to verify the
normalized entries will fit into the element's mode.

This fixes both 120137 and its duplicate 120154.  This has been tested in my
tester.  I'm just waiting for the pre-commit tester to render its verdict.

PR target/120137
PR target/120154
gcc/
* config/riscv/riscv-vect-permconst.cc (process_bb): Verify each
canonicalized element fits into the vector element mode.

gcc/testsuite/

* gcc.target/riscv/pr120137.c: New test.
* gcc.target/riscv/pr120154.c: New test.

gcc/config/riscv/riscv-vect-permconst.cc
gcc/testsuite/gcc.target/riscv/pr120137.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/pr120154.c [new file with mode: 0644]

index feecc7ed6da03551024598359aeba239617dd88a..8e13cf8d558722dc0f9f757d9273081c572e1b64 100644 (file)
@@ -203,6 +203,24 @@ vector_permconst::process_bb (basic_block bb)
       if (bias < 0 || bias > 16384 / 8)
        continue;
 
+      /* We need to verify that each element would be a valid value
+        in the inner mode after applying the bias.  */
+      machine_mode inner = GET_MODE_INNER (GET_MODE (cvec));
+      HOST_WIDE_INT precision = GET_MODE_PRECISION (inner).to_constant ();
+      int i;
+      for (i = 0; i < CONST_VECTOR_NUNITS (cvec).to_constant (); i++)
+       {
+         HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (cvec, i)) - bias;
+         if (val != sext_hwi (val, precision))
+           break;
+       }
+
+      /* If the loop terminated early, then we found a case where the
+        adjusted constant would not fit, so we can't record the constant
+        for this case (it's unlikely to be useful anyway.  */
+      if (i != CONST_VECTOR_NUNITS (cvec).to_constant ())
+       continue;
+
       /* At this point we have a load of a constant integer vector from the
         constant pool.  That constant integer vector is hopefully a
         permutation constant.  We need to make a copy of the vector and
@@ -211,7 +229,7 @@ vector_permconst::process_bb (basic_block bb)
         XXX This violates structure sharing conventions.  */
       rtvec_def *nvec = gen_rtvec (CONST_VECTOR_NUNITS (cvec).to_constant ());
 
-      for (int i = 0; i < CONST_VECTOR_NUNITS (cvec).to_constant (); i++)
+      for (i = 0; i < CONST_VECTOR_NUNITS (cvec).to_constant (); i++)
        nvec->elem[i] = GEN_INT (INTVAL (CONST_VECTOR_ELT (cvec, i)) - bias);
 
       rtx copy = gen_rtx_CONST_VECTOR (GET_MODE (cvec), nvec);
diff --git a/gcc/testsuite/gcc.target/riscv/pr120137.c b/gcc/testsuite/gcc.target/riscv/pr120137.c
new file mode 100644 (file)
index 0000000..c55a1c1
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mrvv-vector-bits=zvl -mabi=lp64" } */
+
+char b[13][13];
+void c() {
+  for (int d = 0; d < 13; ++d)
+    for (int e = 0; e < 13; ++e)
+      b[d][e] = e == 0 ? -98 : 38;
+}
+
+
+
diff --git a/gcc/testsuite/gcc.target/riscv/pr120154.c b/gcc/testsuite/gcc.target/riscv/pr120154.c
new file mode 100644 (file)
index 0000000..fd849ca
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gv -mabi=lp64" } */
+
+
+
+typedef __attribute__((__vector_size__(4))) char V;
+
+V g;
+
+V
+bar(V a, V b)
+{
+  V s = a + b + g;
+  return s;
+}
+
+V
+foo()
+{
+  return bar((V){20}, (V){23, 150});
+}
+