I think this part is no contirvatial, so I will commit this patch after CI passes.
On Wed, Sep 10, 2025 at 6:13 PM Kito Cheng <kito.ch...@sifive.com> wrote: > > 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 >