@@ -6572,9 +6572,129 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
6572
6572
return result;
6573
6573
}
6574
6574
6575
- static int zend_jit_cmp_long_long(dasm_State **Dst, const zend_op *opline, zend_jit_addr op1_addr, zend_jit_addr op2_addr, zend_jit_addr res_addr, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
6575
+ static int zend_jit_is_constant_cmp_long_long(const zend_op *opline,
6576
+ zend_ssa_range *op1_range,
6577
+ zend_jit_addr op1_addr,
6578
+ zend_ssa_range *op2_range,
6579
+ zend_jit_addr op2_addr,
6580
+ zend_bool *result)
6581
+ {
6582
+ zend_long op1_min;
6583
+ zend_long op1_max;
6584
+ zend_long op2_min;
6585
+ zend_long op2_max;
6586
+
6587
+ if (op1_range) {
6588
+ op1_min = op1_range->min;
6589
+ op1_max = op1_range->max;
6590
+ } else if (Z_MODE(op1_addr) == IS_CONST_ZVAL) {
6591
+ ZEND_ASSERT(Z_TYPE_P(Z_ZV(op1_addr)) == IS_LONG);
6592
+ op1_min = op1_max = Z_LVAL_P(Z_ZV(op1_addr));
6593
+ } else {
6594
+ return 0;
6595
+ }
6596
+
6597
+ if (op2_range) {
6598
+ op2_min = op2_range->min;
6599
+ op2_max = op2_range->max;
6600
+ } else if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
6601
+ ZEND_ASSERT(Z_TYPE_P(Z_ZV(op2_addr)) == IS_LONG);
6602
+ op2_min = op2_max = Z_LVAL_P(Z_ZV(op2_addr));
6603
+ } else {
6604
+ return 0;
6605
+ }
6606
+
6607
+ switch (opline->opcode) {
6608
+ case ZEND_IS_EQUAL:
6609
+ case ZEND_IS_IDENTICAL:
6610
+ case ZEND_CASE:
6611
+ case ZEND_CASE_STRICT:
6612
+ if (op1_min == op1_max && op2_min == op2_max && op1_min == op2_min) {
6613
+ *result = 1;
6614
+ return 1;
6615
+ } else if (op1_max < op2_min || op1_min > op2_max) {
6616
+ *result = 0;
6617
+ return 1;
6618
+ }
6619
+ return 0;
6620
+ case ZEND_IS_NOT_EQUAL:
6621
+ case ZEND_IS_NOT_IDENTICAL:
6622
+ if (op1_min == op1_max && op2_min == op2_max && op1_min == op2_min) {
6623
+ *result = 0;
6624
+ return 1;
6625
+ } else if (op1_max < op2_min || op1_min > op2_max) {
6626
+ *result = 1;
6627
+ return 1;
6628
+ }
6629
+ return 0;
6630
+ case ZEND_IS_SMALLER:
6631
+ if (op1_max < op2_min) {
6632
+ *result = 1;
6633
+ return 1;
6634
+ } else if (op1_min >= op2_max) {
6635
+ *result = 0;
6636
+ return 1;
6637
+ }
6638
+ return 0;
6639
+ case ZEND_IS_SMALLER_OR_EQUAL:
6640
+ if (op1_max <= op2_min) {
6641
+ *result = 1;
6642
+ return 1;
6643
+ } else if (op1_min > op2_max) {
6644
+ *result = 0;
6645
+ return 1;
6646
+ }
6647
+ return 0;
6648
+ default:
6649
+ ZEND_UNREACHABLE();
6650
+ }
6651
+ return 0;
6652
+ }
6653
+
6654
+ static int zend_jit_cmp_long_long(dasm_State **Dst,
6655
+ const zend_op *opline,
6656
+ zend_ssa_range *op1_range,
6657
+ zend_jit_addr op1_addr,
6658
+ zend_ssa_range *op2_range,
6659
+ zend_jit_addr op2_addr,
6660
+ zend_jit_addr res_addr,
6661
+ zend_uchar smart_branch_opcode,
6662
+ uint32_t target_label,
6663
+ uint32_t target_label2,
6664
+ const void *exit_addr)
6576
6665
{
6577
6666
zend_bool swap = 0;
6667
+ zend_bool result;
6668
+
6669
+ if (zend_jit_is_constant_cmp_long_long(opline, op1_range, op1_addr, op2_range, op2_addr, &result)) {
6670
+ if (!smart_branch_opcode ||
6671
+ smart_branch_opcode == ZEND_JMPZ_EX ||
6672
+ smart_branch_opcode == ZEND_JMPNZ_EX) {
6673
+ | SET_ZVAL_TYPE_INFO res_addr, (result ? IS_TRUE : IS_FALSE)
6674
+ }
6675
+ if (smart_branch_opcode && !exit_addr) {
6676
+ if (smart_branch_opcode == ZEND_JMPZ ||
6677
+ smart_branch_opcode == ZEND_JMPZ_EX) {
6678
+ if (!result) {
6679
+ | jmp => target_label
6680
+ }
6681
+ } else if (smart_branch_opcode == ZEND_JMPNZ ||
6682
+ smart_branch_opcode == ZEND_JMPNZ_EX) {
6683
+ if (result) {
6684
+ | jmp => target_label
6685
+ }
6686
+ } else if (smart_branch_opcode == ZEND_JMPZNZ) {
6687
+ if (!result) {
6688
+ | jmp => target_label
6689
+ } else {
6690
+ | jmp => target_label2
6691
+ }
6692
+ } else {
6693
+ ZEND_UNREACHABLE();
6694
+ }
6695
+ }
6696
+ return 1;
6697
+ }
6578
6698
6579
6699
if (Z_MODE(op1_addr) == IS_REG) {
6580
6700
if (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 0) {
@@ -7350,7 +7470,20 @@ static int zend_jit_cmp_slow(dasm_State **Dst, const zend_op *opline, zend_jit_a
7350
7470
return 1;
7351
7471
}
7352
7472
7353
- static int zend_jit_cmp(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, zend_jit_addr op2_addr, zend_jit_addr res_addr, int may_throw, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
7473
+ static int zend_jit_cmp(dasm_State **Dst,
7474
+ const zend_op *opline,
7475
+ uint32_t op1_info,
7476
+ zend_ssa_range *op1_range,
7477
+ zend_jit_addr op1_addr,
7478
+ uint32_t op2_info,
7479
+ zend_ssa_range *op2_range,
7480
+ zend_jit_addr op2_addr,
7481
+ zend_jit_addr res_addr,
7482
+ int may_throw,
7483
+ zend_uchar smart_branch_opcode,
7484
+ uint32_t target_label,
7485
+ uint32_t target_label2,
7486
+ const void *exit_addr)
7354
7487
{
7355
7488
zend_bool same_ops = (opline->op1_type == opline->op2_type) && (opline->op1.var == opline->op2.var);
7356
7489
zend_bool has_slow;
@@ -7386,7 +7519,7 @@ static int zend_jit_cmp(dasm_State **Dst, const zend_op *opline, uint32_t op1_in
7386
7519
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >9
7387
7520
}
7388
7521
}
7389
- if (!zend_jit_cmp_long_long(Dst, opline, op1_addr, op2_addr, res_addr, smart_branch_opcode, target_label, target_label2, exit_addr)) {
7522
+ if (!zend_jit_cmp_long_long(Dst, opline, op1_range, op1_addr, op2_range , op2_addr, res_addr, smart_branch_opcode, target_label, target_label2, exit_addr)) {
7390
7523
return 0;
7391
7524
}
7392
7525
if (op1_info & MAY_BE_DOUBLE) {
@@ -7575,7 +7708,20 @@ static int zend_jit_cmp(dasm_State **Dst, const zend_op *opline, uint32_t op1_in
7575
7708
return 1;
7576
7709
}
7577
7710
7578
- static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, zend_jit_addr op2_addr, zend_jit_addr res_addr, int may_throw, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
7711
+ static int zend_jit_identical(dasm_State **Dst,
7712
+ const zend_op *opline,
7713
+ uint32_t op1_info,
7714
+ zend_ssa_range *op1_range,
7715
+ zend_jit_addr op1_addr,
7716
+ uint32_t op2_info,
7717
+ zend_ssa_range *op2_range,
7718
+ zend_jit_addr op2_addr,
7719
+ zend_jit_addr res_addr,
7720
+ int may_throw,
7721
+ zend_uchar smart_branch_opcode,
7722
+ uint32_t target_label,
7723
+ uint32_t target_label2,
7724
+ const void *exit_addr)
7579
7725
{
7580
7726
uint32_t identical_label = (uint32_t)-1;
7581
7727
uint32_t not_identical_label = (uint32_t)-1;
@@ -7608,7 +7754,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t
7608
7754
7609
7755
if ((op1_info & (MAY_BE_REF|MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
7610
7756
(op2_info & (MAY_BE_REF|MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) {
7611
- if (!zend_jit_cmp_long_long(Dst, opline, op1_addr, op2_addr, res_addr, smart_branch_opcode, target_label, target_label2, exit_addr)) {
7757
+ if (!zend_jit_cmp_long_long(Dst, opline, op1_range, op1_addr, op2_range , op2_addr, res_addr, smart_branch_opcode, target_label, target_label2, exit_addr)) {
7612
7758
return 0;
7613
7759
}
7614
7760
return 1;
0 commit comments