diff mbox series

[for-9.0,v13,4/8] target/riscv: always clear vstart in whole vec move insns

Message ID 20240313193059.405329-5-dbarboza@ventanamicro.com
State New
Headers show
Series riscv: set vstart_eq_zero on vector insns | expand

Commit Message

Daniel Henrique Barboza March 13, 2024, 7:30 p.m. UTC
These insns have 2 paths: we'll either have vstart already cleared if
vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
the 'vmvr_v' helper. The helper will clear vstart if it executes until
the end, or if vstart >= vl.

However, if vstart >= maxsz, the helper will be skipped, and vstart
won't be cleared since the helper is being responsible from doing it.

We want to make the helpers responsible to manage vstart, including
these corner cases, precisely to avoid these situations. Move the vstart
>= maxsz cond to the helper, and be sure to clear vstart if that
happens.  This way we're now 100% sure that vstart is being clearer in
the end of the execution, regardless of the path taken.

Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
 target/riscv/vector_helper.c            | 5 +++++
 2 files changed, 5 insertions(+), 3 deletions(-)

Comments

Richard Henderson March 13, 2024, 9:16 p.m. UTC | #1
On 3/13/24 09:30, Daniel Henrique Barboza wrote:
> These insns have 2 paths: we'll either have vstart already cleared if
> vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
> the 'vmvr_v' helper. The helper will clear vstart if it executes until
> the end, or if vstart >= vl.
> 
> However, if vstart >= maxsz, the helper will be skipped, and vstart
> won't be cleared since the helper is being responsible from doing it.
> 
> We want to make the helpers responsible to manage vstart, including
> these corner cases, precisely to avoid these situations. Move the vstart
>> = maxsz cond to the helper, and be sure to clear vstart if that
> happens.  This way we're now 100% sure that vstart is being clearer in
> the end of the execution, regardless of the path taken.
> 
> Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
>   target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
>   target/riscv/vector_helper.c            | 5 +++++
>   2 files changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 8c16a9f5b3..52c26a7834 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -3664,12 +3664,9 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a)               \
>                                vreg_ofs(s, a->rs2), maxsz, maxsz);        \
>               mark_vs_dirty(s);                                           \
>           } else {                                                        \
> -            TCGLabel *over = gen_new_label();                           \
> -            tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over);  \
>               tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
>                                  tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
>               mark_vs_dirty(s);                                           \
> -            gen_set_label(over);                                        \
>           }                                                               \
>           return true;                                                    \
>       }                                                                   \
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index b4360dbd52..7260a5972b 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -5163,6 +5163,11 @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
>   
>       VSTART_CHECK_EARLY_EXIT(env);
>   
> +    if (env->vstart >= maxsz) {
> +        env->vstart = 0;
> +        return;
> +    }

Did you need the VSTART_CHECK_EARLY_EXIT here then?
It certainly seems like the vstart >= vl check is redundant...


r~
Daniel Henrique Barboza March 13, 2024, 9:39 p.m. UTC | #2
On 3/13/24 18:16, Richard Henderson wrote:
> On 3/13/24 09:30, Daniel Henrique Barboza wrote:
>> These insns have 2 paths: we'll either have vstart already cleared if
>> vstart_eq_zero or we'll do a brcond to check if vstart >= maxsz to call
>> the 'vmvr_v' helper. The helper will clear vstart if it executes until
>> the end, or if vstart >= vl.
>>
>> However, if vstart >= maxsz, the helper will be skipped, and vstart
>> won't be cleared since the helper is being responsible from doing it.
>>
>> We want to make the helpers responsible to manage vstart, including
>> these corner cases, precisely to avoid these situations. Move the vstart
>>> = maxsz cond to the helper, and be sure to clear vstart if that
>> happens.  This way we're now 100% sure that vstart is being clearer in
>> the end of the execution, regardless of the path taken.
>>
>> Fixes: f714361ed7 ("target/riscv: rvv-1.0: implement vstart CSR")
>> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>> ---
>>   target/riscv/insn_trans/trans_rvv.c.inc | 3 ---
>>   target/riscv/vector_helper.c            | 5 +++++
>>   2 files changed, 5 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
>> index 8c16a9f5b3..52c26a7834 100644
>> --- a/target/riscv/insn_trans/trans_rvv.c.inc
>> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
>> @@ -3664,12 +3664,9 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a)               \
>>                                vreg_ofs(s, a->rs2), maxsz, maxsz);        \
>>               mark_vs_dirty(s);                                           \
>>           } else {                                                        \
>> -            TCGLabel *over = gen_new_label();                           \
>> -            tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over);  \
>>               tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
>>                                  tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
>>               mark_vs_dirty(s);                                           \
>> -            gen_set_label(over);                                        \
>>           }                                                               \
>>           return true;                                                    \
>>       }                                                                   \
>> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
>> index b4360dbd52..7260a5972b 100644
>> --- a/target/riscv/vector_helper.c
>> +++ b/target/riscv/vector_helper.c
>> @@ -5163,6 +5163,11 @@ void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
>>       VSTART_CHECK_EARLY_EXIT(env);
>> +    if (env->vstart >= maxsz) {
>> +        env->vstart = 0;
>> +        return;
>> +    }
> 
> Did you need the VSTART_CHECK_EARLY_EXIT here then?
> It certainly seems like the vstart >= vl check is redundant...

Hmm right. I thought about maxsz being calculated via vlmax, and vlmax not necessarily
being == vl ... but vlmax will be always >= vl. So the vstart >= vl check s supersed
by vstart >= maxsz.


I'll re-send. Thanks,

Daniel

> 
> 
> r~
diff mbox series

Patch

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 8c16a9f5b3..52c26a7834 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3664,12 +3664,9 @@  static bool trans_##NAME(DisasContext *s, arg_##NAME * a)               \
                              vreg_ofs(s, a->rs2), maxsz, maxsz);        \
             mark_vs_dirty(s);                                           \
         } else {                                                        \
-            TCGLabel *over = gen_new_label();                           \
-            tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over);  \
             tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \
                                tcg_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \
             mark_vs_dirty(s);                                           \
-            gen_set_label(over);                                        \
         }                                                               \
         return true;                                                    \
     }                                                                   \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b4360dbd52..7260a5972b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -5163,6 +5163,11 @@  void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
 
     VSTART_CHECK_EARLY_EXIT(env);
 
+    if (env->vstart >= maxsz) {
+        env->vstart = 0;
+        return;
+    }
+
     memcpy((uint8_t *)vd + H1(i),
            (uint8_t *)vs2 + H1(i),
            maxsz - startb);