[php-src] Issue #23983: Function JIT (8.4+): wrong result after interrupts are handled in a loop

From: Date: Tue, 29 Sep 2026 09:48:12 +0000
Subject: [php-src] Issue #23983: Function JIT (8.4+): wrong result after interrupts are handled in a loop
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-252849@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/23983 Author: frodeborli ### Description With the function JIT (opcache.jit=function) on PHP 8.4 and later, the function below returns a wrong result when interrupts (EG(vm_interrupt)) are handled while its loops run. Here the interrupt comes from pcntl_async_signals(); any zend_interrupt_function user triggers it the same way. ```php <?php $n = 0; pcntl_async_signals(true); pcntl_signal(SIGUSR1, function () use (&$n) { $n++; }); $pid = getmypid(); $p = proc_open(['sh', '-c', "while kill -USR1 $pid 2>/dev/null; do sleep 0.01; done"], [], $pipes); function f(&$n) { $x = 7; for ($i = 1; $n < 20; $i++) { $x = ($x * 31 + $i) & 0xffffff; } $y = 7; for ($j = 1; $j < $i; $j++) { $y = ($y * 31 + $j) & 0xffffff; } return $x === $y; } var_dump(f($n)); proc_terminate($p); ``` ``` php -d opcache.enable_cli=1 -d opcache.jit=function -d opcache.jit_buffer_size=64M test.php ``` Resulted in this output: ``` bool(false) ``` But I expected this output instead: ``` bool(true) ``` It fails on every run with 8.4.16, 8.5.11 and master; 8.2.30 and 8.3.35 (the pre-IR JIT) print bool(true), as do 8.4+ with opcache.jit=tracing or without the JIT. Small changes make it pass: $e = $x === $y; return $e;, returning [$x === $y, $x, $y] (which shows $x and $y equal), or a var_dump() inside f(). So it looks like a register-allocated value not being kept across the interrupt handler call. ### PHP Version ``` PHP 8.5.11 (cli) (NTS), also 8.4.16 and master (8.7.0-dev) ``` ### Operating System Ubuntu 24.04, x86_64

« previous php.bugs (#252849) next »