Commit 9f33bff0906 for php.net

commit 9f33bff09067fd3e5807df23a56b0560dca05b47
Author: Arnaud Le Blanc <arnaud.lb@gmail.com>
Date:   Wed Mar 25 19:01:49 2026 +0100

    Reset stackmap reg

    Add a missing `t->stack_map[...].reg = ZREG_NONE` in `zend_jit_snapshot_handler`.
    This is needed when reg is `ZREG_NONE`, otherwise side traces will have wrong
    assumptions.

    Fixes GH-21158
    Closes GH-21531

diff --git a/NEWS b/NEWS
index 0e042bb864c..d87ceb7d818 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,10 @@ PHP                                                                        NEWS
 - Iconv:
   . Fixed bug GH-17399 (iconv memory leak on bailout). (iliaal)

+- Opcache:
+  . Fixed bug GH-21158 (JIT: Assertion jit->ra[var].flags & (1<<0) failed in
+    zend_jit_use_reg). (Arnaud)
+
 - SPL:
   . Fixed bug GH-21499 (RecursiveArrayIterator getChildren UAF after parent
     free). (Girgias)
diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c
index b87abad4361..2bad605c537 100644
--- a/ext/opcache/jit/zend_jit_ir.c
+++ b/ext/opcache/jit/zend_jit_ir.c
@@ -835,6 +835,7 @@ void *zend_jit_snapshot_handler(ir_ctx *ctx, ir_ref snapshot_ref, ir_insn *snaps
 							addr = (void*)zend_jit_trace_get_exit_addr(exit_point);
 							exit_flags &= ~ZEND_JIT_EXIT_FIXED;
 						}
+						t->stack_map[t->exit_info[exit_point].stack_offset + var].reg = ZREG_NONE;
 						t->stack_map[t->exit_info[exit_point].stack_offset + var].flags = ZREG_TYPE_ONLY;
 					}
 				} else if (!(exit_flags & ZEND_JIT_EXIT_FIXED)) {
diff --git a/ext/opcache/tests/jit/gh21158.phpt b/ext/opcache/tests/jit/gh21158.phpt
new file mode 100644
index 00000000000..89afd058c66
--- /dev/null
+++ b/ext/opcache/tests/jit/gh21158.phpt
@@ -0,0 +1,49 @@
+--TEST--
+GH-21158: Assertion jit->ra[var].flags & (1<<0) failed in zend_jit_use_reg
+--CREDITS--
+YuanchengJiang
+--EXTENSIONS--
+opcache
+--INI--
+opcache.jit=1254
+--FILE--
+<?php
+define('ROW', 10);
+define('COL', 10);
+function count_live_neighbors($board, $row, $col) {
+    $live_neighbors = 0;
+    if ($col + 1 < COL && $board[$row][$col + 1] == 1) $live_neighbors++;
+    if ($row - 1 >= 0 && $col - 1 >= 0 && $board[$row - 1][$col - 1] == 1) $live_neighbors++;
+    if ($row >= 1 && $col + 1 < COL && $board[$row - 1][$col + 1] == 1) $live_neighbors++;
+    return $live_neighbors;
+}
+$board = [
+    [1,1,0,0,1,1,1,1,1,0],
+    [0,1,0,1,1,0,0,1,0,0],
+    [0,1,0,0,1,0,0,0,1,0],
+    [0,0,1,1,1,1,1,0,0,0],
+    [1,1,1,1,1,1,0,1,1,0],
+    [0,1,0,0,1,1,1,0,1,0],
+    [0,1,1,0,1,1,1,1,0,0],
+    [1,1,0,0,0,0,1,1,1,0],
+    [1,0,0,1,1,0,1,1,0,1],
+    [0,0,1,1,1,0,1,1,0,1],
+];
+for ($i = 0; $i < ROW; $i++) {
+    for ($j = 0; $j < COL; $j++) {
+        echo count_live_neighbors($board, $i, $j), ",";
+    }
+    echo "\n";
+}
+?>
+--EXPECT--
+1,0,0,1,1,1,1,1,0,0,
+2,1,2,2,1,2,3,2,1,1,
+2,0,2,2,1,1,1,1,1,0,
+1,1,2,2,1,2,0,1,0,1,
+1,2,2,3,3,2,2,2,0,0,
+2,2,2,3,3,2,2,2,1,1,
+2,1,1,2,2,3,2,2,0,1,
+2,1,1,2,1,3,3,2,1,0,
+1,1,2,1,0,2,2,2,2,1,
+0,2,2,2,1,3,2,1,3,0,