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

Add empty X64/Arm64 nested classes to some System.Runtime.Intrinsics #34587

Closed
EgorBo opened this issue Apr 6, 2020 · 9 comments · Fixed by #38460
Closed

Add empty X64/Arm64 nested classes to some System.Runtime.Intrinsics #34587

EgorBo opened this issue Apr 6, 2020 · 9 comments · Fixed by #38460
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.Intrinsics breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Milestone

Comments

@EgorBo
Copy link
Member

EgorBo commented Apr 6, 2020

Rationale

Imagine you have an arm64 CPU with ArmBase and ArmBase.Arm64 support (both are always enabled for any arm64 CPU), but without Aes, Sha1 and Sha256 features, let's run the following snippet:

Console.WriteLine(ArmBase.IsSupported);       // true
Console.WriteLine(ArmBase.Arm64.IsSupported); // true

Console.WriteLine(Aes.IsSupported);           // false
Console.WriteLine(Aes.Arm64.IsSupported);     // true (??)

Console.WriteLine(Sha1.IsSupported);          // false
Console.WriteLine(Sha1.Arm64.IsSupported);    // true (??)

Console.WriteLine(Sha256.IsSupported);        // false
Console.WriteLine(Sha256.Arm64.IsSupported);  // true (??)

The problem here is the fact that Aes, Sha1 and Sha256 inherit from ArmBase but don't define their own Arm64 nested classes, see sharplab.io for more details (it explains why it can't be fixed in the jit).

Proposed API

    [Intrinsic]
    [CLSCompliant(false)]
    public abstract class Sha1 : ArmBase
    {
        internal Sha1() { }

        public static new bool IsSupported { get => IsSupported; }
        
+       public abstract class Arm64 : ArmBase.Arm64;
+       {
+           public static new bool IsSupported => Sha1.IsSupported; // && IntPtr.Size == 8 ?
+       }

(same for Sha256 and Aes)
UPD same for Aes, Avx, Avx2, Fma, Pclmulqdq, Sse3, Ssse3

/cc @tannergooding @echesakovMSFT

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-Infrastructure-coreclr untriaged New issue has not been triaged by the area owner labels Apr 6, 2020
@EgorBo EgorBo added api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime.Intrinsics labels Apr 6, 2020
@ghost
Copy link

ghost commented Apr 6, 2020

Tagging @tannergooding as an area owner

@EgorBo
Copy link
Member Author

EgorBo commented Apr 6, 2020

Ah, looks like the same problem exists for x64 as well, e.g.:

Console.WriteLine(Avx2.X64.IsSupported);

Prints true on a CPU without AVX2. (because it actually uses Sse42.X64.IsSupported for that)

So we need to do the same for: Aes, Avx, Avx2, Fma, Pclmulqdq, Sse3, Ssse3

@EgorBo EgorBo changed the title Add empty Arm64 nested class to Sha1, Sha256 and Aes. Add empty X64/Arm64 nested classes to some System.Runtime.Intrinsics Apr 6, 2020
@tannergooding
Copy link
Member

For x64 this is a possible breaking change if the user recompiles. I still think it provides a better experience, but it is something that needs to be considered.

@tannergooding tannergooding added api-ready-for-review breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation untriaged New issue has not been triaged by the area owner labels Apr 16, 2020
@BruceForstall BruceForstall added this to To do general in Hardware Intrinsics via automation Apr 16, 2020
@terrajobst terrajobst added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review labels May 5, 2020
@terrajobst
Copy link
Member

terrajobst commented May 5, 2020

Video

  • The problem makes sense, but instead of giving IsSupported behavior, it might be better to hide the nested classes entirely and make calling IsSupported a compile-time error:
    partial class Sha1 : ArmBase
    {
        [EditorBrowsable(Never)]
        public abstract class Arm64            
        {
            // No inheritance, no IsSupported
        }
    }

@JulieLeeMSFT JulieLeeMSFT added this to the 5.0 milestone May 18, 2020
@tannergooding
Copy link
Member

I believe this needs to go back to API review. For x64 in particular, the above doesn't work as there are scenarios like: Sse2 -> Sse3 -> Ssse3 -> Sse41

In this case, Sse2.X64 defines an X64 class as it has new 64-bit specific intrinsics as does Sse41.X64.
Sse3 and Ssse3 do not expose new 64-bit specific intrinsics however.

If we expose intermediate X64 classes which don't inherit and which don't expose an IsSupported then you get into a weird scenario with the actual inheritance hierarchy.
I think the original proposal, which is to expose the new class, have it inherit from BaseIsa.X64 and exppose an IsSupported property is the way to go and will be the most consistent with how the IsSupported checks already work.

It is already the case that Isa.IsSupported can return false but Isa.Method() succeeds because Isa.Method is actually resolved to SomeBaseIsa.Method where SomeBaseIsa.IsSupported is true.

@tannergooding
Copy link
Member

CC. @echesakovMSFT, @terrajobst

@terrajobst
Copy link
Member

terrajobst commented Jun 25, 2020

Video

  • Good point
  • When inheriting, we always should also define all nested types and define IsSupported the appropriately, even if they don't define any other members.
  • (this will probably require more nested types than listed below)
[Intrinsic]
[CLSCompliant(false)]
public partial class Sha1 : ArmBase
{
    public abstract class Arm64 : ArmBase.Arm64;
    {
        public static new bool IsSupported => Sha1.IsSupported && IntPtr.Size == 8;
    }
}

@terrajobst terrajobst added api-needs-work API needs work before it is approved, it is NOT ready for implementation api-approved API was approved in API review, it can be implemented and removed api-approved API was approved in API review, it can be implemented api-needs-work API needs work before it is approved, it is NOT ready for implementation labels Jun 25, 2020
Hardware Intrinsics automation moved this from To do general to Done Jul 10, 2020
@ericstj
Copy link
Member

ericstj commented Jul 24, 2020

@tannergooding
Copy link
Member

dotnet/docs#19682

@dotnet dotnet locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Runtime.Intrinsics breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
Development

Successfully merging a pull request may close this issue.

6 participants