diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 9e16a9c55c9..ae067c58eb3 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -810,28 +810,30 @@ optimize_jmpnz: } break; case ZEND_COALESCE: - if (opline->op1_type == IS_CONST) { + { + zend_ssa_var *var = &ssa->vars[ssa_op->result_def]; + if (opline->op1_type == IS_CONST + && var->use_chain < 0 && var->phi_use_chain == NULL) { if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op1.constant)) == IS_NULL) { + zend_ssa_remove_result_def(ssa, ssa_op); MAKE_NOP(opline); removed_ops++; take_successor_1(ssa, block_num, block); goto optimize_nop; } else { - zend_ssa_var *var = &ssa->vars[ssa_op->result_def]; - if (var->use_chain < 0 && var->phi_use_chain == NULL) { - if (opline->result_type & (IS_TMP_VAR|IS_VAR)) { - zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition); - } - opline->opcode = ZEND_JMP; - opline->result_type = IS_UNUSED; - zend_ssa_remove_result_def(ssa, ssa_op); - COPY_NODE(opline->op1, opline->op2); - take_successor_0(ssa, block_num, block); - goto optimize_jmp; + if (opline->result_type & (IS_TMP_VAR|IS_VAR)) { + zend_optimizer_remove_live_range_ex(op_array, opline->result.var, var->definition); } + opline->opcode = ZEND_JMP; + opline->result_type = IS_UNUSED; + zend_ssa_remove_result_def(ssa, ssa_op); + COPY_NODE(opline->op1, opline->op2); + take_successor_0(ssa, block_num, block); + goto optimize_jmp; } } break; + } case ZEND_NOP: optimize_nop: compress_block(op_array, block); diff --git a/ext/opcache/tests/jmp_elim_004.phpt b/ext/opcache/tests/jmp_elim_004.phpt index e31af3da17b..f4053d9616b 100644 --- a/ext/opcache/tests/jmp_elim_004.phpt +++ b/ext/opcache/tests/jmp_elim_004.phpt @@ -9,9 +9,16 @@ opcache.optimization_level=-1 function test() { $foo = "test"; var_dump($foo ?? "default"); + + $null = null; + var_dump($null ?? 3); + var_dump($null ?? new stdClass); } test(); ?> --EXPECT-- string(4) "test" +int(3) +object(stdClass)#1 (0) { +}