Skip to content

Commit fdb05b9

Browse files
committed
Only replace IN_ARRAY result type for JMPZ/JMPNZ
Replacing the result type in the general case is dangerous, because not all opcodes support both VAR and TMP. One common case is the in_array() result being passed to SEND_VAR, which would have to be changed to SEND_VAL. Rather than complicating this logic, reduce the scope to only doing the type replacement for JMPZ and JMPNZ. The only reason we're doing this in the first place is to enable the smart branch optimization, so we can limit it to the relevant opcodes. Replacing the result type may be marginally useful in other cases as well (as it may avoid reference checks), but not worth the bother.
1 parent e77ac88 commit fdb05b9

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

ext/opcache/Optimizer/dfa_pass.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -474,16 +474,16 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
474474
int var = ssa_op->result_def;
475475
int use = ssa->vars[var].use_chain;
476476

477-
if (ssa->vars[var].phi_use_chain == NULL) {
478-
if (ssa->ops[use].op1_use == var
479-
&& ssa->ops[use].op1_use_chain == -1) {
480-
call_info->caller_call_opline->result_type = IS_TMP_VAR;
481-
op_array->opcodes[use].op1_type = IS_TMP_VAR;
482-
} else if (ssa->ops[use].op2_use == var
483-
&& ssa->ops[use].op2_use_chain == -1) {
484-
call_info->caller_call_opline->result_type = IS_TMP_VAR;
485-
op_array->opcodes[use].op2_type = IS_TMP_VAR;
486-
}
477+
/* If the result is used only in a JMPZ/JMPNZ, replace result type with
478+
* IS_TMP_VAR, which will enable use of smart branches. Don't do this
479+
* in other cases, as not all opcodes support both VAR and TMP. */
480+
if (ssa->vars[var].phi_use_chain == NULL
481+
&& ssa->ops[use].op1_use == var
482+
&& ssa->ops[use].op1_use_chain == -1
483+
&& (op_array->opcodes[use].opcode == ZEND_JMPZ
484+
|| op_array->opcodes[use].opcode == ZEND_JMPNZ)) {
485+
call_info->caller_call_opline->result_type = IS_TMP_VAR;
486+
op_array->opcodes[use].op1_type = IS_TMP_VAR;
487487
}
488488
}
489489
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Don't replace IN_ARRAY result type if the using opcode doesn't support it
3+
--FILE--
4+
<?php
5+
6+
function test($v) {
7+
$ary = ['x', 'y'];
8+
var_dump(in_array($v, $ary));
9+
}
10+
test('x');
11+
12+
?>
13+
--EXPECT--
14+
bool(true)

0 commit comments

Comments
 (0)