can_find_related_mode_p incorrectly handled VLS (Vector Length Specific)
types by using TARGET_MIN_VLEN directly, which is in bits, instead of
converting it to bytes as required.
This patch fixes the issue by dividing TARGET_MIN_VLEN by 8 to convert
from bits to bytes when calculating the number of units for VLS modes.
The fix enables proper vectorization for several test cases:
- zve32f-1.c: Now correctly finds vector mode for SF mode in foo3,
enabling vectorization of an additional loop.
- zve32f_zvl256b-1.c and zve32x_zvl256b-1.c: Added -mrvv-max-lmul=m2
option to handle V8SI[2] (vector array mode) requirements during
vectorizer analysis, which needs V16SI to pass, and V16SI was enabled
incorrectly before.
Changes since V4:
- Fix testsuite, also triaged why changed.
gcc/ChangeLog:
* config/riscv/riscv-selftests.cc (riscv_run_selftests): Call
run_vectorize_related_mode_selftests.
(test_vectorize_related_mode): New function to test
vectorize_related_mode behavior.
(run_vectorize_related_mode_selftests): New function to run all
vectorize_related_mode tests.
(run_vectorize_related_mode_vla_selftests): New function to test
VLA modes.
(run_vectorize_related_mode_vls_rv64gcv_selftests): New function to
test VLS modes on rv64gcv.
(run_vectorize_related_mode_vls_rv32gc_zve32x_zvl256b_selftests):
New function to test VLS modes on rv32gc_zve32x_zvl256b.
(run_vectorize_related_mode_vls_selftests): New function to run all
VLS mode tests.
* config/riscv/riscv-v.cc (can_find_related_mode_p): Fix VLS type
handling by converting TARGET_MIN_VLEN from bits to bytes.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/zve32f-1.c: Update expected
vectorization count from 2 to 3.
* gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c: Add
-mrvv-max-lmul=m2 option.
* gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c: Add
-mrvv-max-lmul=m2 option.
---
gcc/config/riscv/riscv-selftests.cc | 157 ++++++++++++++++++
gcc/config/riscv/riscv-v.cc | 2 +-
.../gcc.target/riscv/rvv/autovec/zve32f-1.c | 2 +-
.../riscv/rvv/autovec/zve32f_zvl256b-1.c | 2 +-
.../riscv/rvv/autovec/zve32x_zvl256b-1.c | 2 +-
5 files changed, 161 insertions(+), 4 deletions(-)
diff --git a/gcc/config/riscv/riscv-selftests.cc
b/gcc/config/riscv/riscv-selftests.cc
index 9ca1ffee394..eff7856f9e8 100644
--- a/gcc/config/riscv/riscv-selftests.cc
+++ b/gcc/config/riscv/riscv-selftests.cc
@@ -367,6 +367,162 @@ run_broadcast_selftests (void)
BROADCAST_TEST (MODE_VECTOR_FLOAT)
}
+static void
+test_vectorize_related_mode (machine_mode vec_mode, scalar_mode ele_mode,
+ machine_mode expected)
+{
+ opt_machine_mode result = riscv_vector::vectorize_related_mode (vec_mode,
+ ele_mode, 0);
+ machine_mode result_mode = result.else_void ();
+ ASSERT_TRUE (result_mode == expected);
+}
+
+static void
+run_vectorize_related_mode_vla_selftests (void)
+{
+ riscv_selftest_arch_abi_setter rv ("rv64imafdcv", ABI_LP64D);
+ enum rvv_max_lmul_enum backup_rvv_max_lmul = rvv_max_lmul;
+ rvv_max_lmul = RVV_M1;
+
+ test_vectorize_related_mode (RVVM1QImode, SImode, RVVM1SImode);
+ test_vectorize_related_mode (RVVM2QImode, SImode, RVVM1SImode);
+ test_vectorize_related_mode (RVVM4QImode, SImode, RVVM1SImode);
+ test_vectorize_related_mode (RVVM8QImode, SImode, RVVM1SImode);
+ test_vectorize_related_mode (RVVM8QImode, DImode, RVVM1DImode);
+ test_vectorize_related_mode (RVVM8QImode, QImode, RVVM1QImode);
+ test_vectorize_related_mode (RVVM8QImode, HImode, RVVM1HImode);
+
+ rvv_max_lmul = RVV_M2;
+
+ test_vectorize_related_mode (RVVM1QImode, SImode, RVVM2SImode);
+ test_vectorize_related_mode (RVVM2QImode, SImode, RVVM2SImode);
+ test_vectorize_related_mode (RVVM4QImode, SImode, RVVM2SImode);
+ test_vectorize_related_mode (RVVM8QImode, SImode, RVVM2SImode);
+ test_vectorize_related_mode (RVVM8QImode, DImode, RVVM2DImode);
+ test_vectorize_related_mode (RVVM8QImode, QImode, RVVM2QImode);
+ test_vectorize_related_mode (RVVM8QImode, HImode, RVVM2HImode);
+
+ rvv_max_lmul = RVV_M4;
+
+ test_vectorize_related_mode (RVVM1QImode, SImode, RVVM4SImode);
+ test_vectorize_related_mode (RVVM2QImode, SImode, RVVM4SImode);
+ test_vectorize_related_mode (RVVM4QImode, SImode, RVVM4SImode);
+ test_vectorize_related_mode (RVVM8QImode, SImode, RVVM4SImode);
+ test_vectorize_related_mode (RVVM8QImode, DImode, RVVM4DImode);
+ test_vectorize_related_mode (RVVM8QImode, QImode, RVVM4QImode);
+ test_vectorize_related_mode (RVVM8QImode, HImode, RVVM4HImode);
+
+ rvv_max_lmul = RVV_M8;
+
+ test_vectorize_related_mode (RVVM1QImode, SImode, RVVM4SImode);
+ test_vectorize_related_mode (RVVM2QImode, SImode, RVVM8SImode);
+ test_vectorize_related_mode (RVVM4QImode, SImode, RVVM8SImode);
+ test_vectorize_related_mode (RVVM8QImode, SImode, RVVM8SImode);
+ test_vectorize_related_mode (RVVM8QImode, DImode, RVVM8DImode);
+ test_vectorize_related_mode (RVVM8QImode, QImode, RVVM8QImode);
+ test_vectorize_related_mode (RVVM8QImode, HImode, RVVM8HImode);
+
+ rvv_max_lmul = backup_rvv_max_lmul;
+}
+
+static void
+run_vectorize_related_mode_vls_rv64gcv_selftests ()
+{
+ enum rvv_vector_bits_enum backup_rvv_vector_bits = rvv_vector_bits;
+ rvv_vector_bits = RVV_VECTOR_BITS_SCALABLE;
+ riscv_selftest_arch_abi_setter rv ("rv64imafdcv", ABI_LP64D);
+ enum rvv_max_lmul_enum backup_rvv_max_lmul = rvv_max_lmul;
+ rvv_max_lmul = RVV_M1;
+
+ test_vectorize_related_mode ( V16QImode, QImode, V16QImode);
+ test_vectorize_related_mode ( V16QImode, HImode, V8HImode);
+ test_vectorize_related_mode ( V16QImode, SImode, V4SImode);
+ test_vectorize_related_mode ( V16QImode, DImode, V2DImode);
+
+ rvv_max_lmul = RVV_M2;
+
+ test_vectorize_related_mode ( V32QImode, QImode, V32QImode);
+ test_vectorize_related_mode ( V32QImode, HImode, V16HImode);
+ test_vectorize_related_mode ( V32QImode, SImode, V8SImode);
+ test_vectorize_related_mode ( V32QImode, DImode, V4DImode);
+
+ rvv_max_lmul = RVV_M4;
+
+ test_vectorize_related_mode ( V128QImode, QImode, V64QImode);
+ test_vectorize_related_mode ( V128QImode, HImode, V32HImode);
+ test_vectorize_related_mode ( V128QImode, SImode, V16SImode);
+ test_vectorize_related_mode ( V128QImode, DImode, V8DImode);
+
+ rvv_max_lmul = RVV_M8;
+
+ test_vectorize_related_mode ( V128QImode, QImode, V128QImode);
+ test_vectorize_related_mode ( V128QImode, HImode, V64HImode);
+ test_vectorize_related_mode ( V128QImode, SImode, V32SImode);
+ test_vectorize_related_mode ( V128QImode, DImode, V16DImode);
+
+ rvv_vector_bits = backup_rvv_vector_bits;
+ rvv_max_lmul = backup_rvv_max_lmul;
+}
+
+static void
+run_vectorize_related_mode_vls_rv32gc_zve32x_zvl256b_selftests ()
+{
+ enum rvv_vector_bits_enum backup_rvv_vector_bits = rvv_vector_bits;
+ rvv_vector_bits = RVV_VECTOR_BITS_SCALABLE;
+ riscv_selftest_arch_abi_setter rv ("rv32gc_zve32x_zvl256b", ABI_ILP32D);
+ enum rvv_max_lmul_enum backup_rvv_max_lmul = rvv_max_lmul;
+ rvv_max_lmul = RVV_M1;
+
+ test_vectorize_related_mode ( V32QImode, QImode, V32QImode);
+ test_vectorize_related_mode ( V32QImode, HImode, V16HImode);
+ test_vectorize_related_mode ( V32QImode, SImode, V8SImode);
+ test_vectorize_related_mode ( V32QImode, DImode, VOIDmode);
+
+ test_vectorize_related_mode ( V16QImode, QImode, V16QImode);
+ test_vectorize_related_mode ( V16QImode, HImode, V16HImode);
+ test_vectorize_related_mode ( V16QImode, SImode, V8SImode);
+ test_vectorize_related_mode ( V16QImode, DImode, VOIDmode);
+
+ rvv_max_lmul = RVV_M2;
+
+ test_vectorize_related_mode ( V32QImode, QImode, V32QImode);
+ test_vectorize_related_mode ( V32QImode, HImode, V32HImode);
+ test_vectorize_related_mode ( V32QImode, SImode, V16SImode);
+ test_vectorize_related_mode ( V32QImode, DImode, VOIDmode);
+
+ rvv_max_lmul = RVV_M4;
+
+ test_vectorize_related_mode ( V128QImode, QImode, V128QImode);
+ test_vectorize_related_mode ( V128QImode, HImode, V64HImode);
+ test_vectorize_related_mode ( V128QImode, SImode, V32SImode);
+ test_vectorize_related_mode ( V128QImode, DImode, VOIDmode);
+
+ rvv_max_lmul = RVV_M8;
+
+ test_vectorize_related_mode ( V128QImode, QImode, V128QImode);
+ test_vectorize_related_mode ( V128QImode, HImode, V128HImode);
+ test_vectorize_related_mode ( V128QImode, SImode, V64SImode);
+ test_vectorize_related_mode ( V128QImode, DImode, VOIDmode);
+
+ rvv_vector_bits = backup_rvv_vector_bits;
+ rvv_max_lmul = backup_rvv_max_lmul;
+
+}
+
+static void
+run_vectorize_related_mode_vls_selftests (void)
+{
+ run_vectorize_related_mode_vls_rv64gcv_selftests ();
+ run_vectorize_related_mode_vls_rv32gc_zve32x_zvl256b_selftests ();
+}
+
+static void
+run_vectorize_related_mode_selftests (void)
+{
+ run_vectorize_related_mode_vla_selftests ();
+ run_vectorize_related_mode_vls_selftests ();
+}
+
namespace selftest {
/* Run all target-specific selftests. */
void
@@ -387,6 +543,7 @@ riscv_run_selftests (void)
run_poly_int_selftests ();
run_const_vector_selftests ();
run_broadcast_selftests ();
+ run_vectorize_related_mode_selftests ();
}
} // namespace selftest
#endif /* #if CHECKING_P */
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index edfb4ff4ba6..adb64c78a1b 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3047,7 +3047,7 @@ can_find_related_mode_p (machine_mode vector_mode,
scalar_mode element_mode,
GET_MODE_SIZE (element_mode), nunits))
return true;
if (riscv_v_ext_vls_mode_p (vector_mode)
- && multiple_p (TARGET_MIN_VLEN * TARGET_MAX_LMUL,
+ && multiple_p ((TARGET_MIN_VLEN * TARGET_MAX_LMUL) / 8,
GET_MODE_SIZE (element_mode), nunits))
return true;
return false;
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c
index 66b4dc636d3..4650b5e57ea 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c
@@ -3,4 +3,4 @@
#include "template-1.h"
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 2 "vect"
} } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops in function" 3 "vect"
} } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c
index e50af33f48b..5c253ce70c3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv32gc_zve32f_zvl256b -mabi=ilp32d
-mrvv-vector-bits=scalable -fdump-tree-vect-details" } */
+/* { dg-options "-march=rv32gc_zve32f_zvl256b -mabi=ilp32d
-mrvv-vector-bits=scalable -mrvv-max-lmul=m2 -fdump-tree-vect-details" } */
#include "template-1.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c
b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c
index 889689523c8..77f98acf87e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv32gc_zve32x_zvl256b -mabi=ilp32d
-mrvv-vector-bits=scalable -fdump-tree-vect-details" } */
+/* { dg-options "-march=rv32gc_zve32x_zvl256b -mabi=ilp32d
-mrvv-vector-bits=scalable -mrvv-max-lmul=m2 -fdump-tree-vect-details" } */
#include "template-1.h"
--
2.34.1