Commit 1cb8a2fd42b for php

commit 1cb8a2fd42bba377f774089f75e4681c70eef0c6
Author: ChrisAbner <chrisabner@hotmail.com>
Date:   Tue Nov 10 21:53:06 2026 -0500

    Fix tracing JIT reading the int result of ++/-- on a reference as a double

    After zend_jit_inc_dec(), the double case dropped the speculative guard
    of the result when !(res_info & MAY_BE_STRING), which is always true
    there. For a reference the trace does not know the type of the value,
    so the result can be an int that the next ASSIGN then reads as a double.
    Check op1_info, like the long case does.

    Close GH-25383

diff --git a/NEWS b/NEWS
index 18ec48a2acf..82567c5abf3 100644
--- a/NEWS
+++ b/NEWS
@@ -64,6 +64,8 @@ PHP                                                                        NEWS
   . Fixed use-after-free in JIT when the error handler releases a string while
     an "Undefined variable" warning is raised for its offset in ?? or nested
     isset()/empty(). (Jorg Sowa)
+  . Fixed tracing JIT reading the int result of ++/-- on a reference as a
+    double. (ChrisAbner)

 - PDO_Firebird:
   . Fixed stack buffer overflow with long connection user names, passwords,
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index 9c54767fc22..2b9852aa614 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -4493,7 +4493,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
 							ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
 						} else if (opline->result_type != IS_UNUSED
 						 && (res_info & (MAY_BE_ANY|MAY_BE_GUARD)) == (MAY_BE_DOUBLE|MAY_BE_GUARD)
-						 && !(res_info & MAY_BE_STRING)) {
+						 && !(op1_info & MAY_BE_STRING)) {
 							ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
 						}
 						goto done;
diff --git a/ext/opcache/tests/jit/inc_025.phpt b/ext/opcache/tests/jit/inc_025.phpt
new file mode 100644
index 00000000000..c6dceb7ea8e
--- /dev/null
+++ b/ext/opcache/tests/jit/inc_025.phpt
@@ -0,0 +1,43 @@
+--TEST--
+JIT INC: 025 (result type of ++/-- on a reference after the trace saw a float)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.protect_memory=1
+opcache.jit=tracing
+--EXTENSIONS--
+opcache
+--FILE--
+<?php
+function pre_inc($a)  { $v = $a; $x = &$v; $out = []; for ($i = 0; $i < 4; $i++) { $out[] = ++$x; } return $out; }
+function post_inc($a) { $v = $a; $x = &$v; $out = []; for ($i = 0; $i < 4; $i++) { $out[] = $x++; } return $out; }
+function pre_dec($a)  { $v = $a; $x = &$v; $out = []; for ($i = 0; $i < 4; $i++) { $out[] = --$x; } return $out; }
+function glob_inc($a) { global $g; $g = $a; $out = []; for ($i = 0; $i < 4; $i++) { $out[] = ++$g; } return $out; }
+function stat_inc($a) { static $s; $s = $a; $out = []; for ($i = 0; $i < 4; $i++) { $out[] = ++$s; } return $out; }
+
+class P { public float|string $t = ''; }
+function typed_ref_inc($a) {
+    $o = new P; $o->t = $a; $x = &$o->t; $out = [];
+    for ($i = 0; $i < 4; $i++) { $out[] = $x++; }
+    return $out;
+}
+
+foreach (['pre_inc', 'post_inc', 'pre_dec', 'glob_inc', 'stat_inc'] as $f) {
+    for ($n = 0; $n < 20; $n++) {
+        $f(1.5);
+    }
+    echo $f, ' ', json_encode($f(5)), "\n";
+}
+for ($n = 0; $n < 20; $n++) {
+    typed_ref_inc(1.5);
+}
+echo 'typed_ref_inc ', json_encode(typed_ref_inc("2.5")), "\n";
+?>
+--EXPECT--
+pre_inc [6,7,8,9]
+post_inc [5,6,7,8]
+pre_dec [4,3,2,1]
+glob_inc [6,7,8,9]
+stat_inc [6,7,8,9]
+typed_ref_inc ["2.5",3.5,4.5,5.5]