Skip to content

Conversation

arnaud-lb
Copy link
Member

@arnaud-lb arnaud-lb commented Sep 3, 2025

Fixes GH-19669

When the assumption that (PRE|POST)_(INC|DEC) overflows turns out to be false and we exit, effects are lost if op1 or result were in regs.

Fix by updating the stack map before creating the exit point.

My understanding is the stack map is setup for exits to the same opline, but not for exits to the next opline (e.g. ZREG_LAST_USE entries are removed by zend_jit_trace_cleanup_stack). Therefore, we need manual stack map manipulations before creating exit points to the next opline.

Analysis of the reproducer:

function test() {
    $a = PHP_INT_MIN;
    $b = 0;
    while ($b++ < 2) {
        $a = (int) ($a-- + $a - $b);
    }
    return $a;
}

Opcodes:

0003 T2 = POST_DEC CV0($a)
0004 T3 = ADD T2 CV0($a)
0005 T2 = SUB T3 CV1($b)
  • POST_DEC is expected to underflow, so a guard is emitted
  • The guard fails at some point
  • During compilation of the side trace, the type of T2 in ADD T2 CV0($a) doesn't match type inference, which causes the assertion failure. This is because exiting from POST_DEC CV0($a) didn't update T2.

@arnaud-lb arnaud-lb changed the base branch from master to PHP-8.4 September 3, 2025 10:12
@arnaud-lb arnaud-lb changed the title Fix deoptimization after exit during POST_(INC|DEC) Fix deoptimization after exit during inc/dec Sep 4, 2025
@arnaud-lb arnaud-lb marked this pull request as ready for review September 4, 2025 13:32
@arnaud-lb arnaud-lb requested a review from dstogov as a code owner September 4, 2025 13:32
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.

assertion failure zend_jit_trace_type_to_info_ex
1 participant