[php-src] Issue #24397: JIT: ir_save assertion `((ref) < 0)` failed when dumping IR with opcache.jit_debug on a foreach loop
| From: | waroad | Date: | Sun, 18 Oct 2026 06:27:40 +0000 |
| Subject: | [php-src] Issue #24397: JIT: ir_save assertion `((ref) < 0)` failed when dumping IR with opcache.jit_debug on a foreach loop | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-253018@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/24397
Author: waroad
With a debug build, dumping the JIT IR via
opcache.jit_debug aborts in
ir_save() on a function containing a foreach. The script was generated by
a testing tool, not taken from a real program.
```php
<?php
function f() { foreach ([1, 2] as $v) $c[] = $v; }
f();
```
```
php -n -d opcache.enable_cli=1 -d opcache.file_update_protection=0 -d opcache.jit=function -d
opcache.jit_buffer_size=64M -d opcache.jit_debug=16777216 reduced.php
```
The IR text is printed up to a BEGIN node, then:
```
l_88 = LOOP_END(l_87);
l_89 = BEGIN(l_36php: ext/opcache/jit/ir/ir_save.c:397: ir_save: Assertion `((ref) < 0)'
failed.
```
I expected the full IR dump to be printed and the process to exit 0, which is what the release build
does with the same command.
Reproduces at 17b6575a3dc4 (latest upstream when checked). The debug build aborts with SIGABRT (exit
134); the release build prints the whole dump and exits 0, so this is an assertion-only failure.
Without opcache.jit_debug the debug build runs the script cleanly. Any of the IR dump
bits 1<<24 to 1<<31 trigger it; the tracing JIT with the same bit did not fail on this
input.
This looks like ir_save() in ext/opcache/jit/ir/ir_save.c (case
IR_OPND_LABEL_REF) assuming a non-zero label operand is a constant (negative) ref, while the
BEGIN node of the foreach loop has an instruction (positive) ref there. Either the IR
builder or the dumper's assumption is off.
I can send a patch if that helps.
Found with an LLM-based testing tool; I used Claude to reduce it and look for the cause.