Skip to content

Commit e32c850

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: Set opline before calling undef op helper JIT: Fixed wrong comparison skip
2 parents d9e5e63 + 4558371 commit e32c850

File tree

5 files changed

+67
-15
lines changed

5 files changed

+67
-15
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11608,6 +11608,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst,
1160811608
if (op2_info & MAY_BE_ANY) {
1160911609
| IF_NOT_ZVAL_TYPE op2_addr, IS_UNDEF, >1, ZREG_TMP1
1161011610
}
11611+
| SET_EX_OPLINE opline, REG0
1161111612
| LOAD_32BIT_VAL FCARG1w, opline->op2.var
1161211613
| EXT_CALL zend_jit_undefined_op_helper, REG0
1161311614
|1:

ext/opcache/jit/zend_jit_trace.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3682,7 +3682,7 @@ static void zend_jit_trace_update_condition_ranges(const zend_op *opline, const
36823682
}
36833683
}
36843684

3685-
static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_ssa *ssa, const zend_op **ssa_opcodes)
3685+
static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_ssa *ssa, const zend_op **ssa_opcodes, const zend_op_array *op_array)
36863686
{
36873687
zend_uchar prev_opcode;
36883688

@@ -3691,18 +3691,23 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o
36913691
&& Z_LVAL_P(RT_CONSTANT(opline, opline->op1)) == 0) {
36923692
if (ssa_op->op2_use >= 0) {
36933693
if ((ssa_op-1)->op1_def == ssa_op->op2_use) {
3694-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3694+
ssa_op--;
3695+
opline = ssa_opcodes[ssa_op - ssa->ops];
3696+
prev_opcode = opline->opcode;
36953697
if (prev_opcode == ZEND_PRE_INC
36963698
|| prev_opcode == ZEND_PRE_DEC
36973699
|| prev_opcode == ZEND_POST_INC
36983700
|| prev_opcode == ZEND_POST_DEC) {
3699-
return 1;
3701+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37003702
}
37013703
} else if ((ssa_op-1)->result_def == ssa_op->op2_use) {
3702-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3704+
ssa_op--;
3705+
opline = ssa_opcodes[ssa_op - ssa->ops];
3706+
prev_opcode = opline->opcode;
37033707
if (prev_opcode == ZEND_ADD
37043708
|| prev_opcode == ZEND_SUB) {
3705-
return 1;
3709+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0 &&
3710+
(OP2_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37063711
}
37073712
}
37083713
}
@@ -3711,18 +3716,23 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o
37113716
&& Z_LVAL_P(RT_CONSTANT(opline, opline->op2)) == 0) {
37123717
if (ssa_op->op1_use >= 0) {
37133718
if ((ssa_op-1)->op1_def == ssa_op->op1_use) {
3714-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3719+
ssa_op--;
3720+
opline = ssa_opcodes[ssa_op - ssa->ops];
3721+
prev_opcode = opline->opcode;
37153722
if (prev_opcode == ZEND_PRE_INC
37163723
|| prev_opcode == ZEND_PRE_DEC
37173724
|| prev_opcode == ZEND_POST_INC
37183725
|| prev_opcode == ZEND_POST_DEC) {
3719-
return 1;
3726+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37203727
}
37213728
} else if ((ssa_op-1)->result_def == ssa_op->op1_use) {
3722-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3729+
ssa_op--;
3730+
opline = ssa_opcodes[ssa_op - ssa->ops];
3731+
prev_opcode = opline->opcode;
37233732
if (prev_opcode == ZEND_ADD
37243733
|| prev_opcode == ZEND_SUB) {
3725-
return 1;
3734+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0 &&
3735+
(OP2_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37263736
}
37273737
}
37283738
}
@@ -4977,9 +4987,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49774987
op2_info = OP2_INFO();
49784988
skip_comparison =
49794989
ssa_op != ssa->ops &&
4980-
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4981-
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4982-
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes);
4990+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4991+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4992+
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes, op_array);
49834993
CHECK_OP1_TRACE_TYPE();
49844994
CHECK_OP2_TRACE_TYPE();
49854995
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {
@@ -5025,9 +5035,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50255035
op2_info = OP2_INFO();
50265036
skip_comparison =
50275037
ssa_op != ssa->ops &&
5028-
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
5029-
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
5030-
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes);
5038+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
5039+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
5040+
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes, op_array);
50315041
CHECK_OP1_TRACE_TYPE();
50325042
CHECK_OP2_TRACE_TYPE();
50335043
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12286,6 +12286,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst,
1228612286
if (op2_info & MAY_BE_ANY) {
1228712287
| IF_NOT_ZVAL_TYPE op2_addr, IS_UNDEF, >1
1228812288
}
12289+
| SET_EX_OPLINE opline, r0
1228912290
| mov FCARG1d, opline->op2.var
1229012291
| EXT_CALL zend_jit_undefined_op_helper, r0
1229112292
|1:

ext/opcache/tests/jit/cmp_007.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
JIT CMP: 007 Wrong comparison skip
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+
--FILE--
10+
<?php
11+
function test($a) {
12+
var_dump(1 - $a != 0);
13+
}
14+
for ($i = 0; $i < 5; $i++) {
15+
test(null);
16+
}
17+
?>
18+
--EXPECT--
19+
bool(true)
20+
bool(true)
21+
bool(true)
22+
bool(true)
23+
bool(true)

ext/opcache/tests/jit/isset_001.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
ISSET_ISEMPTY_DIM with undefined variable
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
function test() {
11+
var_dump(isset($a[$undef]));
12+
}
13+
test();
14+
?>
15+
--EXPECTF--
16+
Warning: Undefined variable $undef in %s on line %d
17+
bool(false)

0 commit comments

Comments
 (0)