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


Reply via email to