Bug 221438 - [JSC] Atomics.store in DFG / FTL should return ToNumber(input) value
Summary: [JSC] Atomics.store in DFG / FTL should return ToNumber(input) value
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Yusuke Suzuki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-02-04 16:51 PST by Yusuke Suzuki
Modified: 2021-02-05 00:45 PST (History)
2 users (show)

See Also:


Attachments
Patch (20.36 KB, patch)
2021-02-04 16:54 PST, Yusuke Suzuki
fpizlo: review+
Details | Formatted Diff | Diff
Patch (22.02 KB, patch)
2021-02-04 18:32 PST, Yusuke Suzuki
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yusuke Suzuki 2021-02-04 16:51:11 PST
[JSC] Atomics.store in DFG / FTL should return ToNumber(input) value
Comment 1 Yusuke Suzuki 2021-02-04 16:54:56 PST
Created attachment 419341 [details]
Patch
Comment 2 Yusuke Suzuki 2021-02-04 16:54:59 PST
<rdar://problem/73973264>
Comment 3 Filip Pizlo 2021-02-04 17:05:45 PST
Comment on attachment 419341 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=419341&action=review

I think you should at least rationalize toIntegerOrInfinity - usually when we say "toFooOrBlah", we mean "convert to foo or return blah", and here you're returning zero.

> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:2353
> +        if (node->op() == AtomicsStore) {
> +            switch (node->arrayMode().type()) {
> +            case Array::Generic:
> +                clobberWorld();
> +                makeHeapTopForNode(node);
> +                break;
> +            default: {
> +                switch (node->result()) {
> +                case NodeResultJS:
> +                    setNonCellTypeForNode(node, SpecInt32Only);
> +                    break;
> +                case NodeResultInt52:
> +                    setNonCellTypeForNode(node, SpecInt52Any);
> +                    break;
> +                case NodeResultDouble:
> +                    setNonCellTypeForNode(node, SpecFullDouble);
> +                    break;
> +                default:
> +                    DFG_CRASH(m_graph, node, "Bad result type");
> +                    break;
> +                }
> +                break;
> +            }
> +            }
> +            break;
> +        }

It's not clear why the switch below this wouldn't handle this properly.  I think that this is worth a good comment.  It's also a bit weird that we're casing on result type rather than the operand type.  Usually, we use the operand's useKind as the criterion we switch on - and from reading the fixup code, it seems like the result type is completely determined by the stored value operand useKind.

> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:19659
> +    LValue toIntegerOrInfinity(LValue doubleValue)
> +    {
> +        return m_out.select(m_out.doubleNotEqualAndOrdered(doubleValue, m_out.doubleZero), m_out.doubleTrunc(doubleValue), m_out.doubleZero);
> +    }

This returns zero in the else case, not infinity.
Comment 4 Filip Pizlo 2021-02-04 17:16:07 PST
Comment on attachment 419341 [details]
Patch

Yusuke convinced me that tointegerorinfinity is right.
Comment 5 Yusuke Suzuki 2021-02-04 18:23:32 PST
Comment on attachment 419341 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=419341&action=review

>> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:2353
>> +        }
> 
> It's not clear why the switch below this wouldn't handle this properly.  I think that this is worth a good comment.  It's also a bit weird that we're casing on result type rather than the operand type.  Usually, we use the operand's useKind as the criterion we switch on - and from reading the fixup code, it seems like the result type is completely determined by the stored value operand useKind.

Yup. The reason is that returned value from AtomicsStore does not rely on typed array types. For example,

Atomics.store(uint8Array, /* index */ 0, Infinity) // => returned value is Infinity

Since the other RMW atomics are returning value stored in the typed array previously, the returned value relies on the typed array types.
On the other hand, Atomics.store's returned value is input value. This means that Atomics.store+Uint8Array can return doubles while the typed array is Uint8Array (the above one is the example).
So,

        case Array::Uint8Array:
            setNonCellTypeForNode(node, SpecInt32Only);
            break;

this is not correct for AtomicsStore. AtomicsStore does not rely on typed array types, it rely on the input values type. And in fixup phase, we properly set result-type based on input value's type for AtomicsStore.
So, here, we use it to show the abstract types for AtomicsStore operation.
I'll add comment about this. And use input's useKind instead.

>> Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:19659
>> +    }
> 
> This returns zero in the else case, not infinity.

Discussed with Phil at slack. This is aligned to the spec. I'll add comments to describe how this function works.
Comment 6 Yusuke Suzuki 2021-02-04 18:32:37 PST
Created attachment 419351 [details]
Patch
Comment 7 EWS 2021-02-05 00:45:19 PST
Committed r272405: <https://trac.webkit.org/changeset/272405>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 419351 [details].