diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 15705533dd621..f1f53667c8180 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -1697,8 +1697,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op break; } if (!zend_jit_assign_dim_op(&ctx, opline, - OP1_INFO(), OP1_DEF_INFO(), OP1_REG_ADDR(), OP2_INFO(), - OP1_DATA_INFO(), OP1_DATA_RANGE(), IS_UNKNOWN, + OP1_INFO(), OP1_DEF_INFO(), OP1_REG_ADDR(), + OP2_INFO(), (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0, + OP1_DATA_INFO(), OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), IS_UNKNOWN, zend_may_throw(opline, ssa_op, op_array, ssa))) { goto jit_failure; } diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index deebd6e401418..7f87a55867c4d 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -12978,9 +12978,20 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, return 1; } -static int zend_jit_assign_dim_op(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_info, uint32_t op1_def_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t op1_data_info, zend_ssa_range *op1_data_range, uint8_t dim_type, int may_throw) +static int zend_jit_assign_dim_op(zend_jit_ctx *jit, + const zend_op *opline, + uint32_t op1_info, + uint32_t op1_def_info, + zend_jit_addr op1_addr, + uint32_t op2_info, + zend_jit_addr op2_addr, + uint32_t op1_data_info, + zend_jit_addr op3_addr, + zend_ssa_range *op1_data_range, + uint8_t dim_type, + int may_throw) { - zend_jit_addr op2_addr, op3_addr, var_addr = IS_UNUSED; + zend_jit_addr var_addr = IS_UNUSED; const void *not_found_exit_addr = NULL; uint32_t var_info = MAY_BE_NULL; ir_ref if_type = IS_UNUSED; @@ -12989,9 +13000,6 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit, const zend_op *opline, uint ZEND_ASSERT(opline->result_type == IS_UNUSED); - op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0; - op3_addr = OP1_DATA_ADDR(); - jit_SET_EX_OPLINE(jit, opline); op1_addr = zend_jit_prepare_array_update(jit, opline, op1_info, op1_addr, &if_type, &ht_ref, &may_throw); @@ -13046,7 +13054,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit, const zend_op *opline, uint } if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_RW, op1_info, - op2_info, OP2_ADDR(), dim_type, NULL, not_found_exit_addr, NULL, + op2_info, op2_addr, dim_type, NULL, not_found_exit_addr, NULL, 0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) { return 0; } @@ -16597,6 +16605,14 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) && (((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) || ((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING)); + case ZEND_ASSIGN_DIM_OP: + if (opline->result_type != IS_UNUSED) { + return 0; + } + if (!zend_jit_supported_binary_op(opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { + return 0; + } + ZEND_FALLTHROUGH; case ZEND_ASSIGN_DIM: case ZEND_FETCH_DIM_W: case ZEND_FETCH_DIM_RW: @@ -16605,7 +16621,8 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa op2_info = OP2_INFO(); if (trace) { if (opline->op1_type == IS_CV) { - if (opline->opcode == ZEND_ASSIGN_DIM + if ((opline->opcode == ZEND_ASSIGN_DIM + || opline->opcode == ZEND_ASSIGN_DIM_OP) && (opline+1)->op1_type == IS_CV && (opline+1)->op1.var == opline->op1.var) { /* skip $a[x] = $a; */ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 6e4fb885b601f..8b1b0bd7e584e 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4639,8 +4639,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par CHECK_OP1_DATA_TRACE_TYPE(); op1_def_info = OP1_DEF_INFO(); if (!zend_jit_assign_dim_op(&ctx, opline, - op1_info, op1_def_info, op1_addr, op2_info, - op1_data_info, OP1_DATA_RANGE(), val_type, + op1_info, op1_def_info, op1_addr, + op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0, + op1_data_info, OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), val_type, zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info))) { goto jit_failure; }