@@ -15285,7 +15285,12 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_
1528515285 ref = ir_CALL_2(IR_LONG, ir_CONST_FC_FUNC(zend_hash_index_find),
1528615286 ir_CONST_ADDR(jumptable), ref);
1528715287 ref = ir_SUB_L(ref, ir_CONST_LONG((uintptr_t)jumptable->arData));
15288- ref = ir_DIV_L(ref, ir_CONST_LONG(sizeof(Bucket)));
15288+ /* Signed DIV by power of 2 may be optimized into SHR only for positive operands */
15289+ if (sizeof(Bucket) == 32) {
15290+ ref = ir_SHR_L(ref, ir_CONST_LONG(5));
15291+ } else {
15292+ ref = ir_DIV_L(ref, ir_CONST_LONG(sizeof(Bucket)));
15293+ }
1528915294 }
1529015295 ref = ir_SWITCH(ref);
1529115296
@@ -15406,7 +15411,12 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_
1540615411 ref = ir_CALL_2(IR_LONG, ir_CONST_FC_FUNC(zend_hash_find),
1540715412 ir_CONST_ADDR(jumptable), ref);
1540815413 ref = ir_SUB_L(ref, ir_CONST_LONG((uintptr_t)jumptable->arData));
15409- ref = ir_DIV_L(ref, ir_CONST_LONG(sizeof(Bucket)));
15414+ /* Signed DIV by power of 2 may be optimized into SHR only for positive operands */
15415+ if (sizeof(Bucket) == 32) {
15416+ ref = ir_SHR_L(ref, ir_CONST_LONG(5));
15417+ } else {
15418+ ref = ir_DIV_L(ref, ir_CONST_LONG(sizeof(Bucket)));
15419+ }
1541015420 ref = ir_SWITCH(ref);
1541115421
1541215422 if (next_opline) {
@@ -15534,7 +15544,17 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_
1553415544 }
1553515545
1553615546 ref = ir_SUB_L(ref, ir_CONST_LONG((uintptr_t)jumptable->arData));
15537- ref = ir_DIV_L(ref, ir_CONST_LONG(HT_IS_PACKED(jumptable) ? sizeof(zval) : sizeof(Bucket)));
15547+ /* Signed DIV by power of 2 may be optimized into SHR only for positive operands */
15548+ if (HT_IS_PACKED(jumptable)) {
15549+ ZEND_ASSERT(sizeof(zval) == 16);
15550+ ref = ir_SHR_L(ref, ir_CONST_LONG(4));
15551+ } else {
15552+ if (sizeof(Bucket) == 32) {
15553+ ref = ir_SHR_L(ref, ir_CONST_LONG(5));
15554+ } else {
15555+ ref = ir_DIV_L(ref, ir_CONST_LONG(sizeof(Bucket)));
15556+ }
15557+ }
1553815558 ref = ir_SWITCH(ref);
1553915559
1554015560 if (next_opline) {
0 commit comments