-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Ensure that the new Vector512 related ISAs are covered by ILLink Substitutions #83040
Conversation
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer, @joperezr Issue Detailsnull
|
Just looking at "current" For example, // The 0->0 contract is fulfilled by setting the LSB to 1.
// Log(1) is 0, and setting the LSB for values > 1 does not change the log2 result.
value |= 1;
// value lzcnt actual expected
// ..0001 31 31-31 0
// ..0010 30 31-30 1
// 0010.. 2 31-2 29
// 0100.. 1 31-1 30
// 1000.. 0 31-0 31
if (Lzcnt.IsSupported)
{
return 31 ^ (int)Lzcnt.LeadingZeroCount(value);
}
if (ArmBase.IsSupported)
{
return 31 ^ ArmBase.LeadingZeroCount(value);
}
if (WasmBase.IsSupported)
{
return 31 ^ WasmBase.LeadingZeroCount(value);
}
// BSR returns the log2 result directly. However BSR is slower than LZCNT
// on AMD processors, so we leave it as a fallback only.
if (X86Base.IsSupported)
{
return (int)X86Base.BitScanReverse(value);
}
// Fallback contract is 0->0
return Log2SoftwareFallback(value); This is being folded down to: value |= 1U;
if (Lzcnt.IsSupported)
return 31 ^ (int) Lzcnt.LeadingZeroCount(value);
if (true) { } // ArmBase.IsSupported
if (true) { } // WasmBase.IsSupported
return X86Base.IsSupported ? (int) X86Base.BitScanReverse(value) : BitOperations.Log2SoftwareFallback(value); Note that |
Also noticed that However, CC. @MichalStrehovsky on this and the immediate above. |
Also noting we have a They're in a separate location so they're easy to miss. It looks like they are being properly handled/processed however. |
I think so. Alternatively, we could have the IsSupported implemented as a constant true in the C# source code instead of the recursive call; that would work too. It's the reason why WasmBase gets stubbed out even though there's no substitution file for NoWasm (we have ILLink.Substitutions.NoArmIntrinsics.xml and ILLink.Substitutions.NoX86Intrinsics.xml, but no NoWasmIntrinsics.xml - I assume for historical reasons?).
IIRC these have the same underlying numerical constants so it doesn't matter. Either way X86 doesn't work with NativeAOT. We might as well delete the |
@MichalStrehovsky Hmmm, we actually can't do this, unfortunately... Basically while it is part of the baseline and "always supported", we also have a release mode config knob ( Such knobs exist so that users can more easily test their various software fallback paths in addition to the intrinsic paths. Replacing the method with returning This is somewhat unfortunate as it means we can't actually trim as much as we'd like while still maintaining accuracy in the exposed APIs. Is there any other feature that might make it feasible to allow trimming here for crossgen2 (where such knobs don't exist) while still allowing indirect queries to work as expected? |
CC. @dotnet/jit-contrib, @dotnet/avx512-contrib Should be ready for review. |
Crossgen2 should "trim" it based on my mental model. Crossgen2 currently pregenerates all public APIs in an assembly and privates are generated as-needed. So when crossgen2 compiles a method body, it will let RyuJIT do the substitution for |
Thanks! I think this should be generally ready for review then. CC. @dotnet/jit-contrib, @dotnet/avx512-contrib |
@@ -5210,7 +5274,7 @@ public new abstract partial class X64 : System.Runtime.Intrinsics.X86.Sse3.X64 | |||
public static new bool IsSupported { get { throw null; } } | |||
} | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(nit) was this generated with the tool? Some classes have a blank line between them, and some don't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but also not entirely...
Several of the corelib facades have bits that weren't done by the tool (often attributes or simple ordering things) and which make generating this "properly" result in large diffs.
So, I typically cut out just the new bits from the generated file and paste them into the checked in copy to avoid that issue.
We should probably do the work to ensure they are in sync again, but it hasn't bubbled up in priority yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public static new bool IsSupported { get => IsSupported; } | ||
|
||
[Intrinsic] | ||
public new abstract class VL : Avx512F.VL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the public nested types need doc comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but it looks like "all" of them are currently missing for System.Runtime.Intrinsics.*
.
I'll log an issue and gets this handled in a follow up PR later tonight.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -21,6 +24,42 @@ | |||
<type fullname="System.Runtime.Intrinsics.X86.Avx2/X64"> | |||
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" /> | |||
</type> | |||
<type fullname="System.Runtime.Intrinsics.X86.Avx512BW"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need ILLink.Substitution entries for these when we also have the .PlatformNotSupported.cs
versions that just return false
? This xml file seems to be included in the same condition as when those .cs files are used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsure actually. Maybe some legacy thing from back when they weren't guaranteed false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like I originally did it in ee12b54, but looking back I'm not sure it is needed. Since we are just following existing convention here, let's not block this PR on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ILLink changes LGTM.
Now that the foundational PRs are in, they'll be several people iterating on adding Vector512 related intrinsics concurrently.
Having these classes defined up front helps reduce merge conflicts and other issues that would otherwise arise.
This makes progress towards #73604, #74813, and #76579