Hi,

In PR120297 we fuse
 vsetvl e8,mf2,...
 vsetvl e64,m1,...
into
 vsetvl e64,m4,...

Individually, that's ok but we also change the new vsetvl's demand to
"SEW only" even though the first original one demanded SEW >= 8 and
ratio = 16.

As we forget the ratio after the merge we find that the vsetvl following
the merged one has ratio = 64 demand and we fuse into
 vsetvl e64,m1,..
which obviously doesn't have ratio = 16 any more.

Regtested on rv64gcv_zvl512b.

Regards
Robin

        PR target/120297

gcc/ChangeLog:

        * config/riscv/riscv-vsetvl.def: Do not forget ratio demand of
        previous vsetvl.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/pr120297.c: New test.
---
gcc/config/riscv/riscv-vsetvl.def             |  6 +--
gcc/testsuite/gcc.target/riscv/rvv/pr120297.c | 50 +++++++++++++++++++
2 files changed, 53 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/pr120297.c

diff --git a/gcc/config/riscv/riscv-vsetvl.def 
b/gcc/config/riscv/riscv-vsetvl.def
index d7a5ada772d..0f999d2276d 100644
--- a/gcc/config/riscv/riscv-vsetvl.def
+++ b/gcc/config/riscv/riscv-vsetvl.def
@@ -79,7 +79,7 @@ DEF_SEW_LMUL_RULE (sew_only, sew_only, sew_only, sew_eq_p, 
sew_eq_p, nop)
DEF_SEW_LMUL_RULE (sew_only, ge_sew, sew_only,
                   sew_ge_and_prev_sew_le_next_max_sew_p, sew_ge_p, nop)
DEF_SEW_LMUL_RULE (
-  sew_only, ratio_and_ge_sew, sew_lmul,
+  sew_only, ratio_and_ge_sew, ratio_and_ge_sew,
  sew_ge_and_prev_sew_le_next_max_sew_and_next_ratio_valid_for_prev_sew_p,
  always_false, modify_lmul_with_next_ratio)

@@ -104,9 +104,9 @@ DEF_SEW_LMUL_RULE (ratio_and_ge_sew, sew_lmul, sew_lmul,
DEF_SEW_LMUL_RULE (ratio_and_ge_sew, ratio_only, ratio_and_ge_sew, ratio_eq_p,
                   ratio_eq_p, use_max_sew_and_lmul_with_prev_ratio)
DEF_SEW_LMUL_RULE (
-  ratio_and_ge_sew, sew_only, sew_only,
+  ratio_and_ge_sew, sew_only, ratio_and_ge_sew,
  sew_le_and_next_sew_le_prev_max_sew_and_prev_ratio_valid_for_next_sew_p,
-  always_false, use_next_sew_with_prev_ratio)
+  sew_eq_p, use_next_sew_with_prev_ratio)
DEF_SEW_LMUL_RULE (ratio_and_ge_sew, ge_sew, ratio_and_ge_sew,
                   max_sew_overlap_and_prev_ratio_valid_for_next_sew_p,
                   sew_ge_p, use_max_sew_and_lmul_with_prev_ratio)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/pr120297.c 
b/gcc/testsuite/gcc.target/riscv/rvv/pr120297.c
new file mode 100644
index 00000000000..3d1845d0fe6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/pr120297.c
@@ -0,0 +1,50 @@
+/* { dg-do run } */
+/* { dg-require-effective-target riscv_v_ok } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fwhole-program" } */
+
+unsigned a;
+short c;
+char d;
+unsigned long e;
+_Bool f[10][10];
+unsigned g[10];
+long long ak;
+char i = 7;
+long long t[10];
+short x[10][10][10][10];
+short y[10][10][10][10];
+
+void
+h (char i, long long t[], short x[][10][10][10], short y[][10][10][10],
+   _Bool aa)
+{
+  for (int j = 2; j < 8; j += 2)
+    {
+      for (short k = 0; k < 10; k++)
+       {
+         for (int l = 3; l < 8; l += 2)
+           a = x[1][j][k][l];
+         c = x[c][1][1][c];
+       }
+      for (int k = 0; k < 10; k++)
+       {
+         f[2][k] |= (_Bool) t[c];
+         g[c] = t[c + 1];
+         d += y[j][1][k][k];
+         e = e > i ? e : i;
+       }
+    }
+}
+
+int
+main ()
+{
+  t[c] = 1;
+  h (i, t, x, y, a);
+  for (int j = 0; j < 10; ++j)
+    for (int k = 0; k < 10; ++k)
+      ak ^= f[j][k] + 238516665 + (ak >> 2);
+  ak ^= g[c] + 238516665 + (ak >> 2);
+  if (ak != 234635118ull)
+    __builtin_abort ();
+}
--
2.50.0

Reply via email to