From: TANG Tiancheng <tangtiancheng....@alibaba-inc.com> When allocating registers for input and output, ensure they match the available registers to avoid allocating illeagal registers.
We should respect RISC-V vector extension's variable-length registers and LMUL-based register grouping. Coordinate with tcg_target_available_regs initialization tcg_target_init (behind this commit) to ensure proper handling of vector register constraints. Note: While mov_vec doesn't have constraints, dup_vec and other IRs do. We need to strengthen constraints for all IRs except mov_vec, and this is sufficient. Signed-off-by: TANG Tiancheng <tangtiancheng....@alibaba-inc.com> Fixes: 29f5e92502 (tcg: Introduce paired register allocation) Reviewed-by: Liu Zhiwei <zhiwei_...@linux.alibaba.com> --- tcg/tcg.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 34e3056380..d26b42534d 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -4722,8 +4722,10 @@ static void tcg_reg_alloc_dup(TCGContext *s, const TCGOp *op) return; } - dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs; - dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs; + dup_out_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[0].regs & + tcg_target_available_regs[ots->type]; + dup_in_regs = tcg_op_defs[INDEX_op_dup_vec].args_ct[1].regs & + tcg_target_available_regs[its->type]; /* Allocate the output register now. */ if (ots->val_type != TEMP_VAL_REG) { @@ -4876,7 +4878,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) reg = ts->reg; i_preferred_regs = 0; - i_required_regs = arg_ct->regs; + i_required_regs = arg_ct->regs & tcg_target_available_regs[ts->type]; allocate_new_reg = false; copyto_new_reg = false; @@ -5078,6 +5080,7 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) /* satisfy the output constraints */ for(k = 0; k < nb_oargs; k++) { + TCGRegSet o_required_regs; i = def->args_ct[k].sort_index; arg = op->args[i]; arg_ct = &def->args_ct[i]; @@ -5085,17 +5088,19 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) /* ENV should not be modified. */ tcg_debug_assert(!temp_readonly(ts)); + o_required_regs = arg_ct->regs & + tcg_target_available_regs[ts->type]; switch (arg_ct->pair) { case 0: /* not paired */ if (arg_ct->oalias && !const_args[arg_ct->alias_index]) { reg = new_args[arg_ct->alias_index]; } else if (arg_ct->newreg) { - reg = tcg_reg_alloc(s, arg_ct->regs, + reg = tcg_reg_alloc(s, o_required_regs, i_allocated_regs | o_allocated_regs, output_pref(op, k), ts->indirect_base); } else { - reg = tcg_reg_alloc(s, arg_ct->regs, o_allocated_regs, + reg = tcg_reg_alloc(s, o_required_regs, o_allocated_regs, output_pref(op, k), ts->indirect_base); } break; @@ -5104,12 +5109,13 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op) if (arg_ct->oalias) { reg = new_args[arg_ct->alias_index]; } else if (arg_ct->newreg) { - reg = tcg_reg_alloc_pair(s, arg_ct->regs, + reg = tcg_reg_alloc_pair(s, o_required_regs, i_allocated_regs | o_allocated_regs, output_pref(op, k), ts->indirect_base); } else { - reg = tcg_reg_alloc_pair(s, arg_ct->regs, o_allocated_regs, + reg = tcg_reg_alloc_pair(s, o_required_regs, + o_allocated_regs, output_pref(op, k), ts->indirect_base); } -- 2.43.0