diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index b5022636536..25c6904f1d5 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4808,14 +4808,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op2_info = OP2_INFO(); zend_jit_addr ref_addr = 0; - if (ra - && ssa_op->op2_def >= 0 - && (!ssa->vars[ssa_op->op2_def].no_val - || (zend_jit_trace_type_to_info(STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var))) & MAY_BE_ANY) != - (op2_info & MAY_BE_ANY))) { - op2_def_addr = OP2_DEF_REG_ADDR(); - } else { + if (ssa_op->op2_def < 0 || (Z_MODE(op2_addr) == IS_REG && ssa->vars[ssa_op->op2_def].no_val)) { op2_def_addr = op2_addr; + } else { + op2_def_addr = OP2_DEF_REG_ADDR(); } CHECK_OP2_TRACE_TYPE(); op1_info = OP1_INFO(); @@ -4910,12 +4906,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par ZEND_FALLTHROUGH; case ZEND_QM_ASSIGN: op1_addr = OP1_REG_ADDR(); - if (ra - && ssa_op->op1_def >= 0 - && !ssa->vars[ssa_op->op1_def].no_val) { - op1_def_addr = OP1_DEF_REG_ADDR(); - } else { + if (ssa_op->op1_def < 0 || (Z_MODE(op1_addr) == IS_REG && ssa->vars[ssa_op->op1_def].no_val)) { op1_def_addr = op1_addr; + } else { + op1_def_addr = OP1_DEF_REG_ADDR(); } op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); @@ -5008,14 +5002,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par break; } op1_addr = OP1_REG_ADDR(); - if (ra - && ssa_op->op1_def >= 0 - && (!ssa->vars[ssa_op->op1_def].no_val - || STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) == IS_UNKNOWN - || STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) >= IS_STRING)) { - op1_def_addr = OP1_DEF_REG_ADDR(); - } else { + if (ssa_op->op1_def < 0 || (Z_MODE(op1_addr) == IS_REG && ssa->vars[ssa_op->op1_def].no_val)) { op1_def_addr = op1_addr; + } else { + op1_def_addr = OP1_DEF_REG_ADDR(); } op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); @@ -6195,7 +6185,14 @@ done: SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var), type, (gen_handler || type == IS_UNKNOWN || !ra || (!RA_HAS_REG(ssa_op->op1_def) && - (opline->opcode == ZEND_ASSIGN || !ssa->vars[ssa_op->op1_def].no_val)))); + !(ssa->vars[ssa_op->op1_def].no_val && + Z_MODE(OP1_REG_ADDR()) == IS_REG && + (opline->opcode == ZEND_QM_ASSIGN || + opline->opcode == ZEND_SEND_VAR || + opline->opcode == ZEND_SEND_VAR_EX || + opline->opcode == ZEND_SEND_VAR_NO_REF || + opline->opcode == ZEND_SEND_VAR_NO_REF_EX || + opline->opcode == ZEND_SEND_FUNC_ARG))))); if (type != IS_UNKNOWN) { ssa->var_info[ssa_op->op1_def].type &= ~MAY_BE_GUARD; if (ra && RA_HAS_REG(ssa_op->op1_def)) { @@ -6241,7 +6238,10 @@ done: } SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->op2.var), type, (gen_handler || type == IS_UNKNOWN || !ra || - (!RA_HAS_REG(ssa_op->op2_def) /*&& !ssa->vars[ssa_op->op2_def].no_val*/))); + (!RA_HAS_REG(ssa_op->op2_def) && + !(ssa->vars[ssa_op->op2_def].no_val && + Z_MODE(OP2_REG_ADDR()) == IS_REG && + opline->opcode == ZEND_ASSIGN)))); if (type != IS_UNKNOWN) { ssa->var_info[ssa_op->op2_def].type &= ~MAY_BE_GUARD; if (ra && RA_HAS_REG(ssa_op->op2_def)) { diff --git a/ext/opcache/tests/jit/assign_dim_017.phpt b/ext/opcache/tests/jit/assign_dim_017.phpt new file mode 100644 index 00000000000..cc5eef1265c --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_017.phpt @@ -0,0 +1,20 @@ +--TEST-- +JIT ASSIGN_DIM: 017 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file