This patch fixes 12 ICEs of "full coverage" testing:
Running target 
riscv-sim/-march=rv64gc_zve32f/-mabi=lp64d/-mcmodel=medlow/--param=riscv-autovec-lmul=dynamic/--param=riscv-autovec-preference=fixed-vlmax
FAIL: gcc.dg/torture/pr96513.c   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (internal compiler error: 
Segmentation fault)
FAIL: gcc.dg/torture/pr96513.c   -O3 -g  (internal compiler error: Segmentation 
fault)

Running target 
riscv-sim/-march=rv64gc_zve32f/-mabi=lp64d/-mcmodel=medlow/--param=riscv-autovec-lmul=m4/--param=riscv-autovec-preference=fixed-vlmax
FAIL: gcc.dg/torture/pr111048.c   -O2  (internal compiler error: Segmentation 
fault)
FAIL: gcc.dg/torture/pr111048.c   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (internal compiler error: 
Segmentation fault)
FAIL: gcc.dg/torture/pr111048.c   -O3 -g  (internal compiler error: 
Segmentation fault)

FAIL: gcc.dg/torture/pr96513.c   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (internal compiler error: 
Segmentation fault)
FAIL: gcc.dg/torture/pr96513.c   -O3 -g  (internal compiler error: Segmentation 
fault)

Running target 
riscv-sim/-march=rv64gc_zve32f/-mabi=lp64d/-mcmodel=medlow/--param=riscv-autovec-lmul=m8/--param=riscv-autovec-preference=fixed-vlmax
FAIL: gcc.dg/torture/pr96513.c   -O3 -fomit-frame-pointer -funroll-loops 
-fpeel-loops -ftracer -finline-functions  (internal compiler error: 
Segmentation fault)
FAIL: gcc.dg/torture/pr96513.c   -O3 -g  (internal compiler error: Segmentation 
fault)

Running target 
riscv-sim/-march=rv64gc_zve32f/-mabi=lp64d/-mcmodel=medlow/--param=riscv-autovec-preference=fixed-vlmax
FAIL: gcc.c-torture/execute/20000801-1.c   -O2  (internal compiler error: 
Segmentation fault)
FAIL: gcc.c-torture/execute/20000801-1.c   -O3 -fomit-frame-pointer 
-funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler 
error: Segmentation fault)
FAIL: gcc.c-torture/execute/20000801-1.c   -O3 -g  (internal compiler error: 
Segmentation fault)

The root cause of those ICEs is vector register size = 32bits, wheras scalar 
register size = 64bit.
That is, vector regsize < scalar regsize on -march=rv64gc_zve32f FIXED-VLMAX.

So the original natural regsize using scalar register size is incorrect. 
Instead, we should return minimum regsize between vector regsize and scalar 
regsize.

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_regmode_natural_size): Fix ICE for 
FIXED-VLMAX of -march=rv32gc_zve32f.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/autovec/bug-4.c: New test.
        * gcc.target/riscv/rvv/autovec/bug-5.c: New test.
        * gcc.target/riscv/rvv/autovec/bug-6.c: New test.

---
 gcc/config/riscv/riscv.cc                     | 12 ++++--
 .../gcc.target/riscv/rvv/autovec/bug-4.c      | 27 ++++++++++++
 .../gcc.target/riscv/rvv/autovec/bug-5.c      | 24 +++++++++++
 .../gcc.target/riscv/rvv/autovec/bug-6.c      | 42 +++++++++++++++++++
 4 files changed, 102 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-6.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3fef1ab1514..8ae65760b6e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -9621,10 +9621,10 @@ riscv_regmode_natural_size (machine_mode mode)
 
   if (riscv_v_ext_mode_p (mode))
     {
+      poly_uint64 size = GET_MODE_SIZE (mode);
       if (riscv_v_ext_tuple_mode_p (mode))
        {
-         poly_uint64 size
-           = GET_MODE_SIZE (riscv_vector::get_subpart_mode (mode));
+         size = GET_MODE_SIZE (riscv_vector::get_subpart_mode (mode));
          if (known_lt (size, BYTES_PER_RISCV_VECTOR))
            return size;
        }
@@ -9634,8 +9634,14 @@ riscv_regmode_natural_size (machine_mode mode)
          if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
            return BYTES_PER_RISCV_VECTOR;
        }
-      if (!GET_MODE_SIZE (mode).is_constant ())
+      if (!size.is_constant ())
        return BYTES_PER_RISCV_VECTOR;
+      else if (!riscv_v_ext_vls_mode_p (mode))
+       /* For -march=rv64gc_zve32f, the natural vector register size
+          is 32bits which is smaller than scalar register size, so we
+          return minimum size between vector register size and scalar
+          register size.  */
+       return MIN (size.to_constant (), UNITS_PER_WORD);
     }
   return UNITS_PER_WORD;
 }
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-4.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-4.c
new file mode 100644
index 00000000000..c860e92dc3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-4.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f -mabi=lp64d -O3 
--param=riscv-autovec-lmul=m8 --param=riscv-autovec-preference=fixed-vlmax" } */
+
+typedef struct {
+  short a;
+  short b;
+} c;
+c *d;
+int e, f, i, j, k, l, m, n, o, p;
+c g, h;
+void q() {
+  do {
+    if (o) {
+      (*d).a = (*d).b = d[e].a = d[e].a * 3 + 1 >> 15;
+      d[e].b = d[e].b * 3 + 1 >> 15;
+    }
+    n = -(d[e].b * g.b) >> 5;
+    m = d[e].b * g.a + 1 >> 5;
+    l = d[f].a * -d[f].b * h.b + 1 >> 5;
+    k = d[f].a * h.b + d[f].b * h.a + 1 >> 5;
+    j = n + l;
+    i = m - k;
+    (*d).a += j;
+    d[e].a -= i;
+    ++d;
+  } while (--p);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-5.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-5.c
new file mode 100644
index 00000000000..df16fb28c49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-5.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f -mabi=lp64d -O2 
--param=riscv-autovec-lmul=m4 --param=riscv-autovec-preference=fixed-vlmax" } */
+
+typedef unsigned char u8;
+
+__attribute__((noipa))
+static void check(const u8 * v) {
+    if (*v != 15) __builtin_trap();
+}
+
+__attribute__((noipa))
+static void bug(void) {
+    u8 in_lanes[32];
+    for (unsigned i = 0; i < 32; i += 2) {
+      in_lanes[i + 0] = 0;
+      in_lanes[i + 1] = ((u8)0xff) >> (i & 7);
+    }
+
+    check(&in_lanes[13]);
+  }
+
+int main() {
+    bug();
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-6.c 
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-6.c
new file mode 100644
index 00000000000..975c4816a28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/bug-6.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f -mabi=lp64d -O2 
--param=riscv-autovec-preference=fixed-vlmax" } */
+
+extern void abort(void);
+extern void exit(int);
+
+void
+foo (char *bp, unsigned n)
+{
+  register char c;
+  register char *ep = bp + n;
+  register char *sp;
+
+  while (bp < ep)
+    {
+      sp = bp + 3;
+      c = *sp;
+      *sp = *bp;
+      *bp++ = c;
+      sp = bp + 1;
+      c = *sp;
+      *sp = *bp;
+      *bp++ = c;
+      bp += 2;
+    }
+}
+
+int main(void)
+{
+  int one = 1;
+
+  if (sizeof(int) != 4 * sizeof(char))
+    exit(0);
+
+  foo((char *)&one, sizeof(one));
+  foo((char *)&one, sizeof(one));
+
+  if (one != 1)
+    abort();
+
+  exit(0);
+}
-- 
2.36.3

Reply via email to