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.

Jeff


        PR target/120137
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.

diff --git a/gcc/config/riscv/riscv-vect-permconst.cc 
b/gcc/config/riscv/riscv-vect-permconst.cc
index feecc7ed6da..05819b3a30c 100644
--- a/gcc/config/riscv/riscv-vect-permconst.cc
+++ b/gcc/config/riscv/riscv-vect-permconst.cc
@@ -203,6 +203,25 @@ 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 +230,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
index 00000000000..c55a1c1b5bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr120137.c
@@ -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
index 00000000000..fd849ca154a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr120154.c
@@ -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});
+}
+

Reply via email to