[PATCH] tcg/riscv64: Set vtype before whole-register vector moves

Max Chou posted 1 patch 3 weeks, 2 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260903170011.3627720-1-max.chou@sifive.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <Alistair.Francis@wdc.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Richard Henderson <richard.henderson@linaro.org>
There is a newer version of this series
tcg/riscv64/tcg-target.c.inc | 2 ++
1 file changed, 2 insertions(+)
[PATCH] tcg/riscv64: Set vtype before whole-register vector moves
Posted by Max Chou 3 weeks, 2 days ago
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
Re: [PATCH] tcg/riscv64: Set vtype before whole-register vector moves
Posted by Richard Henderson 2 weeks, 1 day ago
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~
Re: [PATCH] tcg/riscv64: Set vtype before whole-register vector moves
Posted by Max Chou 1 week, 4 days ago
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~
Re: [PATCH] tcg/riscv64: Set vtype before whole-register vector moves
Posted by Joel Stanley 2 weeks, 4 days ago
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
Re: [PATCH] tcg/riscv64: Set vtype before whole-register vector moves
Posted by Daniel Henrique Barboza 2 weeks, 5 days ago

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;