If reinterpret vnx2bi as vnx16bi, vnx16bi must occupy no more of the underlying registers than vnx2bi.
Consider this following case: void test_vreinterpret_v_b64_i8m1 (uint8_t *in, int8_t *out) { vbool64_t vmask = __riscv_vlm_v_b64 (in, 2); vint8m1_t vout = __riscv_vreinterpret_v_b64_i8m1 (vmask); __riscv_vse8_v_i8m1(out, vout, 16); } compiler parameters: -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -O3 Compilation fails with: test_vreinterpret_v_b64_i8m1during RTL pass: expand test.c: In function 'test_vreinterpret_v_b64_i8m1': test.c:11:22: internal compiler error: in gen_lowpart_general, at rtlhooks.cc:57 11 | vint8m1_t vout = __riscv_vreinterpret_v_b64_i8m1(src); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0xf11876 gen_lowpart_general(machine_mode, rtx_def*) ../.././riscv-gcc/gcc/rtlhooks.cc:57 0x191435e gen_vreinterpretvnx16qi(rtx_def*, rtx_def*) ../.././riscv-gcc/gcc/config/riscv/vector.md:486 0xe08858 maybe_expand_insn(insn_code, unsigned int, expand_operand*) ../.././riscv-gcc/gcc/optabs.cc:8213 0x1471209 riscv_vector::function_expander::generate_insn(insn_code) ../.././riscv-gcc/gcc/config/riscv/riscv-vector-builtins.cc:3813 0x147629c riscv_vector::function_expander::expand() ../.././riscv-gcc/gcc/config/riscv/riscv-vector-builtins.h:520 0x147629c riscv_vector::expand_builtin(unsigned int, tree_node*, rtx_def*) ../.././riscv-gcc/gcc/config/riscv/riscv-vector-builtins.cc:4103 0x9868f9 expand_builtin(tree_node*, rtx_def*, rtx_def*, machine_mode, int) ../.././riscv-gcc/gcc/builtins.cc:7342 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_regmode_natural_size): set the natural size of vector mask mode to one rvv register. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vreinterpet-fixed.c: New test. --- gcc/config/riscv/riscv.cc | 4 ++++ .../gcc.target/riscv/rvv/autovec/vreinterpet-fixed.c | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vreinterpet-fixed.c diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 6eb63a9d4de..73454f65086 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -7362,6 +7362,10 @@ riscv_regmode_natural_size (machine_mode mode) anything smaller than that. */ /* ??? For now, only do this for variable-width RVV registers. Doing it for constant-sized registers breaks lower-subreg.c. */ + + if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) + return BYTES_PER_RISCV_VECTOR; + if (!riscv_vector_chunks.is_constant () && riscv_v_ext_mode_p (mode)) { if (riscv_v_ext_tuple_mode_p (mode)) diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vreinterpet-fixed.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vreinterpet-fixed.c new file mode 100644 index 00000000000..534d5fe0f0a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vreinterpet-fixed.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include "riscv_vector.h" + +void test_vreinterpret_v_b64_i8m1 (uint8_t *in, int8_t *out) +{ + vbool64_t vmask = __riscv_vlm_v_b64 (in, 2); + vint8m1_t vout = __riscv_vreinterpret_v_b64_i8m1 (vmask); + __riscv_vse8_v_i8m1(out, vout, 16); +} -- 2.17.1