Description
tracing jit gives wrong answer on a hot loop. function jit and jit=off are fine so it's a tracing thing.
The following code:
<?php
declare(strict_types=1);
function lookup(string $tape, array $meta, array $state_meta, string $path): int
{
$length = \strlen($path);
$state_offset = 0;
$cursor = 1;
while ($cursor < $length) {
$run = \strcspn($tape, $path[$cursor], $state_offset, 1);
if ($run < 1) {
$m = (int) $meta[$state_offset];
$edge_length = $m & 0xFF;
if ($edge_length === 1
|| \substr_compare($path, "c", $cursor + 1, 1) === 0) {
$cursor += $edge_length;
$state_offset = ($m >> 32) & 0xFFFFFF;
continue;
}
}
return (int) $state_meta[$state_offset];
}
return (int) $state_meta[$state_offset];
}
$tape = "ab";
$meta = [0 => 1 | (1 << 32), 1 => 2 | (2 << 32)];
$state_meta = [0 => 100, 1 => 200, 2 => 300];
for ($w = 0; $w < 2000; $w++) {
lookup($tape, $meta, $state_meta, '/abc');
lookup($tape, $meta, $state_meta, '/abx');
}
var_dump(lookup($tape, $meta, $state_meta, '/abx'));
Resulted in this output:
$ php -d opcache.enable_cli=1 -d opcache.jit_buffer_size=64M -d opcache.jit=tracing repro.php
int(100)
But I expected this output instead:
$ php -d opcache.enable_cli=1 -d opcache.jit_buffer_size=64M -d opcache.jit=function repro.php
int(200)
Probable cause
the IR:
php -d opcache.enable_cli=1 -d opcache.jit=tracing \
-d opcache.jit_buffer_size=64M \
-d opcache.jit_debug=$((0xFFFFFFFF)) repro.php 2>&1 | less
exit_8 is the bad one, CV5($state_offset):int with no (r12).
Environment
php 8.5.6 cli, opcache 8.5.6, linux wsl2, gcc 14. master at fcc29c8.
PHP Version
PHP 8.5.6 (cli) (built: May 14 2026 16:01:51) (NTS)
Copyright (c) The PHP Group
Built by Ubuntu
Zend Engine v4.5.6, Copyright (c) Zend Technologies
with Zend OPcache v8.5.6, Copyright (c), by Zend Technologies
Operating System
Ubuntu 24.04.1 LTS (Noble Numbat) on WSL2, kernel 6.6.
Description
tracing jit gives wrong answer on a hot loop. function jit and jit=off are fine so it's a tracing thing.
The following code:
Resulted in this output:
But I expected this output instead:
Probable cause
the IR:
exit_8 is the bad one, CV5($state_offset):int with no (r12).
Environment
php 8.5.6 cli, opcache 8.5.6, linux wsl2, gcc 14. master at fcc29c8.
PHP Version
Operating System
Ubuntu 24.04.1 LTS (Noble Numbat) on WSL2, kernel 6.6.