diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-23 10:17:30 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-23 10:22:00 +0100 |
commit | 79cf2c56d3c95b184fbdbe2a9bc4afe7bb0dc557 (patch) | |
tree | a10f0b4c25c2e0da29b0a0bdbd5b1a2e1f2a1bae | |
parent | b418fe266dd3ab56358469ed8290187959bad1a7 (diff) | |
download | php-git-79cf2c56d3c95b184fbdbe2a9bc4afe7bb0dc557.tar.gz |
Fixed bug #80786
Don't use r0 as temporary register in math_double_long if it is
already used for a memory result.
This was already done in one branch, but not the other.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/opcache/jit/zend_jit_x86.dasc | 21 | ||||
-rw-r--r-- | ext/opcache/tests/jit/bug80786.phpt | 25 |
3 files changed, 39 insertions, 10 deletions
@@ -9,6 +9,9 @@ PHP NEWS . Fixed bug #80763 (msgfmt_format() does not accept DateTime references). (cmb) +- Opcache: + . Fixed bug #80786 (PHP crash using JIT). (Nikita) + - 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 ceaa2b9a5a..0df475e468 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -4428,7 +4428,14 @@ static int zend_jit_math_double_long(dasm_State **Dst, zend_jit_addr res_addr, uint32_t res_use_info) { - zend_reg result_reg, tmp_reg; + zend_reg result_reg, tmp_reg_gp; + + if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { + /* ASSIGN_DIM_OP */ + tmp_reg_gp = ZREG_R1; + } else { + tmp_reg_gp = ZREG_R0; + } if (zend_is_commutative(opcode) && (Z_MODE(res_addr) != IS_REG || Z_MODE(op1_addr) != IS_REG || Z_REG(res_addr) != Z_REG(op1_addr))) { @@ -4437,13 +4444,7 @@ static int zend_jit_math_double_long(dasm_State **Dst, } else { result_reg = ZREG_XMM0; } - if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { - /* ASSIGN_DIM_OP */ - tmp_reg = ZREG_R1; - } else { - tmp_reg = ZREG_R0; - } - | SSE_GET_ZVAL_LVAL result_reg, op2_addr, tmp_reg + | SSE_GET_ZVAL_LVAL result_reg, op2_addr, tmp_reg_gp if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { /* ASSIGN_DIM_OP */ if (CAN_USE_AVX()) { @@ -4485,7 +4486,7 @@ static int zend_jit_math_double_long(dasm_State **Dst, && Z_LVAL_P(Z_ZV(op2_addr)) == 0) { /* +/- 0 */ } else { - | SSE_GET_ZVAL_LVAL tmp_reg, op2_addr, ZREG_R0 + | SSE_GET_ZVAL_LVAL tmp_reg, op2_addr, tmp_reg_gp | AVX_MATH_REG opcode, result_reg, op1_reg, tmp_reg } } else { @@ -4495,7 +4496,7 @@ static int zend_jit_math_double_long(dasm_State **Dst, && Z_LVAL_P(Z_ZV(op2_addr)) == 0) { /* +/- 0 */ } else { - | SSE_GET_ZVAL_LVAL tmp_reg, op2_addr, ZREG_R0 + | SSE_GET_ZVAL_LVAL tmp_reg, op2_addr, tmp_reg_gp | SSE_MATH_REG opcode, result_reg, tmp_reg } } diff --git a/ext/opcache/tests/jit/bug80786.phpt b/ext/opcache/tests/jit/bug80786.phpt new file mode 100644 index 0000000000..af4675111e --- /dev/null +++ b/ext/opcache/tests/jit/bug80786.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #80786: PHP crash using JIT +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.jit_buffer_size=1M +opcache.jit=function +--FILE-- +<?php + +$a = new Test(); +$a->TestFunc(); +var_dump($a->value); + +class Test{ + public $value = 11.3; + + public function TestFunc() { + $this->value -= 10; + } +} + +?> +--EXPECT-- +float(1.3000000000000007) |