Skip to content

Commit 0d51165

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: JIT x86: Fixed register clobbering in code produced for "$x[$y] %= $z".
2 parents cf7c901 + 443b196 commit 0d51165

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4949,6 +4949,9 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
49494949

49504950
if (opcode == ZEND_MOD) {
49514951
result_reg = ZREG_RAX;
4952+
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
4953+
| mov aword T1, r0 // save
4954+
}
49524955
} else if (Z_MODE(res_addr) == IS_REG) {
49534956
if ((opline->opcode == ZEND_SL || opline->opcode == ZEND_SR)
49544957
&& opline->op2_type != IS_CONST) {
@@ -5053,18 +5056,23 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
50535056
if (op2_lval == 0) {
50545057
| SET_EX_OPLINE opline, r0
50555058
| jmp ->mod_by_zero
5056-
} else if (op2_lval == -1) {
5057-
| xor Ra(result_reg), Ra(result_reg)
50585059
} else {
50595060
result_reg = ZREG_RDX;
5060-
| GET_ZVAL_LVAL ZREG_RAX, op1_addr
5061-
| GET_ZVAL_LVAL ZREG_RCX, op2_addr
5062-
|.if X64
5063-
| cqo
5064-
|.else
5065-
| cdq
5066-
|.endif
5067-
| idiv Ra(ZREG_RCX)
5061+
if (op2_lval == -1) {
5062+
| xor Ra(result_reg), Ra(result_reg)
5063+
} else {
5064+
| GET_ZVAL_LVAL ZREG_RAX, op1_addr
5065+
| GET_ZVAL_LVAL ZREG_RCX, op2_addr
5066+
|.if X64
5067+
| cqo
5068+
|.else
5069+
| cdq
5070+
|.endif
5071+
| idiv Ra(ZREG_RCX)
5072+
}
5073+
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
5074+
| mov r0, aword T1 // restore
5075+
}
50685076
}
50695077
} else {
50705078
if (!op2_range || (op2_range->min <= 0 && op2_range->max >= 0)) {
@@ -5115,6 +5123,9 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
51155123
} else if (Z_MODE(op2_addr) == IS_REG) {
51165124
| idiv Ra(Z_REG(op2_addr))
51175125
}
5126+
if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) {
5127+
| mov r0, aword T1 // restore
5128+
}
51185129
}
51195130
} else if (same_ops) {
51205131
| GET_ZVAL_LVAL result_reg, op1_addr

ext/opcache/tests/jit/mod_003.phpt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
JIT MOD: 003
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
opcache.jit=function
10+
--EXTENSIONS--
11+
opcache
12+
--FILE--
13+
<?php
14+
class Test {
15+
public $prop = 0;
16+
}
17+
function test1($test) {
18+
$test[0] %= 3;
19+
return $test;
20+
}
21+
function test2($test) {
22+
$test->prop %= 3;
23+
return $test;
24+
}
25+
var_dump(test1([0]));
26+
var_dump(test2(new Test));
27+
?>
28+
--EXPECT--
29+
array(1) {
30+
[0]=>
31+
int(0)
32+
}
33+
object(Test)#1 (1) {
34+
["prop"]=>
35+
int(0)
36+
}

0 commit comments

Comments
 (0)