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
>

Reply via email to