Skip to content

Commit 417e3d7

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: Clear ZREG_TYPE_ONLY flag for in-register vars in zend_jit_snapshot_handler() (#22764)
2 parents 5ccb145 + 853b89c commit 417e3d7

3 files changed

Lines changed: 63 additions & 1 deletion

File tree

ext/opcache/jit/zend_jit_ir.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,12 +858,14 @@ void *zend_jit_snapshot_handler(ir_ctx *ctx, ir_ref snapshot_ref, ir_insn *snaps
858858
t->stack_map[t->exit_info[exit_point].stack_offset + var].flags = ZREG_TYPE_ONLY;
859859
} else {
860860
if ((exit_flags & ZEND_JIT_EXIT_FIXED)
861-
&& t->stack_map[t->exit_info[exit_point].stack_offset + var].reg != IR_REG_NUM(reg)) {
861+
&& (t->stack_map[t->exit_info[exit_point].stack_offset + var].reg != IR_REG_NUM(reg)
862+
|| (t->stack_map[t->exit_info[exit_point].stack_offset + var].flags & ~(ZREG_LOAD|ZREG_STORE|ZREG_LAST_USE)))) {
862863
exit_point = zend_jit_duplicate_exit_point(ctx, t, exit_point, snapshot_ref);
863864
addr = (void*)zend_jit_trace_get_exit_addr(exit_point);
864865
exit_flags &= ~ZEND_JIT_EXIT_FIXED;
865866
}
866867
t->stack_map[t->exit_info[exit_point].stack_offset + var].reg = IR_REG_NUM(reg);
868+
t->stack_map[t->exit_info[exit_point].stack_offset + var].flags &= (ZREG_LOAD|ZREG_STORE|ZREG_LAST_USE);
867869
}
868870
} else {
869871
if ((exit_flags & ZEND_JIT_EXIT_FIXED)

ext/opcache/jit/zend_jit_trace.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3571,6 +3571,8 @@ static int zend_jit_trace_deoptimization(
35713571
}
35723572
}
35733573
} else if (STACK_FLAGS(parent_stack, i) == ZREG_TYPE_ONLY) {
3574+
ZEND_ASSERT(reg == ZREG_NONE);
3575+
35743576
uint8_t type = STACK_TYPE(parent_stack, i);
35753577

35763578
if (!zend_jit_store_type(jit, i, type)) {

ext/opcache/tests/jit/gh22763.phpt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
GH-22763: JIT fails to clear ZREG_TYPE_ONLY after setting reg
3+
--FILE--
4+
<?php
5+
6+
function findMiddleSnake(array $a, int $aLo, int $aHi, array $b, int $bLo, int $bHi): array
7+
{
8+
$n = $aHi - $aLo;
9+
$m = $bHi - $bLo;
10+
$delta = $n - $m;
11+
$deltaIsOdd = ($delta & 1) !== 0;
12+
$offset = 4;
13+
$size = 2 * 3 + 2;
14+
$vf = array_fill(0, $size, 0);
15+
$vb = array_fill(0, $size, 0);
16+
17+
$d = 2;
18+
$x = 0;
19+
20+
for ($k = -$d; $k <= $d; $k += 2) {
21+
if ($k === -$d || ($k !== $d && $vb[$offset + $k - 1] < $vb[$offset + $k + 1])) {
22+
$x = $vb[$offset + $k + 1];
23+
var_dump($x);
24+
} else {
25+
$x = $vb[$offset + $k - 1] + 1;
26+
}
27+
28+
$y = $x - $k;
29+
$xs = $x;
30+
$ys = $y;
31+
32+
while ($x < $n && $y < $m && $a[$aLo + $n - 1 - $x] === $b[$bLo + $m - 1 - $y]) {
33+
$x++;
34+
$y++;
35+
}
36+
37+
$vb[$offset + $k] = $x;
38+
39+
if (!$deltaIsOdd) {
40+
$kf = $delta - $k;
41+
42+
if ($kf >= -$d && $kf <= $d && $vf[$offset + $kf] + $vb[$offset + $k] >= $n) {
43+
return [$n - $x, $m - $y, $n - $xs, $m - $ys];
44+
}
45+
}
46+
}
47+
48+
return [];
49+
}
50+
51+
$from = [3,2,1];
52+
$to = [1,99,3];
53+
findMiddleSnake($from, 0, count($from), $to, 0, count($to));
54+
?>
55+
--EXPECTF--
56+
int(0)
57+
58+
Warning: Undefined array key 3 in %s on line %d

0 commit comments

Comments
 (0)