Bug #81226 [Com]: Integer overflow behavior is different with JIT enabled

From: Date: Mon, 12 Jul 2021 13:15:52 +0000
Subject: Bug #81226 [Com]: Integer overflow behavior is different with JIT enabled
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-234971@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81226&edit=1

 ID:                 81226
 Comment by:         hao dot sun at arm dot com
 Reported by:        smokey101stair at gmail dot com
 Summary:            Integer overflow behavior is different with JIT
                     enabled
 Status:             Open
 Type:               Bug
 Package:            JIT
 Operating System:   Ubuntu 20.04
 PHP Version:        8.0.8
 Block user comment: N
 Private report:     N

 New Comment:

I can reproduce this bug in my local environment even with functional JIT.

I noticed that this bug doesn't occur in JIT/x86 on master branch.
After bisect, I guess the root cause is that the following patches in master branch are not merged
to PHP-8.0.*.

https://github.com/php/php-src/commit/5e05c70ee727815805697a90b39f4d82cd4b4d3d#diff-c0fa9f6cbf84b02388699bafb28a11d7f69780bbf2b0e1bceea4cb99763c1328
https://github.com/php/php-src/commit/186a5277aa237b1f98cd0a74f43c535b8958f85b#


Previous Comments:
------------------------------------------------------------------------
[2021-07-07 00:02:12] smokey101stair at gmail dot com

Perhaps you will have better luck reproducing when it is extracted into a function, which also
reproduces the issue for me

<?php

// 65-bit hexadecimal number
$hex = '10000000000000041';

function getNumericReference(string $hex) {
    $characterReferenceCode = 0;

    for ($j = 0, $len = strlen($hex); $j < $len; ++$j) {
        $characterReferenceCode *= 16;
        $characterReferenceCode += ord($hex[$j]) - 0x0030;
    }

    return $characterReferenceCode;
}

for ($i = 0; $i < 20000; ++$i) {
    assert(getNumericReference($hex) > 0x10FFFF);
}

------------------------------------------------------------------------
[2021-07-06 13:54:06] smokey101stair at gmail dot com

Are you able to reproduce if you increase the iterations from 200 to 20000? If not, I'll have
to recheck it when I get home. Is there any other info I can provide to help debug this?

------------------------------------------------------------------------
[2021-07-06 12:59:39] nikic@php.net

This one doesn't reproduce for me.

------------------------------------------------------------------------
[2021-07-06 00:39:00] smokey101stair at gmail dot com

Description:
------------
When $characterReferenceCode overflows in the test script with the JIT enabled, sometimes it
evaluates to 65 and other times it evaluates to 1.844674407371E+19. The expected value is
1.844674407371E+19.

With opcache.jit_debug=1 I get the following:

TRACE-1$/home/trevor/jit_test2.php$9: ; (unknown)
        mov $EG(jit_trace_num), %rax
        mov $0x1, (%rax)
        mov $EG(vm_stack_end), %rax
        mov (%rax), %rcx
        mov $EG(vm_stack_top), %rax
        sub (%rax), %rcx
        cmp $0x60, %rcx
        jb jit$$trace_exit_0
.L1:
        cmp $0x4, 0x88(%r14)
        jnz jit$$trace_exit_1
        cmp $0x4, 0x98(%r14)
        jnz jit$$trace_exit_1
        mov 0x80(%r14), %rax
        cmp 0x90(%r14), %rax
        jge jit$$trace_exit_2
        cmp $0x4, 0x78(%r14)
        jnz jit$$trace_exit_3
        mov 0x70(%r14), %rax
        shl $0x4, %rax
        jo .L6
        mov %rax, 0x70(%r14)
