Skip to content

Commit dbe2cdd

Browse files
committed
Merge branch 'PHP-8.0'
* PHP-8.0: Fix DCE of FREE of COALESCE Note that this is a non-trivial merge, as opt/coalesce.phpt regresses with this change. I'll have to see if it can be improved.
2 parents 513ad97 + 59b2a89 commit dbe2cdd

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

Zend/Optimizer/dce.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,16 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, bool reorder_d
527527
ctx.phi_dead = alloca(sizeof(zend_ulong) * ctx.phi_worklist_len);
528528
memset(ctx.phi_dead, 0xff, sizeof(zend_ulong) * ctx.phi_worklist_len);
529529

530+
/* Mark non-CV phis as live. Even if the result is unused, we generally cannot remove one
531+
* of the producing instructions, as it combines producing the result with control flow.
532+
* This can be made more precise if there are any cases where this is not the case. */
533+
FOREACH_PHI(phi) {
534+
if (phi->var >= op_array->last_var) {
535+
zend_bitset_excl(ctx.phi_dead, phi->ssa_var);
536+
add_phi_sources_to_worklists(&ctx, phi, 0);
537+
}
538+
} FOREACH_PHI_END();
539+
530540
/* Mark reacable instruction without side effects as dead */
531541
int b = ssa->cfg.blocks_count;
532542
while (b > 0) {

ext/opcache/tests/opt/coalesce.phpt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,17 @@ $_main:
2929
0000 RETURN int(1)
3030

3131
a:
32-
; (lines=2, args=0, vars=1, tmps=1)
32+
; (lines=3, args=0, vars=1, tmps=1)
3333
; (after optimizer)
3434
; %s
35-
0000 T1 = COALESCE CV0($test) 0001
36-
0001 RETURN bool(true)
35+
0000 T1 = COALESCE CV0($test) 0002
36+
0001 T1 = QM_ASSIGN bool(true)
37+
0002 RETURN bool(true)
3738

3839
b:
39-
; (lines=2, args=0, vars=1, tmps=1)
40+
; (lines=3, args=0, vars=1, tmps=1)
4041
; (after optimizer)
4142
; %s
42-
0000 T1 = COALESCE CV0($test) 0001
43-
0001 RETURN bool(true)
43+
0000 T1 = COALESCE CV0($test) 0002
44+
0001 T1 = ASSIGN CV0($test) bool(true)
45+
0002 RETURN bool(true)

ext/opcache/tests/opt/dce_010.phpt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Incorrect DCE of FREE of COALESCE
3+
--FILE--
4+
<?php
5+
6+
function test(?string $str) {
7+
$str ?? $str = '';
8+
return strlen($str);
9+
}
10+
11+
$foo = 'foo';
12+
$foo .= 'bar';
13+
var_dump(test($foo));
14+
15+
?>
16+
--EXPECT--
17+
int(6)

0 commit comments

Comments
 (0)