I think the "max poly value" is the LMUL 1 mode coeffs[1] See int vlenb = BYTES_PER_RISCV_VECTOR.coeffs[1];
So I think bump max_power to exact_log2 (64); is not enough. since we adjust the LMUL 1 mode size according to TARGET_MIN_VLEN. I suspect the testcase you append in this patch will fail with -march=rv64gcv_zvl4096b. I think it's more reasonable bump the max power into BYTES_PER_RISCV_VECTOR.coeffs[1] It should be more reasonable: + int max_power = exact_log2 (64); change it into + int max_power = exact_log2 (BYTES_PER_RISCV_VECTOR.coeffs[0]); juzhe.zh...@rivai.ai From: Kito Cheng Date: 2023-10-03 10:27 To: gcc-patches; kito.cheng; palmer; jeffreyalaw; rdapp; juzhe.zhong CC: Kito Cheng Subject: [PATCH] RISC-V: Fix the riscv_legitimize_poly_move issue on targets where the minimal VLEN exceeds 512. riscv_legitimize_poly_move was expected to ensure the poly value is at most 32 times smaller than the minimal VLEN (32 being derived from '4096 / 128'). This assumption held when our mode modeling was not so precisely defined. However, now that we have modeled the mode size according to the correct minimal VLEN info, the size difference between different RVV modes can be up to 64 times. For instance, comparing RVVMF64BI and RVVMF1BI, the sizes are [1, 1] versus [64, 64] respectively. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_legitimize_poly_move): Bump max_power to 64. gcc/testsuite/ChangeLog: * g++.target/riscv/rvv/autovec/bug-01.C: New. * g++.target/riscv/rvv/rvv.exp: Add autovec folder. --- gcc/config/riscv/riscv.cc | 7 ++-- .../g++.target/riscv/rvv/autovec/bug-01.C | 33 +++++++++++++++++++ gcc/testsuite/g++.target/riscv/rvv/rvv.exp | 3 ++ 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.target/riscv/rvv/autovec/bug-01.C diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index d5446b63dbf..6468702e3a3 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2386,9 +2386,10 @@ riscv_legitimize_poly_move (machine_mode mode, rtx dest, rtx tmp, rtx src) } else { - /* FIXME: We currently DON'T support TARGET_MIN_VLEN > 4096. */ - int max_power = exact_log2 (4096 / 128); - for (int i = 0; i < max_power; i++) + /* The size difference between different RVV modes can be up to 64 times. + e.g. RVVMF64BI vs RVVMF1BI on zvl512b, which is [1, 1] vs [64, 64]. */ + int max_power = exact_log2 (64); + for (int i = 0; i <= max_power; i++) { int possible_div_factor = 1 << i; if (factor % (vlenb / possible_div_factor) == 0) diff --git a/gcc/testsuite/g++.target/riscv/rvv/autovec/bug-01.C b/gcc/testsuite/g++.target/riscv/rvv/autovec/bug-01.C new file mode 100644 index 00000000000..fd10009ddbe --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/rvv/autovec/bug-01.C @@ -0,0 +1,33 @@ +/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3" } */ + +class c { +public: + int e(); + void j(); +}; +float *d; +class k { + int f; + +public: + k(int m) : f(m) {} + float g; + float h; + void n(int m) { + for (int i; i < m; i++) { + d[0] = d[1] = d[2] = g; + d[3] = h; + d += f; + } + } +}; +c l; +void o() { + int b = l.e(); + k a(b); + for (;;) + if (b == 4) { + l.j(); + a.n(2); + } +} diff --git a/gcc/testsuite/g++.target/riscv/rvv/rvv.exp b/gcc/testsuite/g++.target/riscv/rvv/rvv.exp index 249530580d7..c30d6e93144 100644 --- a/gcc/testsuite/g++.target/riscv/rvv/rvv.exp +++ b/gcc/testsuite/g++.target/riscv/rvv/rvv.exp @@ -40,5 +40,8 @@ set CFLAGS "-march=$gcc_march -O3" dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/base/*.C]] \ "" $CFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[C\]]] \ + "" $CFLAGS + # All done. dg-finish -- 2.40.1