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.
* config/riscv/riscv.h (MAX_POLY_VARIANT): New.
gcc/testsuite/ChangeLog:
* g++.target/riscv/rvv/autovec/bug-01.C: New.
* g++.target/riscv/rvv/rvv.exp: Add autovec folder.
}
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++)
+ int max_power = exact_log2 (MAX_POLY_VARIANT);
+ for (int i = 0; i <= max_power; i++)
{
int possible_div_factor = 1 << i;
if (factor % (vlenb / possible_div_factor) == 0)
#define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_VECTOR)
#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE, riscv_vector::FRM_NONE}
+
+/* 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]. */
+#define MAX_POLY_VARIANT 64
+
#endif /* ! GCC_RISCV_H */
--- /dev/null
+/* { 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);
+ }
+}
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/base/*.C]] \
"" $CFLAGS
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[C\]]] \
+ "" $CFLAGS
+
# All done.
dg-finish