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..d8cc2858541 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 ( V64QImode, QImode, V64QImode); + test_vectorize_related_mode ( V64QImode, HImode, V32HImode); + test_vectorize_related_mode ( V64QImode, SImode, V16SImode); + test_vectorize_related_mode ( V64QImode, 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 b30a95d0e3f..012ca5918cb 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -3064,7 +3064,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) / BITS_PER_UNIT, 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