Skip to content

Commit 8349835

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Backport fix for GH-12512: JIT Assertion `info & (1 << type)' failed (#12660)
2 parents 3b68df2 + db26aee commit 8349835

File tree

3 files changed

+154
-3
lines changed

3 files changed

+154
-3
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5037,6 +5037,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50375037
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info))) {
50385038
goto jit_failure;
50395039
}
5040+
if (ssa_op->op2_def > 0
5041+
&& Z_MODE(op2_addr) == IS_REG
5042+
&& ssa->vars[ssa_op->op2_def].no_val) {
5043+
uint8_t type = (op2_info & MAY_BE_LONG) ? IS_LONG : IS_DOUBLE;
5044+
uint32_t var_num = EX_VAR_TO_NUM(opline->op2.var);
5045+
5046+
if (STACK_MEM_TYPE(stack, var_num) != type
5047+
&& ssa->vars[ssa_op->op2_def].use_chain < 0
5048+
&& !ssa->vars[ssa_op->op2_def].phi_use_chain) {
5049+
if (!zend_jit_store_var_type(&dasm_state, var_num, type)) {
5050+
return 0;
5051+
}
5052+
SET_STACK_TYPE(stack, var_num, type, 1);
5053+
}
5054+
}
50405055
if (opline->op2_type == IS_CV
50415056
&& ssa_op->op2_def >= 0
50425057
&& ssa->vars[ssa_op->op2_def].alias == NO_ALIAS) {
@@ -5073,6 +5088,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50735088
res_use_info, res_info, res_addr)) {
50745089
goto jit_failure;
50755090
}
5091+
if (ssa_op->op1_def > 0
5092+
&& Z_MODE(op1_addr) == IS_REG
5093+
&& ssa->vars[ssa_op->op1_def].no_val) {
5094+
uint8_t type = (op1_info & MAY_BE_LONG) ? IS_LONG : IS_DOUBLE;
5095+
uint32_t var_num = EX_VAR_TO_NUM(opline->op1.var);
5096+
5097+
if (STACK_MEM_TYPE(stack, var_num) != type
5098+
&& ssa->vars[ssa_op->op1_def].use_chain < 0
5099+
&& !ssa->vars[ssa_op->op1_def].phi_use_chain) {
5100+
if (!zend_jit_store_var_type(&dasm_state, var_num, type)) {
5101+
return 0;
5102+
}
5103+
SET_STACK_TYPE(stack, var_num, type, 1);
5104+
}
5105+
}
50765106
if (opline->op1_type == IS_CV
50775107
&& ssa_op->op1_def >= 0
50785108
&& ssa->vars[ssa_op->op1_def].alias == NO_ALIAS) {
@@ -5155,6 +5185,21 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
51555185
op1_info, op1_addr, op1_def_addr)) {
51565186
goto jit_failure;
51575187
}
5188+
if (ssa_op->op1_def > 0
5189+
&& Z_MODE(op1_addr) == IS_REG
5190+
&& ssa->vars[ssa_op->op1_def].no_val) {
5191+
uint8_t type = (op1_info & MAY_BE_LONG) ? IS_LONG : IS_DOUBLE;
5192+
uint32_t var_num = EX_VAR_TO_NUM(opline->op1.var);
5193+
5194+
if (STACK_MEM_TYPE(stack, var_num) != type
5195+
&& ssa->vars[ssa_op->op1_def].use_chain < 0
5196+
&& !ssa->vars[ssa_op->op1_def].phi_use_chain) {
5197+
if (!zend_jit_store_var_type(&dasm_state, var_num, type)) {
5198+
return 0;
5199+
}
5200+
SET_STACK_TYPE(stack, var_num, type, 1);
5201+
}
5202+
}
51585203
if (opline->op1_type == IS_CV
51595204
&& ssa_op->op1_def >= 0
51605205
&& ssa->vars[ssa_op->op1_def].alias == NO_ALIAS) {
@@ -6875,9 +6920,30 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
68756920
}
68766921
} else if (p->stop == ZEND_JIT_TRACE_STOP_LINK
68776922
|| p->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) {
6878-
if (!zend_jit_trace_deoptimization(&dasm_state, 0, NULL,
6879-
stack, op_array->last_var + op_array->T, NULL, NULL, NULL, 0)) {
6880-
goto jit_failure;
6923+
if (ra
6924+
&& (p-1)->op != ZEND_JIT_TRACE_ENTER
6925+
&& (p-1)->op != ZEND_JIT_TRACE_BACK
6926+
&& opline->opcode != ZEND_DO_UCALL
6927+
&& opline->opcode != ZEND_DO_FCALL
6928+
&& opline->opcode != ZEND_DO_FCALL_BY_NAME
6929+
&& opline->opcode != ZEND_INCLUDE_OR_EVAL) {
6930+
if (!zend_jit_trace_deoptimization(&dasm_state, 0, NULL,
6931+
stack, op_array->last_var + op_array->T, NULL, NULL, NULL, 0)) {
6932+
goto jit_failure;
6933+
}
6934+
for (i = 0; i < op_array->last_var; i++) {
6935+
int8_t reg = STACK_REG(stack, i);
6936+
uint8_t type = STACK_TYPE(stack, i);
6937+
6938+
if (reg == ZREG_NONE
6939+
&& type != IS_UNKNOWN
6940+
&& type != STACK_MEM_TYPE(stack, i)) {
6941+
if (!zend_jit_store_var_type(&dasm_state, i, type)) {
6942+
return 0;
6943+
}
6944+
SET_STACK_TYPE(stack, i, type, 1);
6945+
}
6946+
}
68816947
}
68826948
if (p->stop == ZEND_JIT_TRACE_STOP_LINK) {
68836949
const void *timeout_exit_addr = NULL;

ext/opcache/tests/jit/gh12512.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
GH-12512: missing type store
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
--FILE--
7+
<?php
8+
function bar(array &$a): ?bool {
9+
$ret = null;
10+
foreach ($a as $key => $val) {
11+
if ($val === 2) {
12+
unset($a[$key]);
13+
}
14+
}
15+
return $ret;
16+
}
17+
18+
function foo($a, bool $b): bool {
19+
if ($b) return true;
20+
$n2 = count($a);
21+
do {
22+
$n = $n2;
23+
$res = bar($a);
24+
$n2 = count($a);
25+
} while ($res === null && $n !== $n2);
26+
27+
if ($res === null && $n === 0) {
28+
return false;
29+
}
30+
return true;
31+
}
32+
33+
$a = [1,'a'=>5];
34+
bar($a);
35+
foo([1,'a'=>5], true);
36+
foo([1,'a'=>5], false);
37+
foo([2,'a'=>5], false);
38+
?>
39+
DONE
40+
--EXPECT--
41+
DONE

ext/opcache/tests/jit/gh12512_2.phpt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
GH-12512: missing type store
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
--FILE--
7+
<?php
8+
function foo(array $a, $exit) {
9+
$n = 0;
10+
11+
$count = count($a);
12+
if ($count == 0) {
13+
return 0;
14+
}
15+
$a2 = [];
16+
foreach ($a as $v) {
17+
$a2[] = $v;
18+
}
19+
20+
$count = $a2[5];
21+
22+
for ($i = 0; $i < $count; $i++) {
23+
$x = $a[$i];
24+
for ($k = $i + 1; $k < $count; $k++) {
25+
$y = $a[$k];
26+
$n += $x > $y;
27+
}
28+
if ($exit) {
29+
return $n;
30+
}
31+
}
32+
33+
return $n;
34+
}
35+
var_dump(foo([1,2,3,4,5,6,7,8], 1));
36+
var_dump(foo([1,2,3,4,5,6,7,8], 1));
37+
var_dump(foo([1,2,3,4,5,6,7,8], 0));
38+
?>
39+
DONE
40+
--EXPECT--
41+
int(0)
42+
int(0)
43+
int(0)
44+
DONE

0 commit comments

Comments
 (0)