Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding System.Runtime.CompilerServices.Unsafe.BitCast #82917

Merged
merged 13 commits into from
Mar 8, 2023

Conversation

tannergooding
Copy link
Member

This resolves #81334

@dotnet-issue-labeler dotnet-issue-labeler bot added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI new-api-needs-documentation labels Mar 2, 2023
@dotnet-issue-labeler
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost ghost assigned tannergooding Mar 2, 2023
@ghost
Copy link

ghost commented Mar 2, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak
See info in area-owners.md if you want to be subscribed.

Issue Details

This resolves #81334

Author: tannergooding
Assignees: -
Labels:

area-CodeGen-coreclr, new-api-needs-documentation

Milestone: -

@stephentoub
Copy link
Member

Where should we be using this in runtime?

@tannergooding
Copy link
Member Author

Where should we be using this in runtime?

Working on getting that up. We can use it in BitConverter, in Enum (where we're going from TEnum to known underlying type), and in a few various places that Unsafe.As<TFrom, TTo> is being used today to remove the "address taken" consideration.

@Wraith2
Copy link
Contributor

Wraith2 commented Mar 3, 2023

Does this also need adding to mono?

@tannergooding
Copy link
Member Author

Does this also need adding to mono?

Yesn't. Since there is a software fallback, Mono isn't going to fail.

MonoLLVM looks to already be doing the right things but might benefit throughput wise if it was special cased. The same goes for MonoJIT and WASM.

@tannergooding tannergooding marked this pull request as ready for review March 3, 2023 23:12
@tannergooding
Copy link
Member Author

CC. @dotnet/jit-contrib


bool involvesStructType = false;

if (fromType == TYP_STRUCT)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this whole condition be simplified to

if ((fromType == TYP_STRUCT) ^ ((fromType == TYP_STRUCT))
    return null;
if ((fromType == TYP_STRUCT) && ((fromType == TYP_STRUCT))
    ...

?
(nit)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that code is much less obvious and harder to read/understand. It's the kind of thing that you have to stop and think about boolean tables to remember what it does.

The current code is a bit more verbose, but I think that almost anyone can understand what's happening.


GenTree* op1 = impPopStack().val;

if (op1->IsCnsFltOrDbl())
Copy link
Member

@EgorBo EgorBo Mar 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move these foldings to gtFoldExprConst ? (or I'd expect them to be already there) so we can just emit bitcast here and have much simpler logic - it is a bit hard to read. Although, you don't even need to call gtFoldExprConst here, it will likely be called by someone else in importer, e.g. if it's part of a condition for a branch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, but I think it can/should be a separate PR given it has to touch a bit of unrelated other code that exists.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notably, we can't "easily" do this since it would regress handling on 32-bit for double/int64. Once we add the relevant decomposition support then it won't be so problematic.

public static TTo BitCast<TFrom, TTo>(TFrom source)
where TFrom : struct
where TTo : struct
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this check IsReferenceOrContainsReferences on TFrom/TTo and throw?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply checking that IsReferenceOrContainsReferences is the same between TFrom and TTo will only catch a subset of cases. It won't catch the more complex cases where they match, but the layouts are then considered "incompatible".

The implementation will "do the right thing" as the software fallback just uses As<TFrom, TTo>(ref value) and the intrinsic logic checks for compatible layouts. It's just that them being actually incompatible may result in UB, much as it would for As or many of the other Unsafe APIs.

Copy link
Member

@EgorBo EgorBo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM assuming CI passes

@tannergooding tannergooding merged commit 3f3db95 into dotnet:main Mar 8, 2023
@tannergooding tannergooding deleted the bitcast branch March 8, 2023 22:18
@ghost ghost locked as resolved and limited conversation to collaborators Apr 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI new-api-needs-documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[API Proposal]: Unsafe.BitCast for efficient type reinterpretation
7 participants