Skip to content

Commit

Permalink
Don't replace values in unreachable code in sccp
Browse files Browse the repository at this point in the history
While technically legal, this may cause unexpected situations
(in this example, setting an FE_FREE operand to constant null)
and is suboptimal anyway. It's better to preserve the vacuous type
and drop it later (though we currently don't implement this).
  • Loading branch information
nikic committed Sep 20, 2021
1 parent b4d7387 commit 1b33da5
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
6 changes: 6 additions & 0 deletions ext/opcache/Optimizer/sccp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2139,6 +2139,12 @@ static zval *value_from_type_and_range(sccp_ctx *ctx, int var_num, zval *tmp) {
return NULL;
}

if (!(info->type & MAY_BE_ANY)) {
/* This code must be unreachable. We could replace operands with NULL, but this doesn't
* really make things better. It would be better to later remove this code entirely. */
return NULL;
}

if (!(info->type & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_NULL))) {
ZVAL_NULL(tmp);
return tmp;
Expand Down
33 changes: 28 additions & 5 deletions ext/opcache/tests/opt/sccp_022.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,23 @@ function foo(int $x) {
$a->foo = 5;
echo $a[1];
}
function bar() {
foreach ($a as $v) {
foreach ($v as $v2) {}
}
}
?>
--EXPECTF--
$_main:
; (lines=1, args=0, vars=0, tmps=0)
; (after optimizer)
; %ssccp_022.php:1-10
; %s
0000 RETURN int(1)

foo:
; (lines=10, args=1, vars=2, tmps=1)
; (lines=11, args=1, vars=2, tmps=1)
; (after optimizer)
; %ssccp_022.php:2-8
; %s
0000 CV0($x) = RECV 1
0001 ASSIGN_DIM CV1($a) int(0)
0002 OP_DATA CV0($x)
Expand All @@ -37,5 +42,23 @@ foo:
0005 ECHO string("5")
0006 ASSIGN_OBJ CV1($a) string("foo")
0007 OP_DATA int(5)
0008 T2 = FETCH_DIM_R null int(1)
0009 RETURN null
0008 T2 = FETCH_DIM_R CV1($a) int(1)
0009 ECHO T2
0010 RETURN null

bar:
; (lines=9, args=0, vars=3, tmps=2)
; (after optimizer)
; %s
0000 V3 = FE_RESET_R CV0($a) 0007
0001 FE_FETCH_R V3 CV1($v) 0007
0002 V4 = FE_RESET_R CV1($v) 0005
0003 FE_FETCH_R V4 CV2($v2) 0005
0004 JMP 0003
0005 FE_FREE V4
0006 JMP 0001
0007 FE_FREE V3
0008 RETURN null
LIVE RANGES:
3: 0001 - 0007 (loop)
4: 0003 - 0005 (loop)

0 comments on commit 1b33da5

Please sign in to comment.