[php-src] Issue #22115: Tracing JIT: side-exit SNAPSHOT omits a loop-PHI register, interpreter resumes

[email protected] (wilaak) Thu, 21 May 2026 23:32:41 +0000
Newsgroups php.bugs
Message-ID <4pnZ0pQ0T9uyZ16zlq5sLCxrPycq7A6qEHZZdTPlLSU@main.internal.php.net>
Issue: https://github.com/php/php-src/issues/22115
Author: wilaak

### Description

### 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
<?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 fcc29c8d.


### PHP Version

```plain
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.