Skip to content

Commit

Permalink
Fixed bug #81225 (Wrong result with pow operator with JIT enabled)
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Jul 19, 2021
1 parent 9fbcaa5 commit 9cd4371
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ PHP NEWS
- CGI:
. Fixed bug #80849 (HTTP Status header truncation). (cmb)

- Opcache:
. Fixed bug #81225 (Wrong result with pow operator with JIT enabled).
(Dmitry)

- Standard:
. Fixed bug #72146 (Integer overflow on substr_replace). (cmb)
. Fixed bug #81265 (getimagesize returns 0 for 256px ICO images).
Expand Down
9 changes: 6 additions & 3 deletions ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -4274,17 +4274,20 @@ static int zend_jit_math_long_long(dasm_State **Dst,
} else if (opcode == ZEND_ADD &&
!may_overflow &&
Z_MODE(op1_addr) == IS_REG &&
Z_MODE(op2_addr) == IS_CONST_ZVAL) {
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Z_LVAL_P(Z_ZV(op2_addr))]
} else if (opcode == ZEND_ADD &&
!may_overflow &&
Z_MODE(op2_addr) == IS_REG &&
Z_MODE(op1_addr) == IS_CONST_ZVAL) {
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op1_addr)))) {
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Z_LVAL_P(Z_ZV(op1_addr))]
} else if (opcode == ZEND_SUB &&
!may_overflow &&
Z_MODE(op1_addr) == IS_REG &&
Z_MODE(op2_addr) == IS_CONST_ZVAL) {
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))-Z_LVAL_P(Z_ZV(op2_addr))]
} else {
| GET_ZVAL_LVAL result_reg, op1_addr
Expand Down
32 changes: 32 additions & 0 deletions ext/opcache/tests/jit/bug81225.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
Bug #81225: Wrong result with pow operator with JIT enabled
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=1M
opcache.jit=tracing
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php

function unsignedLong(int $offset): int
{
$normalizedOffset = $offset % (2 ** 32);

if ($normalizedOffset < 0) {
$normalizedOffset += 2 ** 32;
}

return $normalizedOffset;
}

$offset = -0x100000000 + 2;

for ($i = 0; $i < 200; ++$i) {
assert(unsignedLong($offset) === 2);
}
?>
OK
--EXPECT--
OK

0 comments on commit 9cd4371

Please sign in to comment.