-
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
JIT: CMOV aka CMOVcc not generated when method is inlined. #96593
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsDescriptionWhen playing with the now infamous "One Billion Row Challenge", I noticed that while the JIT properly emits To confirm that what I observed in SharpLab corresponded to what would be a Tier1 codegen, I manually observed a Release build in Visual Studio. I could see the assembly for the method changing between two occurences of a manual breakpoint (using As far as I can tell, the code generation difference is not directly related to JIT inlining, as I would see the conditional jump opcodes before splitting this specific code in a separate method. Relevant C# Code for the method:
Code of the method before inlining:
Relevant code of the method when inlined:
I initially thought that the problem with I tried to trick the JIT in generating Code can also be found here: https://github.com/hexawyz/OneBillionRows/blob/adf45647de4d4d9d49c6002e29bd483cee608af3/OneBillionRows/Program.cs#L328 I apologize for not providing a more minimal repro, but hopefully, this one is still small enough so that you can understand what is happening here. ConfigurationLocal: .NET 8.0.100
|
It's probably this #96380 |
Thanks for the report. Indeed, this is a duplicate of #96380. We do not emit conditional instructions inside loops today because it can cause significant performance regressions, and the right analysis to predict the profitability has not yet been implemented. |
Description
When playing with the now infamous "One Billion Row Challenge", I noticed that while the JIT properly emits
CMOVG
andCMOVL
for Min/Max operations, those sometimes get replaced by more classical branches when in the context of a more complex method.I've put the relevant code here to look at the disassembly: Code on SharpLab
To confirm that what I observed in SharpLab corresponded to what would be a Tier1 codegen, I manually observed a Release build in Visual Studio. I could see the assembly for the method changing between two occurences of a manual breakpoint (using
Debugger.Break()
)As far as I can tell, the code generation difference is not directly related to JIT inlining, as I would see the conditional jump opcodes before splitting this specific code in a separate method.
Relevant C# Code for the method:
Code of the method before inlining:
Relevant code of the method when inlined:
I initially thought that the problem with
CMOVcc
was that it can not have a memory destination, but as can be seen in the non inlined method, the JIT chooses to use it despite that fact, which matches with my intuition that it is the correct thing to do here.The jumps that I see re-introduced in the inlined version (possibly because the JIT failed to detect the pattern there ?) are at least increasing the size of the assembly, but I'd assume they would possibly degrade the performance of the code, depending on the exact data processed.
I tried to trick the JIT in generating
CMOV
-based code in multiple different ways there (introducing intermediate variables, etc), but I could not get it to not do it.IIRC, the worst of the cases I managed to produce was one where the conditional jumps would directly point to
JMP
opcodes without doing anything else uselful.Code can also be found here: https://github.com/hexawyz/OneBillionRows/blob/adf45647de4d4d9d49c6002e29bd483cee608af3/OneBillionRows/Program.cs#L328
I apologize for not providing a more minimal repro, but hopefully, this one is still small enough so that you can understand what is happening here.
Configuration
Local: .NET 8.0.100, x64
SharpLab: Core CLR 8.0.23.53103 on x64
The text was updated successfully, but these errors were encountered: