Skip to content

Commit de04211

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: JIT: Fixed wrong comparison skip
2 parents 28aceed + a666f28 commit de04211

File tree

2 files changed

+48
-15
lines changed

2 files changed

+48
-15
lines changed

ext/opcache/jit/zend_jit_trace.c

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

3683-
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)
3683+
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)
36843684
{
36853685
zend_uchar prev_opcode;
36863686

@@ -3689,18 +3689,23 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o
36893689
&& Z_LVAL_P(RT_CONSTANT(opline, opline->op1)) == 0) {
36903690
if (ssa_op->op2_use >= 0) {
36913691
if ((ssa_op-1)->op1_def == ssa_op->op2_use) {
3692-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3692+
ssa_op--;
3693+
opline = ssa_opcodes[ssa_op - ssa->ops];
3694+
prev_opcode = opline->opcode;
36933695
if (prev_opcode == ZEND_PRE_INC
36943696
|| prev_opcode == ZEND_PRE_DEC
36953697
|| prev_opcode == ZEND_POST_INC
36963698
|| prev_opcode == ZEND_POST_DEC) {
3697-
return 1;
3699+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
36983700
}
36993701
} else if ((ssa_op-1)->result_def == ssa_op->op2_use) {
3700-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3702+
ssa_op--;
3703+
opline = ssa_opcodes[ssa_op - ssa->ops];
3704+
prev_opcode = opline->opcode;
37013705
if (prev_opcode == ZEND_ADD
37023706
|| prev_opcode == ZEND_SUB) {
3703-
return 1;
3707+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0 &&
3708+
(OP2_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37043709
}
37053710
}
37063711
}
@@ -3709,18 +3714,23 @@ static bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_ssa_o
37093714
&& Z_LVAL_P(RT_CONSTANT(opline, opline->op2)) == 0) {
37103715
if (ssa_op->op1_use >= 0) {
37113716
if ((ssa_op-1)->op1_def == ssa_op->op1_use) {
3712-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3717+
ssa_op--;
3718+
opline = ssa_opcodes[ssa_op - ssa->ops];
3719+
prev_opcode = opline->opcode;
37133720
if (prev_opcode == ZEND_PRE_INC
37143721
|| prev_opcode == ZEND_PRE_DEC
37153722
|| prev_opcode == ZEND_POST_INC
37163723
|| prev_opcode == ZEND_POST_DEC) {
3717-
return 1;
3724+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37183725
}
37193726
} else if ((ssa_op-1)->result_def == ssa_op->op1_use) {
3720-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3727+
ssa_op--;
3728+
opline = ssa_opcodes[ssa_op - ssa->ops];
3729+
prev_opcode = opline->opcode;
37213730
if (prev_opcode == ZEND_ADD
37223731
|| prev_opcode == ZEND_SUB) {
3723-
return 1;
3732+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0 &&
3733+
(OP2_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
37243734
}
37253735
}
37263736
}
@@ -4975,9 +4985,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49754985
op2_info = OP2_INFO();
49764986
skip_comparison =
49774987
ssa_op != ssa->ops &&
4978-
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4979-
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4980-
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes);
4988+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4989+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4990+
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes, op_array);
49814991
CHECK_OP1_TRACE_TYPE();
49824992
CHECK_OP2_TRACE_TYPE();
49834993
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {
@@ -5023,9 +5033,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50235033
op2_info = OP2_INFO();
50245034
skip_comparison =
50255035
ssa_op != ssa->ops &&
5026-
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
5027-
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
5028-
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes);
5036+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
5037+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
5038+
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes, op_array);
50295039
CHECK_OP1_TRACE_TYPE();
50305040
CHECK_OP2_TRACE_TYPE();
50315041
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {

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)

0 commit comments

Comments
 (0)