diff --git a/ext/opcache/jit/zend_jit_arm64.dasc b/ext/opcache/jit/zend_jit_arm64.dasc index 9c94a3a0b74..6d6bc471ec2 100644 --- a/ext/opcache/jit/zend_jit_arm64.dasc +++ b/ext/opcache/jit/zend_jit_arm64.dasc @@ -3615,6 +3615,18 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + if (!Z_LOAD(src) && !Z_STORE(src) && Z_STORE(dst)) { + zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + + if (!zend_jit_spill_store(Dst, dst, var_addr, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } + } } else if (Z_MODE(dst) == IS_MEM_ZVAL) { if (!Z_LOAD(src) && !Z_STORE(src)) { if (!zend_jit_spill_store(Dst, src, dst, info, diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 51b11aac6c7..177c7478b3d 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4119,7 +4119,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ssa->var_info[i].type &= ~MAY_BE_GUARD; op_type = concrete_type(ssa->var_info[i].type); - if (!zend_jit_type_guard(&dasm_state, opline, i, op_type)) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(i), op_type)) { goto jit_failure; } SET_STACK_TYPE(stack, i, op_type, 1); @@ -4152,7 +4152,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ZEND_ASSERT(ival->reg != ZREG_NONE); if (info & MAY_BE_GUARD) { - if (!zend_jit_type_guard(&dasm_state, opline, phi->var, concrete_type(info))) { + if (!zend_jit_type_guard(&dasm_state, opline, EX_NUM_TO_VAR(phi->var), concrete_type(info))) { goto jit_failure; } info &= ~MAY_BE_GUARD; @@ -6270,8 +6270,7 @@ done: || opline->opcode == ZEND_COALESCE || opline->opcode == ZEND_JMP_NULL || opline->opcode == ZEND_FE_RESET_R) { - if (!ra[ssa_op->op1_use] - || ra[ssa_op->op1_use]->reg != ra[ssa_op->op1_def]->reg) { + if (!ra[ssa_op->op1_use]) { flags |= ZREG_LOAD; } } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 20d76010c2e..2de49f11f24 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3955,6 +3955,18 @@ static int zend_jit_update_regs(dasm_State **Dst, uint32_t var, zend_jit_addr sr } else { ZEND_UNREACHABLE(); } + if (!Z_LOAD(src) && !Z_STORE(src) && Z_STORE(dst)) { + zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, var); + + if (!zend_jit_spill_store(Dst, dst, var_addr, info, + JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || + JIT_G(current_frame) == NULL || + STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var)) == IS_UNKNOWN || + (1 << STACK_MEM_TYPE(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(var))) != (info & MAY_BE_ANY) + )) { + return 0; + } + } } else if (Z_MODE(dst) == IS_MEM_ZVAL) { if (!Z_LOAD(src) && !Z_STORE(src)) { if (!zend_jit_spill_store(Dst, src, dst, info, diff --git a/ext/opcache/tests/jit/reg_alloc_007.phpt b/ext/opcache/tests/jit/reg_alloc_007.phpt new file mode 100644 index 00000000000..2c9f13943d7 --- /dev/null +++ b/ext/opcache/tests/jit/reg_alloc_007.phpt @@ -0,0 +1,26 @@ +--TEST-- +Register Alloction 007: Missing store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $a in %sreg_alloc_007.php on line 4 + +Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %sreg_alloc_007.php:6 +Stack trace: +#0 %sreg_alloc_007.php(9): test() +#1 {main} + thrown in %sreg_alloc_007.php on line 6