-
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
The "no." opcode prefix is not implemented #10112
Comments
I would think that, at the very least, we should ignore the opcode (other than the "correctness/verifiability" checks) rather than throwing I do think that supporting the opcode would be beneficial though, as it is basically a built-in way of doing certain JIT hints (https://github.com/dotnet/corefx/issues/26188). |
NOTE: Ignoring the prefix is allowed by the spec:
|
This would also be a completely valid implementation of the instructions. Unlike the |
Yes, it's optional, and ignoring it would be the very least in order to satisfy the spec. But I'd like to see it fully supported. I'm not familiar with the JIT implementation so I'm speculating here, but I'd guess that optionally removing existing checks shouldn't be too hard to implement. |
Related to #17469. Adds support for the IL `no.` prefix, which hints to the JIT to ignore certain checks. Currently implemented as a nop (which is ECMA335 compliant), but is validated.
If there is still use in this, I am currently implementing this so that the JIT just ignores it - during import, it just validates that the flags are correct and the opcode is correct and then does nothing with it. However, there are a couple of questions around it i am not sure about:
|
TBH implementing it so it's ignored is wasted effort unless it's a first step towards real support. |
Implementing it so it is ignored would mean there was the potential for langs to expose it, even if it initially does nothing, which could make it worth it to actually make it omit the checks |
Also, to be picky, helps ECMA compliance |
If future compatibility is what you want, I'd just ignore all invalid uses. This could be helpful if another flag is added to the instruction in the future. But that's only my opinion 😉 |
Currently have set it to only read bits it should be concerned with, so yeah, invalid and zero values are allowed. Am currently attempting to implement removal of range checks through |
We should be able to represent 32 flags in an int, not 8. Can't you use a 0x2, 0x4, or 0x8 based value? |
Why is this written in hex in the first place? There must be a good reason as |
I am appalled i did not notice a) it was in hex and b) if that was binary there would be values left over. Thanks for the help, but sorry for the appallingly stupid question 😂 |
No worries.... what is there is misleadingly odd. We should double-check that there's nothing funny going with the uses that would somehow require those values. |
This could be great opportunity for optimizing add-in for https://github.com/mono/linker Sorry for edits, I was writing faster than thinking. |
I'm pretty sure The spec even says so:
|
Yes, a good first step would be to recognize and ignore the prefix. I would suggest being permissive in what you accept as any future extensions will likely have the "optional / hint" flavor to them too. So ignoring bits that are unspecified would be ok. After that I would suggest working up a good set of test cases, and think through what should happen on them. Especially things like CSE candidates that differ only in
Perhaps? It is not clear this is something the jit can rely on. And there are potentially other challenges: attribute recognition at jit time is expensive, and we may end up stripping this attribute away in implementation assemblies, at least in some cases. |
I have a working ignoring version, I'll write up some tests that ensure the opcode following the prefix is valid and then can think up the test cases for actually implementing them |
Writing up the "what is expected" for various situations where it is implemented as nop and when it is fully implemented. Mostly resolved, except whether |
That may be a bit too lenient? The spec is pretty clear that consecutive Though I suppose even that might be questioned -- if some current IL provider sets some of the currently unused bits, then we might have unexpected problems if we decide to use those bits for something someday. So perhaps it's best to only accept the currently defined values? |
I think that a single It wouldn't be great if we wanted to start supporting some new prefix in the future (having it be optionally recognized as well) and then that library could no longer run on an older runtime. Especially if that was the only change to the library. |
Switched it to fail on multiple prefixes now. However, facing a bigger issue that is stumping me. It appears some sort of IL modification is happening before the reaching import to do with prefixes. It appears prefixes in invalid places are removed - I have 110% verified these prefixes are in the binary, by means of hexedit and ILDASM, but by the time it reaches |
That seems odd -- I am not aware of anything in the runtime that would strip out prefixes -- editing IL on the fly is tricky. Can you verify the assembly being used at runtime is really the one you expect? |
I am 100% sure it is - my commands are just:
|
Perhaps you need to update this entry in opcode.def? |
I did, it is now It is then in |
Ok ... what does |
The path to the CoreRun, |
Depending on what you are doing there may be more than one copy of corerun in your tree. So which one are you using? is it under bin\Product or bin\Tests ? |
Expected behaviour is observed with the program, an |
WIP - Attempting to remove array bound checks in certain cases when `no. rangecheck` is specified. Part of fix to #17469
I think the suggestion here with removing the null checks based on the C#8 feature was more directed at the idea of adding support to the IL Linker to add the |
but looking at the diff on my draft PR, i am sure none of that code is responsible for the transformation. |
Draft PR up at dotnet/coreclr#23851, has a couple of typos with variable names and there might be an erroneous bracket (fixed on local, will push when I next can), but that's not an issue atm because the code is never reached due to this weird disappearance of the prefix |
@AndyAyersMS I used Product |
I'll take a look when I get a chance, might be a day or two. |
Related to #17469. Adds support for the IL `no.` prefix, which hints to the JIT to ignore certain checks. Currently implemented as a nop (which is ECMA335 compliant), but is validated.
WIP - Attempting to remove array bound checks in certain cases when `no. rangecheck` is specified. Part of fix to #17469
Is this on the roadmap? I've done awful things to trick the JIT into emitting the equivalent of a |
Related to #17469. Adds support for the IL `no.` prefix, which hints to the JIT to ignore certain checks. Currently implemented as a nop (which is ECMA335 compliant), but is validated.
WIP - Attempting to remove array bound checks in certain cases when `no. rangecheck` is specified. Part of fix to #17469
This got lost, but I came back to it today and have a working version that supports and verifies all combinations of (From ECMA)
|
Not sure if |
Awesome, I'll start on that. In the meantime, worth opening a draft PR to show the diff? |
ECMA-335 specifies the
no.
opcode prefix as the following (III.2.2):In short, it allows for automatic type checks, range checks or null checks to be skipped, which would be useful for optimizing hot code paths.
The current implementation throws
InvalidProgramException
whenever it encounters this prefix. This opcode is simply marked as unused right now:https://github.com/dotnet/coreclr/blob/8499136a9a79fd37a4acb9dc690a4815edd8081d/src/inc/opcode.def#L320
Here's a simple method which reproduces the problem:
category:correctness
theme:msil
skill-level:intermediate
cost:medium
The text was updated successfully, but these errors were encountered: