-
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
Support MULX returning ValueTuple #61336
Conversation
Note regarding the 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. |
Tagging subscribers to this area: @JulieLeeMSFT |
So I tried to get the stale PR #37928 working again, but there are two issues that I'm having trouble with:
|
Math.BigMul diff is a slight improvement (due to the memory stores/loads), but actually it should generate this: mulx rax, rdx, rcx
mov qword ptr [r8], rdx
ret |
@EgorBo maybe you have some good hints? |
Speaking as a front-end person... There is an invariant in the Jit that promoted struct locals must be either:
As for the immediate cause of spilling, it is because this must be added as a new "special" case, along with the multireg calls, here: runtime/src/coreclr/jit/morphblock.cpp Lines 695 to 708 in b07b26d
|
@@ -3707,6 +3707,7 @@ public abstract partial class Bmi2 : System.Runtime.Intrinsics.X86.X86Base | |||
public static new bool IsSupported { get { throw null; } } | |||
public static uint MultiplyNoFlags(uint left, uint right) { throw null; } | |||
public unsafe static uint MultiplyNoFlags(uint left, uint right, uint* low) { throw null; } | |||
internal unsafe static (uint Lower, uint Upper) MultiplyNoFlags2(uint left, uint right) { 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: changes in /ref
are not required for internal
APIs.
/// MULX r32a, r32b, reg/m32 | ||
/// The above native signature does not directly correspond to the managed signature. | ||
/// </summary> | ||
internal static unsafe (uint Lower, uint Upper) MultiplyNoFlags2(uint left, uint right) => MultiplyNoFlags2(left, right); |
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.
I know this is an existing pattern for intrinsic, but would be less confusing if it is something like:
=> throw new NotImplementedException("Intrinsic must be implemented by the runtime.");
instead of recursive call.
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.
I note that the recursiveness is an implementation detail that allows (easy) detection of when the intrinsic must be expanded:
runtime/src/coreclr/jit/importer.cpp
Lines 3740 to 3741 in 1d352fc
// The recursive non-virtual calls to Jit intrinsics are must-expand by convention. | |
mustExpand = mustExpand || (gtIsRecursiveCall(method) && !(methodFlags & CORINFO_FLG_VIRTUAL)); |
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.
Ah, I see. Thanks for the link. IMO, it would have made the managed APIs more readable if the detection was based off of some descriptive construct.
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.
This implementation is actually there to support calls using reflection. It's mostly a theoretical concern, but precludes a need for special handling of reflection for HW intrinsics.
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.
However, for internal methods throwing might be a valid option, not sure.
Draft Pull Request was automatically closed for inactivity. Please let us know if you'd like to reopen it. |
Based on #37928, fixes #11782.