Skip to content

Commit 4cf3da7

Browse files
committed
Keep value of register before possible side exit
1 parent 9b1c02c commit 4cf3da7

File tree

1 file changed

+27
-1
lines changed

1 file changed

+27
-1
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4162,6 +4162,22 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op
41624162
return 1;
41634163
}
41644164

4165+
static int zend_jit_opline_uses_reg(const zend_op *opline, int8_t reg)
4166+
{
4167+
if ((opline+1)->opcode == ZEND_OP_DATA
4168+
&& ((opline+1)->op1_type & (IS_VAR|IS_TMP_VAR|IS_CV))
4169+
&& JIT_G(current_frame)->stack[EX_VAR_TO_NUM((opline+1)->op1.var)].reg == reg) {
4170+
return 1;
4171+
}
4172+
return
4173+
((opline->result_type & (IS_VAR|IS_TMP_VAR|IS_CV)) &&
4174+
JIT_G(current_frame)->stack[EX_VAR_TO_NUM(opline->result.var)].reg == reg) ||
4175+
((opline->op1_type & (IS_VAR|IS_TMP_VAR|IS_CV)) &&
4176+
JIT_G(current_frame)->stack[EX_VAR_TO_NUM(opline->op1.var)].reg == reg) ||
4177+
((opline->op2_type & (IS_VAR|IS_TMP_VAR|IS_CV)) &&
4178+
JIT_G(current_frame)->stack[EX_VAR_TO_NUM(opline->op2.var)].reg == reg);
4179+
}
4180+
41654181
static int zend_jit_math_long_long(dasm_State **Dst,
41664182
const zend_op *opline,
41674183
zend_uchar opcode,
@@ -4176,7 +4192,14 @@ static int zend_jit_math_long_long(dasm_State **Dst,
41764192
zend_reg result_reg;
41774193

41784194
if (Z_MODE(res_addr) == IS_REG && (res_info & MAY_BE_LONG)) {
4179-
result_reg = Z_REG(res_addr);
4195+
if (may_overflow && (res_info & MAY_BE_GUARD)
4196+
&& JIT_G(current_frame)
4197+
&& JIT_G(current_frame)->stack
4198+
&& zend_jit_opline_uses_reg(opline, Z_REG(res_addr))) {
4199+
result_reg = ZREG_R0;
4200+
} else {
4201+
result_reg = Z_REG(res_addr);
4202+
}
41804203
} else if (Z_MODE(op1_addr) == IS_REG && Z_LAST_USE(op1_addr)) {
41814204
result_reg = Z_REG(op1_addr);
41824205
} else if (Z_REG(res_addr) != ZREG_R0) {
@@ -4247,6 +4270,9 @@ static int zend_jit_math_long_long(dasm_State **Dst,
42474270
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
42484271
if ((res_info & MAY_BE_ANY) == MAY_BE_LONG) {
42494272
| jo &exit_addr
4273+
if (Z_MODE(res_addr) == IS_REG && result_reg != Z_REG(res_addr)) {
4274+
| mov Ra(Z_REG(res_addr)), Ra(result_reg)
4275+
}
42504276
} else if ((res_info & MAY_BE_ANY) == MAY_BE_DOUBLE) {
42514277
| jno &exit_addr
42524278
} else {

0 commit comments

Comments
 (0)