[Webkit-unassigned] [Bug 178379] New: [ARM64] static_cast<int32_t>() in BinaryOpNode::emitBytecode() prevents op_unsigned emission

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Oct 17 00:33:58 PDT 2017


https://bugs.webkit.org/show_bug.cgi?id=178379

            Bug ID: 178379
           Summary: [ARM64] static_cast<int32_t>() in
                    BinaryOpNode::emitBytecode() prevents op_unsigned
                    emission
           Product: WebKit
           Version: WebKit Nightly Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: New Bugs
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: zan at falconsigh.net
                CC: utatane.tea at gmail.com

Using GCC 6.3.1 and targeting ARM64 on Linux, the stress/uint32-to-number-overflows-to-uint52.js JSC stress test (in all variations) fails since r223318 landed.

http://trac.webkit.org/browser/webkit/trunk/JSTests/stress/uint32-to-number-overflows-to-uint52.js

The compareToLargeNumber() function in that test is the problematic one:

> function compareToLargeNumber(value)
> {
>     return (value >>> 0) < 4294967294;
> }

Here's the generated bytecode output for this function on x86_64, which matches ARM64 before r223318:

compareToLargeNumber#D5ozQ8:[0x7ff965a890d0->0x7ff965aa8ba0, NoneFunctionCall, 20 (NeverInline)]: 20 m_instructions; 160 bytes; 2 parameter(s); 8 callee register(s); 6 variable(s); scope at loc3
[   0] enter             
[   1] get_scope         loc3
[   3] mov               loc4, loc3
[   6] check_traps       
[   7] urshift           loc6, arg1, Int32: 0(const0)
[  11] unsigned          loc6, loc6
[  14] less              loc6, loc6, Double: 4751297606871678976, 4294967294.000000(const1)
[  18] ret               loc6

Here's the currently generated bytecode on ARM64, missing op_unsigned:

compareToLargeNumber#D5ozQ8:[0x7f809890d0->0x7f809a8ba0, NoneFunctionCall, 17 (NeverInline)]: 17 m_instructions; 136 bytes; 2 parameter(s); 8 callee register(s); 6 variable(s); scope at loc3
[   0] enter             
[   1] get_scope         loc3
[   3] mov               loc4, loc3
[   6] check_traps       
[   7] urshift           loc6, arg1, Int32: 0(const0)
[  11] below             loc6, loc6, Double: 4751297606871678976, 4294967294.000000(const1)
[  15] ret               loc6

-----

Problem can be tracked to the double-to-int32_t conversion in the helper isUInt32() lambda in BinaryOpNode::emitBytecode(). On x86_64, the 4294967294.0 double value is converted to a negative 32-bit of value -2147483648, which prevents the m_shouldToUnsignedResult value for the op_urshift BinaryOpNode to be set to false, which ends up emitting op_unsigned and thus passing the test.

On ARM64, the same double value is converted to 2147483647. The GCC-generated code does this using the plain fcvtzs instruction:

>   6fe208:	940039b2 	bl	70c8d0 <JSC::NumberNode::value() const [clone .isra.109]>
>   6fe20c:	1e780000 	fcvtzs	w0, d0

Result of this is that both left and right sides of the binary op are recognized as an uint32 value, short-cutting op_unsigned and failing the test.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20171017/4341e61a/attachment.html>


More information about the webkit-unassigned mailing list