diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 5aa62d2e0878..9e53faaf0e08 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3290,6 +3290,7 @@ static zend_jit_reg_var* zend_jit_trace_allocate_registers(zend_jit_trace_rec *t RA_REG_FLAGS(def) |= ZREG_LOAD; RA_REG_FLAGS(use) |= ZREG_STORE; } else { + /* trace-entry value */ use = phi->sources[0]; if (zend_jit_var_supports_reg(ssa, use)) { ZEND_ASSERT(!RA_HAS_REG(use)); @@ -3298,6 +3299,8 @@ static zend_jit_reg_var* zend_jit_trace_allocate_registers(zend_jit_trace_rec *t count++; } else { RA_REG_FLAGS(def) |= ZREG_LOAD; + /* back-edge value */ + RA_REG_FLAGS(phi->sources[1]) |= ZREG_STORE; } } } else if (RA_HAS_REG(use)) { diff --git a/ext/opcache/tests/jit/gh24206.phpt b/ext/opcache/tests/jit/gh24206.phpt new file mode 100644 index 000000000000..258aa9d2eb1d --- /dev/null +++ b/ext/opcache/tests/jit/gh24206.phpt @@ -0,0 +1,65 @@ +--TEST-- +GH-24206: Tracing JIT loses loop-carried CV when its loop PHI is reloaded from memory +--EXTENSIONS-- +opcache +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=64M +opcache.jit=tracing +--CREDITS-- +Fabien Potencier and Symfony contributors +mercierj +--FILE-- + 1, "\xc3" => 2, "\xa9" => 0]; + + public static function scan(string $s): int { + $n = strlen($s); + $count = 0; + for ($i = 0; $i < $n; ++$i) { + $char = $s[$i]; + $size = self::MAP[$char]; + if ($size == 0) { + return -1; + } + for ($j = 1; $j < $size; ++$j) { + } + $i += $j - 1; + ++$count; + } + return $count; + } +} + +var_dump(Scanner::scan(str_repeat("a", 200) . "\xc3\xa9" . "aaa")); + +?> +--EXPECT-- +int(204)