[php-src] PR #24651: Tracing JIT: keep the SEND_VAL type guard after assigning to a reference

From: Date: Sat, 24 Oct 2026 15:42:54 +0000
Subject: [php-src] PR #24651: Tracing JIT: keep the SEND_VAL type guard after assigning to a reference
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39823@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24651 Author: waroad @ndossche here is the patch I offered in the issue, as you asked. With opcache.jit=tracing, a trace like sink($x = $y + 2) can be recorded while $x is a reference to an untyped property, then run while $x is a reference to a typed float (or string) property. When that happens, sink() receives an int holding the raw bits of the converted value: int(4617315517961601024) instead of float(5), and for a string property an unrelated int (int(1097804056) in my run) instead of string(1) "5". When an ASSIGN result goes straight into the following SEND_VAL, the tracing JIT fuses the two. The result is written directly into the callee's argument slot, the SEND_VAL is skipped, and the callee's parameter takes the type recorded for the SEND_VAL operand. That type was never checked. It's fine when the result is a copy of the guarded op2, but the typed reference helper can coerce the value, so the recorded type may be wrong. The fix stops fusing in that case: when op1 is a guarded reference (ref_addr is set), the result goes to its own slot as usual, and SEND_VAL checks its type and side-exits if it doesn't match. The reference branch also had a second copy of the result address / send-fusion code, which the shared code right after it already does. I removed that copy so there is only one place to apply the condition. The new test ext/opcache/tests/jit/gh24436.phpt runs the same call site with untyped, typed float and typed string property references. It fails without the patch and passes with it, both with run-tests' defaults and with CI's tracing JIT options. The reproducer from the issue, run with the command line given there, also prints int(4617315517961601024) before the patch and float(5) after. ext/opcache/tests passes in both tracing and function JIT modes. I based this on PHP-8.4 since that's the branch I reproduced and tested on. Fixes #24436. Found with an LLM-based testing tool; I wrote this fix with help from Claude and reviewed it myself.

« previous php.git-pulls (#39823) next »