summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2021-02-24 12:20:20 +0300
committerDmitry Stogov <dmitry@zend.com>2021-02-24 12:20:20 +0300
commitb7fa5268e4d9ca7ee4c2ae908b6b45b9517d5921 (patch)
tree815ddd2881dc6701156b56d432a648f213cb1380
parent8162c3d1fdd13bfdbbb010c9ce4ebf75ee0316dd (diff)
downloadphp-git-b7fa5268e4d9ca7ee4c2ae908b6b45b9517d5921.tar.gz
Fixed bug #80782 (DASM_S_RANGE_VREG on PHP_INT_MIN-1)
-rw-r--r--NEWS1
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc17
-rw-r--r--ext/opcache/tests/jit/bug80782.phpt18
3 files changed, 32 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index e3e8be870b..18bd50a986 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ PHP NEWS
- Opcache:
. Fixed bug #80786 (PHP crash using JIT). (Nikita)
+ . Fixed bug #80782 (DASM_S_RANGE_VREG on PHP_INT_MIN-1). (Dmitry)
- Session:
. Fixed bug #80774 (session_name() problem with backslash). (cmb)
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 0df475e468..d886085ad4 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -4329,12 +4329,17 @@ static int zend_jit_math_long_long(dasm_State **Dst,
}
do {
- if ((Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op1_addr)) == 1) ||
- (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1)) {
+ if ((sizeof(void*) == 8 || Z_MODE(res_addr) != IS_REG) &&
+ ((Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op1_addr)) == 1) ||
+ (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1))) {
if (opcode == ZEND_ADD) {
|.if X64
| mov64 rax, 0x43e0000000000000
- | SET_ZVAL_LVAL res_addr, rax
+ if (Z_MODE(res_addr) == IS_REG) {
+ | movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax
+ } else {
+ | SET_ZVAL_LVAL res_addr, rax
+ }
|.else
| SET_ZVAL_LVAL res_addr, 0
| SET_ZVAL_W2 res_addr, 0x41e00000
@@ -4343,7 +4348,11 @@ static int zend_jit_math_long_long(dasm_State **Dst,
} else if (opcode == ZEND_SUB) {
|.if X64
| mov64 rax, 0xc3e0000000000000
- | SET_ZVAL_LVAL res_addr, rax
+ if (Z_MODE(res_addr) == IS_REG) {
+ | movd xmm(Z_REG(res_addr)-ZREG_XMM0), rax
+ } else {
+ | SET_ZVAL_LVAL res_addr, rax
+ }
|.else
| SET_ZVAL_LVAL res_addr, 0x00200000
| SET_ZVAL_W2 res_addr, 0xc1e00000
diff --git a/ext/opcache/tests/jit/bug80782.phpt b/ext/opcache/tests/jit/bug80782.phpt
new file mode 100644
index 0000000000..c05987cbe2
--- /dev/null
+++ b/ext/opcache/tests/jit/bug80782.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #80782 (DASM_S_RANGE_VREG on PHP_INT_MIN-1)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit=tracing
+opcache.jit_buffer_size=1M
+opcache.protect_memory=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+define('LONG_MIN', PHP_INT_MIN);
+var_dump(LONG_MIN-1);
+?>
+--EXPECTF--
+float(%s)