Skip to content

Commit a743fd7

Browse files
committed
JIT: Fixed wrong comparison skip
1 parent 6ab36fb commit a743fd7

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
@@ -3433,7 +3433,7 @@ static void zend_jit_trace_update_condition_ranges(const zend_op *opline, const
34333433
}
34343434
}
34353435

3436-
static zend_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)
3436+
static zend_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)
34373437
{
34383438
zend_uchar prev_opcode;
34393439

@@ -3442,18 +3442,23 @@ static zend_bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_
34423442
&& Z_LVAL_P(RT_CONSTANT(opline, opline->op1)) == 0) {
34433443
if (ssa_op->op2_use >= 0) {
34443444
if ((ssa_op-1)->op1_def == ssa_op->op2_use) {
3445-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3445+
ssa_op--;
3446+
opline = ssa_opcodes[ssa_op - ssa->ops];
3447+
prev_opcode = opline->opcode;
34463448
if (prev_opcode == ZEND_PRE_INC
34473449
|| prev_opcode == ZEND_PRE_DEC
34483450
|| prev_opcode == ZEND_POST_INC
34493451
|| prev_opcode == ZEND_POST_DEC) {
3450-
return 1;
3452+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
34513453
}
34523454
} else if ((ssa_op-1)->result_def == ssa_op->op2_use) {
3453-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3455+
ssa_op--;
3456+
opline = ssa_opcodes[ssa_op - ssa->ops];
3457+
prev_opcode = opline->opcode;
34543458
if (prev_opcode == ZEND_ADD
34553459
|| prev_opcode == ZEND_SUB) {
3456-
return 1;
3460+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0 &&
3461+
(OP2_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
34573462
}
34583463
}
34593464
}
@@ -3462,18 +3467,23 @@ static zend_bool zend_jit_may_skip_comparison(const zend_op *opline, const zend_
34623467
&& Z_LVAL_P(RT_CONSTANT(opline, opline->op2)) == 0) {
34633468
if (ssa_op->op1_use >= 0) {
34643469
if ((ssa_op-1)->op1_def == ssa_op->op1_use) {
3465-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3470+
ssa_op--;
3471+
opline = ssa_opcodes[ssa_op - ssa->ops];
3472+
prev_opcode = opline->opcode;
34663473
if (prev_opcode == ZEND_PRE_INC
34673474
|| prev_opcode == ZEND_PRE_DEC
34683475
|| prev_opcode == ZEND_POST_INC
34693476
|| prev_opcode == ZEND_POST_DEC) {
3470-
return 1;
3477+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
34713478
}
34723479
} else if ((ssa_op-1)->result_def == ssa_op->op1_use) {
3473-
prev_opcode = ssa_opcodes[(ssa_op - ssa->ops) - 1]->opcode;
3480+
ssa_op--;
3481+
opline = ssa_opcodes[ssa_op - ssa->ops];
3482+
prev_opcode = opline->opcode;
34743483
if (prev_opcode == ZEND_ADD
34753484
|| prev_opcode == ZEND_SUB) {
3476-
return 1;
3485+
return (OP1_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0 &&
3486+
(OP2_INFO() & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)-MAY_BE_LONG)) == 0;
34773487
}
34783488
}
34793489
}
@@ -4777,9 +4787,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
47774787
op2_info = OP2_INFO();
47784788
skip_comparison =
47794789
ssa_op != ssa->ops &&
4780-
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4781-
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4782-
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes);
4790+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4791+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4792+
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes, op_array);
47834793
CHECK_OP1_TRACE_TYPE();
47844794
CHECK_OP2_TRACE_TYPE();
47854795
if ((opline->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {
@@ -4825,9 +4835,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
48254835
op2_info = OP2_INFO();
48264836
skip_comparison =
48274837
ssa_op != ssa->ops &&
4828-
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4829-
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG &&
4830-
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes);
4838+
(op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4839+
(op2_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG &&
4840+
zend_jit_may_skip_comparison(opline, ssa_op, ssa, ssa_opcodes, op_array);
48314841
CHECK_OP1_TRACE_TYPE();
48324842
CHECK_OP2_TRACE_TYPE();
48334843
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)