.L2:
        mov $EG(vm_stack_top), %r15
        mov (%r15), %r15
        mov $EG(vm_stack_top), %rdx
        add $0x60, (%rdx)
        mov $0x0, 0x28(%r15)
        mov $0x5572643c6590, %rcx
        mov %rcx, 0x18(%r15)
        mov $0x0, 0x20(%r15)
        mov $0x1, 0x2c(%r15)
        cmp $0x6, 0x58(%r14)
        jnz jit$$trace_exit_4
        cmp $0x4, 0x88(%r14)
        jnz jit$$trace_exit_4
        mov $0x409da8e0, (%r14)
        mov 0x50(%r14), %rdi
        mov 0x80(%r14), %rsi
        mov $zend_jit_fetch_dim_str_offset_r_helper, %rax
        call *%rax
        mov %rax, 0xa0(%r14)
        mov $0x6, 0xa8(%r14)
        mov $EG(exception), %rax
        cmp $0x0, (%rax)
        jnz JIT$$exception_handler
        cmp $0x6, 0xa8(%r14)
        jnz jit$$trace_exit_6
        mov 0xa0(%r14), %rdx
        mov %rdx, 0x50(%r15)
        mov 0xa8(%r14), %eax
        mov %eax, 0x58(%r15)
        mov $0x409da920, (%r14)
        mov %r14, 0x30(%r15)
        lea 0xb0(%r14), %rsi
        mov $0x1, 0x8(%rsi)
        mov $EG(current_execute_data), %rcx
        mov %r15, (%rcx)
        mov %r15, %rdi
        mov $0x557262a8e270, %rax
        call *%rax
        mov $EG(current_execute_data), %rax
        mov %r14, (%rax)
        test $0x1, 0x59(%r15)
        jnz .L7
.L3:
        mov $EG(vm_stack_top), %rax
        mov %r15, (%rax)
        mov $EG(exception), %rax
        cmp $0x0, (%rax)
        jnz JIT$$icall_throw
        mov $EG(vm_interrupt), %rax
        cmp $0x0, (%rax)
        jnz jit$$trace_exit_7
        mov 0xb0(%r14), %rax
        sub $0x30, %rax
        jo jit$$trace_exit_8
        mov %rax, 0xa0(%r14)
        mov $0x4, 0xa8(%r14)
        cmp $0x4, 0x78(%r14)
        jnz jit$$trace_exit_9
        mov 0x70(%r14), %rax
        add 0xa0(%r14), %rax
        jo .L8
        mov %rax, 0x70(%r14)
.L4:
        cmp $0x4, 0x88(%r14)
        jnz jit$$trace_exit_10
        add $0x1, 0x80(%r14)
        jo .L9
.L5:
        mov $EG(vm_interrupt), %rax
        cmp $0x0, (%rax)
        jz .L1
        jmp jit$$trace_exit_11
.L6:
        vxorps %xmm0, %xmm0, %xmm0
        vcvtsi2sd 0x70(%r14), %xmm0, %xmm0
        mov $0x10, %rax
        vxorps %xmm1, %xmm1, %xmm1
        vcvtsi2sd %rax, %xmm1, %xmm1
        vmulsd %xmm1, %xmm0, %xmm0
        vmovsd %xmm0, 0x70(%r14)
        mov $0x5, 0x78(%r14)
        jmp .L2
.L7:
        mov 0x50(%r15), %rdi
        sub $0x1, (%rdi)
        jnz .L3
        mov $0x409da920, (%r14)
        mov $rc_dtor_func, %rax
        call *%rax
        jmp .L3
.L8:
        vxorps %xmm0, %xmm0, %xmm0
        vcvtsi2sd 0x70(%r14), %xmm0, %xmm0
        vxorps %xmm1, %xmm1, %xmm1
        vcvtsi2sd 0xa0(%r14), %xmm1, %xmm1
        vaddsd %xmm1, %xmm0, %xmm0
        vmovsd %xmm0, 0x70(%r14)
        mov $0x5, 0x78(%r14)
        jmp .L4
.L9:
        mov $0x43e0000000000000, %rax
        mov %rax, 0x80(%r14)
        mov $0x5, 0x88(%r14)
        jmp .L5

Test script:
---------------
<?php

// 65-bit hexadecimal number
$hex = '10000000000000041';

for ($i = 0; $i < 200; ++$i) {
    $characterReferenceCode = 0;

    for ($j = 0, $len = strlen($hex); $j < $len; ++$j) {
        $characterReferenceCode *= 16;
        $characterReferenceCode += ord($hex[$j]) - 0x0030;
    }

    assert($characterReferenceCode > 0x10FFFF);
}




------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=81226&edit=1


Thread (7 messages)

« previous php.bugs (#234971) next »