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

Update a few code paths to ensure the trimmer can do its job #106777

Merged
merged 3 commits into from
Oct 19, 2024

Conversation

tannergooding
Copy link
Member

This should help resolve #93399

There are potentially other less obvious cases I missed and there's quite a bit of code that is relying on the [CompExactlyDependsOn(...)] attribute and a higher level check for the trimmer to "work" as expected.

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Aug 21, 2024
@tannergooding tannergooding added area-System.Runtime.Intrinsics and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Aug 21, 2024
@tannergooding
Copy link
Member Author

@akoeplinger this should help resolve the trimmer size, is this a case you're wanting backported for .NET 9?

I think for .NET 10 we probably want to do a more complete look at the places using hardware intrinsics in the BCL and ensure they're all doing straightforward checks that both R2R and the linker can trivially understand.

internal static void ThrowUnreachableException()
{
#if NET
throw new UnreachableException();
Copy link
Member

Choose a reason for hiding this comment

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

TIL that this exception type exists. Does it have any special meaning from the perspective of the trimmer?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, its just the exception type we added explicitly to represent paths that should be "unreachable", so its the most appropriate one to use here.

{
// Workaround for missing MultiplyAddAdjacent on ARM
Vector128<short> even = AdvSimd.Arm64.TransposeEven(nibbles, Vector128<byte>.Zero).AsInt16();
Vector128<short> odd = AdvSimd.Arm64.TransposeOdd(nibbles, Vector128<byte>.Zero).AsInt16();
even = AdvSimd.ShiftLeftLogical(even, 4).AsInt16();
output = AdvSimd.AddSaturate(even, odd).AsByte();
}
else
{
// We explicitly recheck each IsSupported query to ensure that the trimmer can see which paths are live/dead
Copy link
Member

Choose a reason for hiding this comment

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

Could you explain why this added branch is necessary? My expectation is that the entire method should have been trimmed altogether if its preconditions are not met.

Copy link
Member Author

Choose a reason for hiding this comment

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

Some of the checks are "dynamic" and not statically true/false.

For example, if (Sse2.IsSupported) is statically true for x86/x64 and if (AdvSimd.Arm64.IsSupported) is statically false, but if (Ssse3.IsSupported) is dynamic because it depends on the underlying hardware.

This means that on an x86/x64 system, the TryDecodeFromUtf16 will always be preserved in IL. Prior to this PR, the else path was therefore being kept for the case that we were on hardware where Ssse3.IsSupported was false and that rooted AdvSimd.Arm64 on xarch unnecessarily.

With this change, we instead now allow the AdvSimd path to be trimmed out as dead code and the IL will instead keep the ThrowUnreachableException which allows things like R2R, the JIT, or AOT compilers to trim it out as dead code (because they will know the target hardware and treat Ssse3.IsSupported as constant, then allowing the method to be removed).

Copy link
Member

Choose a reason for hiding this comment

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

Thanks

Copy link
Member

@akoeplinger akoeplinger left a comment

Choose a reason for hiding this comment

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

LGTM, sorry I somehow missed the notification on this one before.

@tannergooding tannergooding merged commit 6cea093 into dotnet:main Oct 19, 2024
144 of 146 checks passed
@tannergooding tannergooding deleted the fix-93399 branch October 19, 2024 13:57
@github-actions github-actions bot locked and limited conversation to collaborators Nov 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[trimmer] per-RID linked corlib assembly contains foreign platform intrinsics classes
3 participants