1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.0' into PHP-8.1

* PHP-8.0:
  JIT: Fixed incorrect MOD into BW_AND optimization
This commit is contained in:
Dmitry Stogov
2021-11-10 21:18:15 +03:00
3 changed files with 39 additions and 28 deletions

View File

@@ -4609,7 +4609,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
{
bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
zend_reg result_reg;
zval tmp;
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6, ZREG_TMP1
@@ -4618,19 +4617,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6, ZREG_TMP1
}
if (opcode == ZEND_MOD && Z_MODE(op2_addr) == IS_CONST_ZVAL &&
op1_range &&
op1_range->min >= 0) {
zend_long l = Z_LVAL_P(Z_ZV(op2_addr));
if (zend_long_is_power_of_two(l)) {
/* Optimisation for mod of power of 2 */
opcode = ZEND_BW_AND;
ZVAL_LONG(&tmp, l - 1);
op2_addr = ZEND_ADDR_CONST_ZVAL(&tmp);
}
}
if (Z_MODE(res_addr) == IS_REG) {
if ((opline->opcode == ZEND_SL || opline->opcode == ZEND_SR)
&& opline->op2_type != IS_CONST) {
@@ -4742,6 +4728,15 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| b ->mod_by_zero
} else if (op2_lval == -1) {
| mov Rx(result_reg), xzr
} else if (zend_long_is_power_of_two(op2_lval) && op1_range && op1_range->min >= 0) {
zval tmp;
zend_jit_addr tmp_addr;
/* Optimisation for mod of power of 2 */
ZVAL_LONG(&tmp, op2_lval - 1);
tmp_addr = ZEND_ADDR_CONST_ZVAL(&tmp);
| GET_ZVAL_LVAL result_reg, op1_addr, TMP1
| LONG_MATH ZEND_BW_AND, result_reg, tmp_addr, TMP1
} else {
| GET_ZVAL_LVAL ZREG_TMP1, op1_addr, TMP1
| GET_ZVAL_LVAL ZREG_TMP2, op2_addr, TMP2

View File

@@ -5023,7 +5023,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
{
bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
zend_reg result_reg;
zval tmp;
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6
@@ -5032,19 +5031,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
if (opcode == ZEND_MOD && Z_MODE(op2_addr) == IS_CONST_ZVAL &&
op1_range &&
op1_range->min >= 0) {
zend_long l = Z_LVAL_P(Z_ZV(op2_addr));
if (zend_long_is_power_of_two(l)) {
/* Optimisation for mod of power of 2 */
opcode = ZEND_BW_AND;
ZVAL_LONG(&tmp, l - 1);
op2_addr = ZEND_ADDR_CONST_ZVAL(&tmp);
}
}
if (opcode == ZEND_MOD) {
result_reg = ZREG_RAX;
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
@@ -5154,6 +5140,15 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
if (op2_lval == 0) {
| SET_EX_OPLINE opline, r0
| jmp ->mod_by_zero
} else if (zend_long_is_power_of_two(op2_lval) && op1_range && op1_range->min >= 0) {
zval tmp;
zend_jit_addr tmp_addr;
/* Optimisation for mod of power of 2 */
ZVAL_LONG(&tmp, op2_lval - 1);
tmp_addr = ZEND_ADDR_CONST_ZVAL(&tmp);
| GET_ZVAL_LVAL result_reg, op1_addr
| LONG_MATH ZEND_BW_AND, result_reg, tmp_addr
} else {
result_reg = ZREG_RDX;
if (op2_lval == -1) {

View File

@@ -0,0 +1,21 @@
--TEST--
JIT MUL: 007 incorrect optimization
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_update_protection=0
opcache.jit_buffer_size=1M
opcache.protect_memory=1
--FILE--
<?php
function test() {
1.5%2%2%2/2%2;
}
test();
?>
DONE
--EXPECTF--
Deprecated: Implicit conversion from float 1.5 to int loses precision in %smul_007.php on line 3
Deprecated: Implicit conversion from float 0.5 to int loses precision in %smul_007.php on line 3
DONE