@@ -15285,7 +15285,12 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_
15285
15285
ref = ir_CALL_2(IR_LONG, ir_CONST_FC_FUNC(zend_hash_index_find),
15286
15286
ir_CONST_ADDR(jumptable), ref);
15287
15287
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
+ }
15289
15294
}
15290
15295
ref = ir_SWITCH(ref);
15291
15296
@@ -15406,7 +15411,12 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_
15406
15411
ref = ir_CALL_2(IR_LONG, ir_CONST_FC_FUNC(zend_hash_find),
15407
15412
ir_CONST_ADDR(jumptable), ref);
15408
15413
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
+ }
15410
15420
ref = ir_SWITCH(ref);
15411
15421
15412
15422
if (next_opline) {
@@ -15534,7 +15544,17 @@ static int zend_jit_switch(zend_jit_ctx *jit, const zend_op *opline, const zend_
15534
15544
}
15535
15545
15536
15546
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
+ }
15538
15558
ref = ir_SWITCH(ref);
15539
15559
15540
15560
if (next_opline) {
0 commit comments