Skip to content

Commit b38c57b

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Fixed GH-12382: JIT Index invalid or out of range error
2 parents 325b2b4 + 5a8f96b commit b38c57b

File tree

2 files changed

+76
-7
lines changed

2 files changed

+76
-7
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4391,6 +4391,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
43914391
uint32_t res_use_info,
43924392
int may_overflow)
43934393
{
4394+
bool must_set_cflags = 0;
43944395
bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
43954396
zend_reg result_reg;
43964397
zend_reg tmp_reg = ZREG_R0;
@@ -4413,34 +4414,63 @@ static int zend_jit_math_long_long(dasm_State **Dst,
44134414
tmp_reg = ZREG_FCARG1;
44144415
}
44154416

4417+
if (may_overflow) {
4418+
must_set_cflags = 1;
4419+
} else {
4420+
const zend_op *next_opline = opline + 1;
4421+
4422+
if (next_opline->opcode == ZEND_IS_EQUAL ||
4423+
next_opline->opcode == ZEND_IS_NOT_EQUAL ||
4424+
next_opline->opcode == ZEND_IS_SMALLER ||
4425+
next_opline->opcode == ZEND_IS_SMALLER_OR_EQUAL ||
4426+
next_opline->opcode == ZEND_CASE ||
4427+
next_opline->opcode == ZEND_IS_IDENTICAL ||
4428+
next_opline->opcode == ZEND_IS_NOT_IDENTICAL ||
4429+
next_opline->opcode == ZEND_CASE_STRICT) {
4430+
if (next_opline->op1_type == IS_CONST
4431+
&& Z_TYPE_P(RT_CONSTANT(next_opline, next_opline->op1)) == IS_LONG
4432+
&& Z_LVAL_P(RT_CONSTANT(next_opline, next_opline->op1)) == 0
4433+
&& next_opline->op2_type == opline->result_type
4434+
&& next_opline->op2.var == opline->result.var) {
4435+
must_set_cflags = 1;
4436+
} else if (next_opline->op2_type == IS_CONST
4437+
&& Z_TYPE_P(RT_CONSTANT(next_opline, next_opline->op2)) == IS_LONG
4438+
&& Z_LVAL_P(RT_CONSTANT(next_opline, next_opline->op2)) == 0
4439+
&& next_opline->op2_type == opline->result_type
4440+
&& next_opline->op2.var == opline->result.var) {
4441+
must_set_cflags = 1;
4442+
}
4443+
}
4444+
}
4445+
44164446
if (opcode == ZEND_MUL &&
44174447
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
44184448
Z_LVAL_P(Z_ZV(op2_addr)) == 2) {
4419-
if (Z_MODE(op1_addr) == IS_REG && !may_overflow) {
4449+
if (Z_MODE(op1_addr) == IS_REG && !must_set_cflags) {
44204450
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Ra(Z_REG(op1_addr))]
44214451
} else {
44224452
| GET_ZVAL_LVAL result_reg, op1_addr
44234453
| add Ra(result_reg), Ra(result_reg)
44244454
}
44254455
} else if (opcode == ZEND_MUL &&
44264456
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
4427-
!may_overflow &&
4457+
!must_set_cflags &&
44284458
Z_LVAL_P(Z_ZV(op2_addr)) > 0 &&
44294459
zend_long_is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr)))) {
44304460
| GET_ZVAL_LVAL result_reg, op1_addr
44314461
| shl Ra(result_reg), zend_long_floor_log2(Z_LVAL_P(Z_ZV(op2_addr)))
44324462
} else if (opcode == ZEND_MUL &&
44334463
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
44344464
Z_LVAL_P(Z_ZV(op1_addr)) == 2) {
4435-
if (Z_MODE(op2_addr) == IS_REG && !may_overflow) {
4465+
if (Z_MODE(op2_addr) == IS_REG && !must_set_cflags) {
44364466
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Ra(Z_REG(op2_addr))]
44374467
} else {
44384468
| GET_ZVAL_LVAL result_reg, op2_addr
44394469
| add Ra(result_reg), Ra(result_reg)
44404470
}
44414471
} else if (opcode == ZEND_MUL &&
44424472
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
4443-
!may_overflow &&
4473+
!must_set_cflags &&
44444474
Z_LVAL_P(Z_ZV(op1_addr)) > 0 &&
44454475
zend_long_is_power_of_two(Z_LVAL_P(Z_ZV(op1_addr)))) {
44464476
| GET_ZVAL_LVAL result_reg, op2_addr
@@ -4451,19 +4481,19 @@ static int zend_jit_math_long_long(dasm_State **Dst,
44514481
| GET_ZVAL_LVAL result_reg, op1_addr
44524482
| shr Ra(result_reg), zend_long_floor_log2(Z_LVAL_P(Z_ZV(op2_addr)))
44534483
} else if (opcode == ZEND_ADD &&
4454-
!may_overflow &&
4484+
!must_set_cflags &&
44554485
Z_MODE(op1_addr) == IS_REG &&
44564486
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
44574487
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
44584488
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Z_LVAL_P(Z_ZV(op2_addr))]
44594489
} else if (opcode == ZEND_ADD &&
4460-
!may_overflow &&
4490+
!must_set_cflags &&
44614491
Z_MODE(op2_addr) == IS_REG &&
44624492
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
44634493
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op1_addr)))) {
44644494
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Z_LVAL_P(Z_ZV(op1_addr))]
44654495
} else if (opcode == ZEND_SUB &&
4466-
!may_overflow &&
4496+
!must_set_cflags &&
44674497
Z_MODE(op1_addr) == IS_REG &&
44684498
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
44694499
IS_SIGNED_32BIT(-Z_LVAL_P(Z_ZV(op2_addr)))) {

ext/opcache/tests/jit/gh12382.phpt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
GH-12382: JIT Index invalid or out of range error
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
--FILE--
7+
<?php
8+
function applyMaskPenaltyRule3(SplFixedArray $array) : void
9+
{
10+
for ($y = 0; $y < 21; ++$y) {
11+
for ($x = 0; $x < 21; ++$x) {
12+
if (
13+
(
14+
$x + 10 < 21
15+
&& 0 === $array[$y][$x + 7]
16+
)
17+
|| (
18+
$x - 4 >= 0
19+
&& 0 === $array[$y][$x - 1]
20+
)
21+
) {
22+
}
23+
}
24+
}
25+
}
26+
27+
$matrix = SplFixedArray::fromArray(
28+
array_map(
29+
fn (array $arr): SplFixedArray => SplFixedArray::fromArray($arr),
30+
[[1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, ], [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, ], [0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, ], [0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, ], [1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, ], [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, ], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, ], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, ], [1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, ], [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, ], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, ], ]
31+
)
32+
);
33+
34+
applyMaskPenaltyRule3($matrix);
35+
applyMaskPenaltyRule3($matrix);
36+
?>
37+
DONE
38+
--EXPECT--
39+
DONE

0 commit comments

Comments
 (0)