Skip to content

Commit fd1ea3c

Browse files
kairoscindossche
andcommitted
Fix GH-24214: Bind shared JIT assignment values for OSR
Co-authored-by: Nora Dossche <7771979+ndossche@users.noreply.github.com>
1 parent 6e6ec4b commit fd1ea3c

4 files changed

Lines changed: 88 additions & 7 deletions

File tree

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ PHP NEWS
163163
- Opcache:
164164
. Fixed bug GH-24397 (Assertion failure when dumping JIT IR).
165165
(Ilia Alshanetsky)
166+
. Fixed bug GH-24214 (Function JIT fails to restore shared assignment values
167+
at loop entries when DFA optimization is disabled). (Alessio Attilio)
166168
. Fixed tracing JIT returning a wrapped integer instead of a float on
167169
integer overflow after an integer was compared with a float or
168170
numeric-string literal. (Ilia Alshanetsky)

‎ext/opcache/jit/zend_jit_ir.c‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,13 +1354,6 @@ static bool zend_jit_spilling_may_cause_conflict(zend_jit_ctx *jit, int var, ir_
13541354
&& (jit->ssa->cfg.blocks[jit->ssa->vars[jit->ssa->ops[jit->ssa->vars[var].definition].op1_use].definition_phi->block].flags & ZEND_BB_LOOP_HEADER)) {
13551355
/* Avoid moving spill store out of loop */
13561356
return 1;
1357-
} else if (jit->ssa->vars[var].definition >= 0
1358-
&& jit->ssa->ops[jit->ssa->vars[var].definition].op1_def == var
1359-
&& jit->ssa->ops[jit->ssa->vars[var].definition].op1_use >= 0
1360-
&& jit->ssa->ops[jit->ssa->vars[var].definition].op2_use >= 0
1361-
&& jit->ra[jit->ssa->ops[jit->ssa->vars[var].definition].op2_use].ref == val) {
1362-
/* Avoid spill conflict between of ASSIGN.op1_def and ASSIGN.op1_use */
1363-
return 1;
13641357
}
13651358
return 0;
13661359
}
@@ -1387,6 +1380,14 @@ static void zend_jit_def_reg(zend_jit_ctx *jit, zend_jit_addr addr, ir_ref val)
13871380
val = ir_emit2(&jit->ctx, IR_OPT(IR_COPY, jit->ctx.ir_base[val].type), val, 1);
13881381
}
13891382
}
1383+
if (jit->ssa->vars[var].var < jit->current_op_array->last_var
1384+
&& jit->ssa->vars[var].definition >= 0
1385+
&& jit->ssa->ops[jit->ssa->vars[var].definition].op1_def == var
1386+
&& jit->ssa->ops[jit->ssa->vars[var].definition].op1_use >= 0
1387+
&& jit->ssa->ops[jit->ssa->vars[var].definition].op2_use >= 0
1388+
&& jit->ra[jit->ssa->ops[jit->ssa->vars[var].definition].op2_use].ref == val) {
1389+
val = ir_emit2(&jit->ctx, IR_OPT(IR_COPY, jit->ctx.ir_base[val].type), val, 1);
1390+
}
13901391
if (!zend_jit_spilling_may_cause_conflict(jit, var, val)) {
13911392
val = ir_bind(&jit->ctx, -EX_NUM_TO_VAR(jit->ssa->vars[var].var), val);
13921393
}

‎ext/opcache/tests/jit/gh24214.phpt‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
GH-24214 (Shared assignment values must be restored at function JIT loop entries)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.jit=1235
9+
opcache.jit_buffer_size=64M
10+
opcache.jit_hot_loop=1
11+
opcache.optimization_level=0x7FFEBFDF
12+
--FILE--
13+
<?php
14+
function markTokens(array $tokens): array {
15+
$n = count($tokens);
16+
for ($i = 0; $i < $n; ++$i) {
17+
$tokens[$i][4] = true;
18+
}
19+
return $tokens;
20+
}
21+
22+
var_dump(markTokens([[], [], []]) === [[4 => true], [4 => true], [4 => true]]);
23+
24+
foreach ([3, 0, 1, 64] as $size) {
25+
$tokens = markTokens(array_fill(0, $size, []));
26+
var_dump(count($tokens) === $size);
27+
var_dump($tokens === array_fill(0, $size, [4 => true]));
28+
}
29+
?>
30+
--EXPECT--
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
bool(true)
36+
bool(true)
37+
bool(true)
38+
bool(true)
39+
bool(true)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
GH-24214 (Shared floating-point assignment values must be restored at function JIT loop entries)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.jit=1235
9+
opcache.jit_buffer_size=64M
10+
opcache.jit_hot_loop=1
11+
opcache.optimization_level=0x7FFEBFDF
12+
--FILE--
13+
<?php
14+
function markTokens(array $tokens): array {
15+
$n = (float) count($tokens);
16+
for ($i = 0; $i < $n; ++$i) {
17+
$tokens[$i][4] = true;
18+
}
19+
return $tokens;
20+
}
21+
22+
var_dump(markTokens([[], [], []]) === [[4 => true], [4 => true], [4 => true]]);
23+
24+
foreach ([3, 0, 1, 64] as $size) {
25+
$tokens = markTokens(array_fill(0, $size, []));
26+
var_dump(count($tokens) === $size);
27+
var_dump($tokens === array_fill(0, $size, [4 => true]));
28+
}
29+
?>
30+
--EXPECT--
31+
bool(true)
32+
bool(true)
33+
bool(true)
34+
bool(true)
35+
bool(true)
36+
bool(true)
37+
bool(true)
38+
bool(true)
39+
bool(true)

0 commit comments

Comments
 (0)