diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index da97d102f202..ea95f1ce99fc 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3215,10 +3215,16 @@ static zend_jit_reg_var* zend_jit_trace_allocate_registers(zend_jit_trace_rec *t zend_ssa_phi *phi = ssa->blocks[1].phis; while (phi) { - i = phi->sources[1]; - if (RA_HAS_IVAL(i) && !ssa->vars[phi->ssa_var].no_val) { - RA_IVAL_END(i, idx); - RA_IVAL_FLAGS(i) &= ~ZREG_LAST_USE; + if (RA_HAS_IVAL(phi->sources[1]) && !ssa->vars[phi->ssa_var].no_val) { + int cv = ssa->vars[phi->ssa_var].var; + int k; + + /* All SSA versions of a loop-carried CV share the same register */ + for (k = 0; k < ssa->vars_count; k++) { + if (ssa->vars[k].var == cv && RA_HAS_IVAL(k)) { + RA_IVAL_FLAGS(k) &= ~ZREG_LAST_USE; + } + } } phi = phi->next; } diff --git a/ext/opcache/tests/jit/gh22115.phpt b/ext/opcache/tests/jit/gh22115.phpt new file mode 100644 index 000000000000..a7c80e88d4e8 --- /dev/null +++ b/ext/opcache/tests/jit/gh22115.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-22115: Tracing JIT drops loop-PHI CV register from SNAPSHOT after intermediate op1_def +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=32M +opcache.jit=tracing +--FILE-- +> 16) & 0xFFFF; + continue; + } + return $s; + } + return $s; +} +$meta = [0 => 1 | (1 << 16), 1 => 2 | (2 << 16)]; +for ($w = 0; $w < 2000; $w++) f($meta, 3); +var_dump(f($meta, 3)); +?> +--EXPECT-- +int(1)