-
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
Irrelevant type checks in inlined generics for value types influencing optimizations #37904
Comments
The codegen backs to normal (see diff) if I change return left.CompareTo(right) < 0; to return left.CompareTo(right) < 0 ? true : false; 😄 |
Because
Compare versus
The general fix for this is forward substitution (#4655). As an alternative, note that when importing, only one of the returns is reachable. The inliner is deciding to create a return spill temp eagerly, based on the number of returns seen in the IL, and it could instead wait and see how many returns actually get reached as the IL is imported, but this might not be easy to implement. @stephentoub how impactful is this? I can look into the more specialized fix suggested above if this is blocking something important. |
Thanks for asking. It looks like I can use @EgorBo's proposed workaround and that will address my immediate needs. |
I don't see us getting to forward sub in 6.0, so moving to future. |
Catch patterns like the one in dotnet#37904 where a trinary compare feeds a binary compare.
Catch patterns like the one in #37904 where a trinary compare feeds a binary compare.
The codegen of (inlined) |
@huoyaoyuan I think the code gen is still different with the From sharplab.io
The 'without' version does look cleaner, however, in a quick test here I observed the 'with' version executing faster than the 'without' version (test PC is an AMD Ryzen 7 PRO 5750G). |
Consider this sharplab.io repro:
https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABAJgEYBYAKGIAYACY8gOgCUBXAOwwEt8YLAMIR8AB14AbGFADKMgG68wMXAG4a9BrIAW2KGIAy2YO258BG6jQDaAKV4YA4jC4zlACgwBPMTAgAZh68PACUoQC6mgDMDLgw2NIAJkykDEIAPAAqAHwMAO46MjAMWQwgDACSIuL6JtLZOTQA3jQM7UyxzEgMIRjpomL6MOQeskNcjQwA1jDeuGilDBihDAC8eYaquFl6XKOz8zZ0EYsrDAD8DOTlDHRWbR3EXeQ9fQO1sKRjE1OHC0tzhsGFtcDs9t9/sdTstVlcbhV7jRHu0bABZGAYHQQJKVcSSDwYrE4vFiSQAeTEfAgXFwLAAggBzRmwMG8BQwSpcSQhEKMyIozpMV4MYAQCCSEHbXbYfYeMrSAIYRZlKC8Rk6FaC1rUDp63oBBheXz+IJZVZrNbLE2BDzMOjhQX6p4AdgYAUS8QeuudTDdiowwkGwyyEA8ao15wydyseoAvsifaiidjcfjCZjU6SKVTeDS6UyWdt2ZzubyuPyokmhd1ReLJaDwbLvgqYEqVQwI5rQtqna6GAGg58YKHw+ruwxo0jqwnqHGgA==
The codegen for Compare1 and Compare2 are identical, as is expected, since T is a value type (Int32) and we should be specializing such that the whole string type check is eliminated:
However, when these methods are inlined, the callers exhibit non-trivial differences:
It looks like when the type check is absent, the JIT figures out that the whole
int.CompareTo(int) < 0
can be simplified into just:but when the irrelevant type check is present, it fails to optimize this, and we end up with the complete implementation from
Int32.CompareTo
:I see similar behavior from the master branch. Repro:
and output from JitDisasm:
cc: @AndyAyersMS
category:cq
theme:inlining
skill-level:expert
cost:large
The text was updated successfully, but these errors were encountered: