@@ -4366,11 +4366,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn)
43664366 ir_backend_data *data = ctx->data;
43674367 dasm_State **Dst = &data->dasm_state;
43684368 ir_type type = insn->type;
4369- ir_reg def_reg = ctx->regs[def][0];
4369+ ir_reg def_reg = IR_REG_NUM( ctx->regs[def][0]) ;
43704370 ir_reg op2_reg = ctx->regs[def][2];
43714371 ir_reg tmp_reg = ctx->regs[def][3];
43724372 int32_t offset;
43734373
4374+ if (ctx->use_lists[def].count == 1) {
4375+ /* dead load */
4376+ return;
4377+ }
43744378 IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
43754379 if (op2_reg != IR_REG_NONE) {
43764380 if (IR_REG_SPILLED(op2_reg)) {
@@ -4394,11 +4398,15 @@ static void ir_emit_va_arg(ir_ctx *ctx, ir_ref def, ir_insn *insn)
43944398 ir_backend_data *data = ctx->data;
43954399 dasm_State **Dst = &data->dasm_state;
43964400 ir_type type = insn->type;
4397- ir_reg def_reg = ctx->regs[def][0];
4401+ ir_reg def_reg = IR_REG_NUM( ctx->regs[def][0]) ;
43984402 ir_reg op2_reg = ctx->regs[def][2];
43994403 ir_reg tmp_reg = ctx->regs[def][3];
44004404 int32_t offset;
44014405
4406+ if (ctx->use_lists[def].count == 1) {
4407+ /* dead load */
4408+ return;
4409+ }
44024410 IR_ASSERT(def_reg != IR_REG_NONE && tmp_reg != IR_REG_NONE);
44034411 if (op2_reg != IR_REG_NONE) {
44044412 if (IR_REG_SPILLED(op2_reg)) {
@@ -4935,6 +4943,28 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
49354943 return;
49364944 }
49374945
4946+ /* Move op2 to a tmp register before epilogue if it's in
4947+ * used_preserved_regs, because it will be overridden. */
4948+
4949+ ir_reg op2_reg = IR_REG_NONE;
4950+ if (!IR_IS_CONST_REF(insn->op2)) {
4951+ op2_reg = ctx->regs[def][2];
4952+ IR_ASSERT(op2_reg != IR_REG_NONE);
4953+
4954+ if (IR_REG_SPILLED(op2_reg)) {
4955+ op2_reg = IR_REG_INT_TMP;
4956+ ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
4957+ } else if (IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, IR_REG_NUM(op2_reg))) {
4958+ ir_reg orig_op2_reg = op2_reg;
4959+ op2_reg = IR_REG_INT_TMP;
4960+
4961+ ir_type type = ctx->ir_base[insn->op2].type;
4962+ | ASM_REG_REG_OP mov, type, op2_reg, IR_REG_NUM(orig_op2_reg)
4963+ } else {
4964+ op2_reg = IR_REG_NUM(op2_reg);
4965+ }
4966+ }
4967+
49384968 ir_emit_epilogue(ctx);
49394969
49404970 if (IR_IS_CONST_REF(insn->op2)) {
@@ -4947,13 +4977,8 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
49474977 | br Rx(IR_REG_INT_TMP)
49484978 }
49494979 } else {
4950- ir_reg op2_reg = ctx->regs[def][2];
4951-
49524980 IR_ASSERT(op2_reg != IR_REG_NONE);
4953- if (IR_REG_SPILLED(op2_reg)) {
4954- op2_reg = IR_REG_NUM(op2_reg);
4955- ir_emit_load(ctx, IR_ADDR, op2_reg, insn->op2);
4956- }
4981+ IR_ASSERT(!IR_REGSET_IN((ir_regset)ctx->used_preserved_regs, op2_reg));
49574982 | br Rx(op2_reg)
49584983 }
49594984}
0 commit comments