Skip to content

OPcache: preserve constant and reusable expression assignment values - #24762

Open
aasul wants to merge 2 commits into
php:PHP-8.4from
aasul:fix/gh24683-jit-cv-lifetime
Open

aasul wants to merge 2 commits into
php:PHP-8.4from
aasul:fix/gh24683-jit-cv-lifetime

Conversation

@aasul

@aasul aasul commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

AI assistance disclosure: OpenAI Codex assisted with development, source review, validation, and this description.

Preserve identical typed constants when assignment cleanup paths produce the same IR constant. Building a PHI and then a CV-bound COPY can let the constant spill move before the guard protecting the assignment and overwrite a still-live CV value.

Separately, give reusable pure-expression results and CV assignments distinct hard COPY identities. A later assignment can otherwise overwrite a CV-backed spill that CSE still needs. After optimized liveness and coalescing, reuse the checked assignment COPY's storage only for adjacent, identically typed definitions whose ranges cover every later source range. Reject coalesced/live-in intervals and direct source snapshots, and retain independent storage when those checks fail.

The extra independent values initially exhausted the fixed trace spill frame on a five-expression floating-point workload: the earlier A+C candidate compiled one trace and logged 26 compilation errors. Checked sharing restores two compiled traces with zero errors; read-only probes on current PHP 8.4 and 8.5 show 16 bytes needed within the unchanged 32-byte frame.

Regression coverage includes the original A case, the original two-file C case, a natural floating-point CSE failure, and a pressure test that requires successful trace compilation without requiring an exact trace count. The floating-point PHPT naturally reports wrong: 725 before C's correction and wrong: 0 afterward on local x86_64.

Final Linux x86_64 validation (zero failures or warnings in these runs):

Configuration PASS SKIP
Current PHP 8.4 debug NTS, full JIT directory (59f8e1d2653c) 505 10
Current PHP 8.5 debug NTS, full JIT directory (2546fe9e827e) 520 10
Current PHP 8.4 + #24484 and #24635, full JIT directory 508 10
Preserved PHP 8.5 + both PRs, full JIT directory (d98dc49a9a59) 522 10
PHP 8.5 debug ZTS, full JIT directory (d98dc49a9a59) 519 10
PHP 8.5 release NTS, four new PHPTs (d98dc49a9a59) 4 0
Committed PHP 8.4 files, final focused PHPT run 4 0

Nine fixtures agree across interpreter, function JIT, and tracing JIT in each of those six runtime configurations. Original A compiles its loop and caller link (six traces), original C compiles its root (one trace), and the floating-point and unchanged pressure workloads each compile two traces, all without compilation errors.

The original C reproduction already passes naturally on local x86_64 builds before this change. The separate floating-point reproducer and the earlier controlled spill-store diagnostic provide additional evidence: the diagnostic produced 939 wrong calls before / zero after on PHP 8.5, and 936 / zero on PHP 8.4. Those diagnostic artifacts were reviewed separately from natural execution. Natural ARM64 validation remains outstanding.

Compatibility was checked with the actual code and tests at #24484 head 53f79bd859dd5a0c7e2dbfea363dec760512e6b8 and #24635 head 54b5f7cf0c5e2796d62ecaf0c280d0c7e53be1e7. The conflict check still runs before the new COPY, preserving #24484's older-reference safeguard. Both GH-24471 tests pass standalone, but that behavioral overlap does not replace #24484. GH-24634 still requires #24635: its separate test fails standalone and passes in both combined builds.

This contribution covers the two inspected mechanisms, not every possible CV binding problem. Reproduction B still cannot compile its intended tracing path locally (zero compiled traces, 14 compilation errors) and remains unresolved; correct fallback output is not evidence of a B fix.

Refs GH-24683.

aasul added 2 commits October 26, 2026 22:36
Keep an identical typed constant as the result of assignment cleanup
branches instead of creating a PHI and a CV-bound COPY. A movable COPY
can otherwise spill the constant into the CV before the assignment's
guard, overwriting a value that the trace still needs.

Add the original constant-assignment regression from phpGH-24683.

Refs phpGH-24683.
Give pure-expression CV assignments their own hard COPY, including when
the existing conflict check rejects a binding. A later assignment must
not overwrite storage still needed by a reusable expression.

After optimized liveness and coalescing, share a checked bound COPY's
spill slot only when adjacent definitions have compatible types, the
COPY's ranges cover every later source range, neither interval was
coalesced or live before its definition, and no snapshot names the source.
Keep separate value identities and private source spills otherwise.

This avoids exhausting the fixed trace spill frame in safe reuse cases.
Add the original two-file C reproduction, a natural floating-point CSE
regression, and a test requiring successful compilation under pressure.

Refs phpGH-24683.
@aasul
aasul requested a review from dstogov as a code owner October 26, 2026 21:48
Copilot AI balanced review requested due to automatic review settings October 26, 2026 21:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants