Skip to content

Commit

Permalink
Fix removal of unreachable code in SCCP
Browse files Browse the repository at this point in the history
Due to a wrongly placed check, we were only performing the
unreachable code removal if there were loop vars...
  • Loading branch information
nikic committed Feb 22, 2019
1 parent 4a98f42 commit ea115a6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
7 changes: 3 additions & 4 deletions ext/opcache/Optimizer/scdf.c
Expand Up @@ -189,6 +189,9 @@ static zend_bool kept_alive_by_loop_var_free(scdf_ctx *scdf, uint32_t block_idx)
const zend_op_array *op_array = scdf->op_array;
const zend_cfg *cfg = &scdf->ssa->cfg;
const zend_basic_block *block = &cfg->blocks[block_idx];
if (!(cfg->flags & ZEND_FUNC_FREE_LOOP_VAR)) {
return 0;
}
for (i = block->start; i < block->start + block->len; i++) {
zend_op *opline = &op_array->opcodes[i];
if (opline->opcode == ZEND_FE_FREE ||
Expand All @@ -215,10 +218,6 @@ int scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
zend_ssa *ssa = scdf->ssa;
int i;
int removed_ops = 0;

if (!(ssa->cfg.flags & ZEND_FUNC_FREE_LOOP_VAR)) {
return 0;
}
for (i = 0; i < ssa->cfg.blocks_count; i++) {
if (!zend_bitset_in(scdf->executable_blocks, i)
&& (ssa->cfg.blocks[i].flags & ZEND_BB_REACHABLE)
Expand Down
38 changes: 38 additions & 0 deletions ext/opcache/tests/opt/sccp_026.phpt
@@ -0,0 +1,38 @@
--TEST--
SCCP 026: Elimination of dead code due to conflicting type checks
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
opcache.opt_debug_level=0x20000
opcache.preload=
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
function test($var) {
if (!is_string($var) || (is_object($var) && !method_exists($var, '__toString'))) {
return;
}

var_dump($username);
}
?>
--EXPECTF--
$_main: ; (lines=1, args=0, vars=0, tmps=0)
; (after optimizer)
; %s:1-10
L0 (10): RETURN int(1)

test: ; (lines=9, args=1, vars=2, tmps=1)
; (after optimizer)
; %s:2-8
L0 (2): CV0($var) = RECV 1
L1 (3): T2 = TYPE_CHECK (string) CV0($var)
L2 (3): JMPZ T2 L4
L3 (3): JMP L5
L4 (4): RETURN null
L5 (7): INIT_FCALL 1 %d string("var_dump")
L6 (7): SEND_VAR CV1($username) 1
L7 (7): DO_ICALL
L8 (8): RETURN null

0 comments on commit ea115a6

Please sign in to comment.