-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Change the ReciprocalEstimate and ReciprocalSqrtEstimate APIs to be mustExpand on RyuJIT #102098
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
b2d559e
Change the ReciprocalEstimate and ReciprocalSqrtEstimate APIs to be m…
tannergooding 30dc925
Apply formatting patch
tannergooding 67a391b
Fix the RV64 and LA64 builds
tannergooding 42a1dd5
Mark the ReciprocalEstimate and ReciprocalSqrtEstimate methods as Agg…
tannergooding f177bd2
Mark other usages of ReciprocalEstimate and ReciprocalSqrtEstimate in…
tannergooding 62933bc
Mark several non-deterministic APIs as BypassReadyToRun and skip intr…
tannergooding afdcb1b
Cleanup based on PR recommendations to rely on the runtime rather tha…
tannergooding 91d105c
Adding a regression test ensuring direct and indirect invocation of n…
tannergooding ed406bf
Add a note about non-deterministic intrinsic expansion to the botr
tannergooding 1b16a09
Apply formatting patch
tannergooding 1000066
Merge branch 'main' into fix-101731
tannergooding 0312112
Ensure vector tests are correctly validating against the scalar imple…
tannergooding 461c4b5
Fix the JIT/SIMD/VectorConvert test and workaround a 32-bit test issue
tannergooding 9983d9d
Skip a test on Mono due to a known/tracked issue
tannergooding 5bddfc1
Ensure that lowering on Arm64 doesn't make an assumption about cast s…
tannergooding 1e0879f
Ensure the tier0opts local is used
tannergooding f63c575
Ensure impEstimateIntrinsic bails out for APIs that need to be implem…
tannergooding File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
If I understand correctly there is no JIT side implementation limitation here. This is an EE side policy that ideally ought to be applied there (for example by some
bool onNonDeterministicIntrinsic(bool mustExpand)
JIT-EE function that returns true if the JIT should expand it).This approach will show up in the crossgen2 log with a misleading "JIT implementation limitation" error. Does that only happen inside our own definitions of these intrinsics? If so I guess I can live with it (and in any case if changing this we can do it in a follow up to unblock CI asap).
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.
Does this message show up to end users if they use composite mode?
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, only for the recursive expansion. The regular expansion is handled gracefully by simply not doing it, so it persists as a regular CALL instead.
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.
Not sure. Happy to test, just not familiar with the best way to do that however.
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.
Could you elaborate a bit on how you would expect this to work?
It's unclear to me how the JIT would use this to fail compilation for the method. We can certainly have the VM say that the JIT is compiling for an unknown machine (which differs from JIT which is current machine and NAOT which is a specific machine), but the JIT would still only be able to call
implLimitation()
here as a result of that JIT/EE call.The VM could avoid trying to compile such a method entirely, but that would entail it doing the check for whether the call is recursive and that's not always trivial to do given the various if/else patterns and constant folding that can occur. The JIT is really the best thing equipped to detect the actual recursion.
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.
So it's less
bool onNonDeterministicIntrinsic(bool mustExpand)
and morevoid notifyNonDeterministicIntrinsicUsage(NamedIntrinsic intrinsic, bool mustExpand)
or something to that effect, which then allows the VM to decide to throw out the compilation result (such as by throwing or some other mechanism).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.
Explicit tailcalls in crossgen2 do not result in "JIT implementation limitation". I have personally used these messages to investigate our cases where we fail R2R compilations, and if I saw "JIT implementation limitation" I would assume something we should be fixing on the JIT side as implementation limitations within the JIT should not be hittable in practice.
Completely failing a compilation is a pretty large decision. Having to abuse
implLimitation()
to do so is an indication to me that it should be done on the EE side.That would be another way to do it, I was just wanting to move all of the policy to the EE side in a single JIT-EE 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.
Happy to do the work here if it's desired.
I do, in general, like the premise of a JIT/EE call of the shape
bool notifyNonDeterministicOperationUsage(SomeIdentifier identifier, bool mustExpand) const
. We have many places in the JIT today that are queryingopts.IsReadyToRun()
and potentially not accounting for NAOT (such as in valuenum), many of these places are specifically just trying to consider the fact that some edge case handling is non-deterministic and figure out whether something like constant folding is "ok". So having something that allows us to basically query if the VM supports seems beneficial. Longer term, it would also allow playing into multiple compilations if that was ever desired (say compiling once for legacy, once for VEX, once for EVEX, etc).Such a shape matches the general look of
bool notifyInstructionSetUsage(CORINFO_InstructionSet isa, bool supported) const
and plays into the same consideration of being able to simply say "I'm trying to do this, is it okay" and with the expectation thatmustExpand == true
can't returnfalse
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 certainly am not going to lose sleep over not changing this right at this moment. If you think this will be more broadly useful elsewhere then I don't mind leaving this as a clean up to happen as part of that work when we get to 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.
What would the EE side of this callback look like? I think that the EE side will either implement this as unconditional no-op (for non-resilient codegen) or as unconditional exception throw (for resilient codegen). The JIT is told whether to generate resilient or non-resilient code via compilation JIT flags. I do not see the point in asking EE about whether you really meant to generate resilient code.
I have glanced over valuenum and I do not see any problems there. There is a history behind why NAOT is treated as R2R. It does not necessarily match how some devs think about it these days. I would be fine with using less ambiguous names here.
I see this as JIT implementation limitation. We can implement this properly in the JIT and get rid of
BlockNonDeterministicIntrinsics
if we want. It would require the JIT to figure out the best hardware level to target (same as what we do in other places that use hw intrinsics opportunistically), and let the EE know that the code took a dependency on the exact hardware spec vianotifyInstructionSetUsage
. We may need to expand thenotifyInstructionSetUsage
to make it work well and future proof.Short of that, if we do not like the "JIT implementation limitation" message being show to the user in the verbose log, we can introduce JIT/EE interface
implementationLimination(char* message)
method that shows an implementation limitation error with a custom message.