Skip to content

Fix GH-24397: Clear vacated MERGE inputs in _zend_jit_fix_merges() - #437

Closed
iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-24397-jit-fix-merges-stale-inputs
Closed

iliaal wants to merge 1 commit into
PHP-8.4from
fix/gh-24397-jit-fix-merges-stale-inputs

Conversation

@iliaal

@iliaal iliaal commented Oct 18, 2026

Copy link
Copy Markdown
Owner

_zend_jit_fix_merges() compacts a MERGE's live inputs to the left without clearing the slots it vacates. When one input survives, the node becomes a BEGIN whose op2 is a label operand, so the stale END ref is read as a label: ir_save() asserts on it in debug builds when an IR dump bit is set in opcache.jit_debug, and in all builds the aliasing load and store searches treat the block as address-taken and stop there.

The test fails only on debug builds, since IR_ASSERT is compiled out in release. PHI compaction in the same function reads only up to inputs_count, and the PHI-to-COPY conversion already overwrites op2.

Fixes php#24397

_zend_jit_fix_merges() compacts the non-zero inputs of a MERGE or
LOOP_BEGIN to the left but left the vacated slots holding their old refs.
When a single input survives, the node becomes a BEGIN whose op2 is a
label operand, so the stale END ref was read as a label: ir_save()
asserted on it, and the aliasing load and store searches stopped at the
block as if its address were taken. PHI inputs are compacted the same way
but are bounded by inputs_count, and a PHI reduced to COPY already
overwrites op2.

Fixes phpGH-24397
@iliaal

iliaal commented Oct 18, 2026

Copy link
Copy Markdown
Owner Author

Submitted upstream as php#24419.

@iliaal iliaal closed this Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant