tcg/riscv64/tcg-target.c.inc | 2 ++ 1 file changed, 2 insertions(+)
According to the RISC-V unpriviledge spec,
"vset{i}vl{i} and whole register loads and stores do not depend upon
vtype."
The whole-register vector move instructions reuqire legal vtype that
trap when VILL is set.
The tcg_out_mov in tcg/riscv64 missed the vtype setup before emitting the
OPC_VMVNR_V.
Fixes: d4be6ee1111 ("tcg/riscv: Implement vector mov/dup{m/i}")
Signed-off-by: Max Chou <max.chou@sifive.com>
---
tcg/riscv64/tcg-target.c.inc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
index 2ce9d47a633..fbfb4c44470 100644
--- a/tcg/riscv64/tcg-target.c.inc
+++ b/tcg/riscv64/tcg-target.c.inc
@@ -778,6 +778,8 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
{
int lmul = type - riscv_lg2_vlenb;
int nf = 1 << MAX(lmul, 0);
+
+ set_vtype_len(s, type);
tcg_out_opc_vi(s, OPC_VMVNR_V, ret, arg, nf - 1);
}
break;
--
2.43.0
On 9/3/26 07:00, Max Chou wrote:
> According to the RISC-V unpriviledge spec,
> "vset{i}vl{i} and whole register loads and stores do not depend upon
> vtype."
> The whole-register vector move instructions reuqire legal vtype that
> trap when VILL is set.
>
> The tcg_out_mov in tcg/riscv64 missed the vtype setup before emitting the
> OPC_VMVNR_V.
>
> Fixes: d4be6ee1111 ("tcg/riscv: Implement vector mov/dup{m/i}")
> Signed-off-by: Max Chou <max.chou@sifive.com>
> ---
> tcg/riscv64/tcg-target.c.inc | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
> index 2ce9d47a633..fbfb4c44470 100644
> --- a/tcg/riscv64/tcg-target.c.inc
> +++ b/tcg/riscv64/tcg-target.c.inc
> @@ -778,6 +778,8 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> {
> int lmul = type - riscv_lg2_vlenb;
> int nf = 1 << MAX(lmul, 0);
> +
> + set_vtype_len(s, type);
> tcg_out_opc_vi(s, OPC_VMVNR_V, ret, arg, nf - 1);
> }
> break;
If I understand correctly, this happens when vtype is completely unset,
such as the first use within the TB, or call-clobbered after a helper.
We don't actually need @type, just not the "uninitialized" type,
TCG_TYPE_COUNT, per init_setting_vtype.
That you encountered a reg-reg move in such a situation makes me wonder
if we have failed to correctly mark all of these vector registers
call-clobbered?
r~
On 2026-09-10 12:11, Richard Henderson wrote:
> On 9/3/26 07:00, Max Chou wrote:
> > According to the RISC-V unpriviledge spec,
> > "vset{i}vl{i} and whole register loads and stores do not depend upon
> > vtype."
> > The whole-register vector move instructions reuqire legal vtype that
> > trap when VILL is set.
> >
> > The tcg_out_mov in tcg/riscv64 missed the vtype setup before emitting the
> > OPC_VMVNR_V.
> >
> > Fixes: d4be6ee1111 ("tcg/riscv: Implement vector mov/dup{m/i}")
> > Signed-off-by: Max Chou <max.chou@sifive.com>
> > ---
> > tcg/riscv64/tcg-target.c.inc | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
> > index 2ce9d47a633..fbfb4c44470 100644
> > --- a/tcg/riscv64/tcg-target.c.inc
> > +++ b/tcg/riscv64/tcg-target.c.inc
> > @@ -778,6 +778,8 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> > {
> > int lmul = type - riscv_lg2_vlenb;
> > int nf = 1 << MAX(lmul, 0);
> > +
> > + set_vtype_len(s, type);
> > tcg_out_opc_vi(s, OPC_VMVNR_V, ret, arg, nf - 1);
> > }
> > break;
>
> If I understand correctly, this happens when vtype is completely unset, such
> as the first use within the TB, or call-clobbered after a helper.
>
> We don't actually need @type, just not the "uninitialized" type,
> TCG_TYPE_COUNT, per init_setting_vtype.
>
Hi Richard,
Thanks for the suggestion. Will send v2 for this part.
> That you encountered a reg-reg move in such a situation makes me wonder if
> we have failed to correctly mark all of these vector registers
> call-clobbered?
I just checked the tcg_target_init to confirm that all the vector
registers (v0-v31) are marked call-clobbered.
rnax
>
>
> r~
On Fri, 4 Sept 2026 at 02:30, Max Chou <max.chou@sifive.com> wrote:
>
> According to the RISC-V unpriviledge spec,
> "vset{i}vl{i} and whole register loads and stores do not depend upon
> vtype."
> The whole-register vector move instructions reuqire legal vtype that
> trap when VILL is set.
>
> The tcg_out_mov in tcg/riscv64 missed the vtype setup before emitting the
> OPC_VMVNR_V.
>
> Fixes: d4be6ee1111 ("tcg/riscv: Implement vector mov/dup{m/i}")
> Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Thanks! I had the same patch in my tree.
I hit a crash running qemu-x86_64 on top of qemu-system-riscv64 -cpu
rva23u64. Notably the spacemit K3 doesn't crash, but other (stricter)
implementations will.
Cheers,
Joel
On 9/3/2026 2:00 PM, Max Chou wrote:
> According to the RISC-V unpriviledge spec,
> "vset{i}vl{i} and whole register loads and stores do not depend upon
> vtype."
> The whole-register vector move instructions reuqire legal vtype that
> trap when VILL is set.
>
> The tcg_out_mov in tcg/riscv64 missed the vtype setup before emitting the
> OPC_VMVNR_V.
>
> Fixes: d4be6ee1111 ("tcg/riscv: Implement vector mov/dup{m/i}")
> Signed-off-by: Max Chou <max.chou@sifive.com>
> ---
Reviewed-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
> tcg/riscv64/tcg-target.c.inc | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
> index 2ce9d47a633..fbfb4c44470 100644
> --- a/tcg/riscv64/tcg-target.c.inc
> +++ b/tcg/riscv64/tcg-target.c.inc
> @@ -778,6 +778,8 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
> {
> int lmul = type - riscv_lg2_vlenb;
> int nf = 1 << MAX(lmul, 0);
> +
> + set_vtype_len(s, type);
> tcg_out_opc_vi(s, OPC_VMVNR_V, ret, arg, nf - 1);
> }
> break;
© 2016 - 2026 Red Hat, Inc.