]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Fix can_find_related_mode_p for VLS types
authorKito Cheng <kito.cheng@sifive.com>
Thu, 14 Aug 2025 13:29:38 +0000 (21:29 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Thu, 11 Sep 2025 07:17:32 +0000 (15:17 +0800)
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
gcc/config/riscv/riscv-v.cc
gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f-1.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32f_zvl256b-1.c
gcc/testsuite/gcc.target/riscv/rvv/autovec/zve32x_zvl256b-1.c

index 9ca1ffee394fac83a757183df2d55eeea23b1c16..d8cc2858541ad05c3ee7787bcf537fd8741bd889 100644 (file)
@@ -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 */
index b30a95d0e3f1b7e17eb945b038f6aeada1f3cb8e..012ca5918cb2117e3c312f2fb705aed55196211c 100644 (file)
@@ -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;
index 66b4dc636d3fdf281cae9d14437cf925ab78426b..4650b5e57eabf2f81c4728d4f9fd08c31dd00bdc 100644 (file)
@@ -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" } } */
index e50af33f48b81f8c82ea4f12ccbfcf188ee6a591..5c253ce70c30d1ebbdf2a73374e276b01b02d0b2 100644 (file)
@@ -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"
 
index 889689523c85b94851fa0f0bef78af61c4f007f1..77f98acf87e0b950a4e0b7a139bfc0337dca6e50 100644 (file)
@@ -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"