@@ -11389,6 +11389,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit,
11389
11389
uint32_t op1_info,
11390
11390
uint32_t op2_info,
11391
11391
zend_jit_addr op2_addr,
11392
+ zend_ssa_range *op2_range,
11392
11393
uint8_t dim_type,
11393
11394
const void *found_exit_addr,
11394
11395
const void *not_found_exit_addr,
@@ -11489,9 +11490,16 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit,
11489
11490
// JIT: if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed))
11490
11491
ref = ir_LOAD_U32(ir_ADD_OFFSET(ht_ref, offsetof(zend_array, nNumUsed)));
11491
11492
#if SIZEOF_ZEND_LONG == 8
11492
- ref = ir_ZEXT_L(ref);
11493
- #endif
11493
+ if ((Z_MODE(op2_addr) == IS_CONST_ZVAL && val >= 0 && val <= UINT32_MAX)
11494
+ || (op2_range && op2_range->min >= 0 && op2_range->max <= UINT32_MAX)) {
11495
+ /* comapre only the lower 32-bits to allow load fusion on x86_64 */
11496
+ cond = ir_ULT(ir_TRUNC_U32(h), ref);
11497
+ } else {
11498
+ cond = ir_ULT(h, ir_ZEXT_L(ref));
11499
+ }
11500
+ #else
11494
11501
cond = ir_ULT(h, ref);
11502
+ #endif
11495
11503
if (type == BP_JIT_IS) {
11496
11504
if (not_found_exit_addr) {
11497
11505
ir_GUARD(cond, ir_CONST_ADDR(not_found_exit_addr));
@@ -11988,6 +11996,7 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,
11988
11996
bool op1_avoid_refcounting,
11989
11997
uint32_t op2_info,
11990
11998
zend_jit_addr op2_addr,
11999
+ zend_ssa_range *op2_range,
11991
12000
uint32_t res_info,
11992
12001
zend_jit_addr res_addr,
11993
12002
uint8_t dim_type)
@@ -12108,7 +12117,7 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,
12108
12117
12109
12118
if (!zend_jit_fetch_dimension_address_inner(jit, opline,
12110
12119
(opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS,
12111
- op1_info, op2_info, op2_addr, dim_type, NULL, not_found_exit_addr, exit_addr,
12120
+ op1_info, op2_info, op2_addr, op2_range, dim_type, NULL, not_found_exit_addr, exit_addr,
12112
12121
result_type_guard, ht_ref, found_inputs, found_vals,
12113
12122
&end_inputs, ¬_found_inputs)) {
12114
12123
return 0;
@@ -12446,6 +12455,7 @@ static int zend_jit_fetch_dim(zend_jit_ctx *jit,
12446
12455
zend_jit_addr op1_addr,
12447
12456
uint32_t op2_info,
12448
12457
zend_jit_addr op2_addr,
12458
+ zend_ssa_range *op2_range,
12449
12459
zend_jit_addr res_addr,
12450
12460
uint8_t dim_type)
12451
12461
{
@@ -12510,7 +12520,7 @@ static int zend_jit_fetch_dim(zend_jit_ctx *jit,
12510
12520
may_throw = 1;
12511
12521
}
12512
12522
if (!zend_jit_fetch_dimension_address_inner(jit, opline, type, op1_info,
12513
- op2_info, op2_addr, dim_type, NULL, NULL, NULL,
12523
+ op2_info, op2_addr, op2_range, dim_type, NULL, NULL, NULL,
12514
12524
0, ht_ref, found_inputs, found_vals, &end_inputs, NULL)) {
12515
12525
return 0;
12516
12526
}
@@ -12621,6 +12631,7 @@ static int zend_jit_isset_isempty_dim(zend_jit_ctx *jit,
12621
12631
bool op1_avoid_refcounting,
12622
12632
uint32_t op2_info,
12623
12633
zend_jit_addr op2_addr,
12634
+ zend_ssa_range *op2_range,
12624
12635
uint8_t dim_type,
12625
12636
int may_throw,
12626
12637
uint8_t smart_branch_opcode,
@@ -12670,7 +12681,7 @@ static int zend_jit_isset_isempty_dim(zend_jit_ctx *jit,
12670
12681
}
12671
12682
}
12672
12683
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_JIT_IS, op1_info,
12673
- op2_info, op2_addr, dim_type, found_exit_addr, not_found_exit_addr, NULL,
12684
+ op2_info, op2_addr, op2_range, dim_type, found_exit_addr, not_found_exit_addr, NULL,
12674
12685
0, ht_ref, true_inputs, NULL, &false_inputs, NULL)) {
12675
12686
return 0;
12676
12687
}
@@ -12814,6 +12825,7 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit,
12814
12825
zend_jit_addr op1_addr,
12815
12826
uint32_t op2_info,
12816
12827
zend_jit_addr op2_addr,
12828
+ zend_ssa_range *op2_range,
12817
12829
uint32_t val_info,
12818
12830
zend_jit_addr op3_addr,
12819
12831
zend_jit_addr op3_def_addr,
@@ -12883,7 +12895,7 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit,
12883
12895
ir_refs_init(found_values, 8);
12884
12896
12885
12897
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_W, op1_info,
12886
- op2_info, op2_addr, dim_type, NULL, NULL, NULL,
12898
+ op2_info, op2_addr, op2_range, dim_type, NULL, NULL, NULL,
12887
12899
0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) {
12888
12900
return 0;
12889
12901
}
@@ -12985,6 +12997,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit,
12985
12997
zend_jit_addr op1_addr,
12986
12998
uint32_t op2_info,
12987
12999
zend_jit_addr op2_addr,
13000
+ zend_ssa_range *op2_range,
12988
13001
uint32_t op1_data_info,
12989
13002
zend_jit_addr op3_addr,
12990
13003
zend_ssa_range *op1_data_range,
@@ -13054,7 +13067,7 @@ static int zend_jit_assign_dim_op(zend_jit_ctx *jit,
13054
13067
}
13055
13068
13056
13069
if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_RW, op1_info,
13057
- op2_info, op2_addr, dim_type, NULL, not_found_exit_addr, NULL,
13070
+ op2_info, op2_addr, op2_range, dim_type, NULL, not_found_exit_addr, NULL,
13058
13071
0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) {
13059
13072
return 0;
13060
13073
}
0 commit comments