@@ -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