-
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
JIT emits unnecessary movsxd instructions when calling into Span indexer #12218
Comments
The same The zero-extension could be omitted, if the JIT recognizes this pattern, and operate with the native int size (i.e. G_M56184_IG03:
03048A add eax, dword ptr [rdx+4*rdi]
FFC7 inc rdi
3BFE cmp rdi, rsi
7CF4 jl SHORT G_M56184_IG03 |
Range prop may be able to determine Worth taking a quick look. |
@AndyAyersMS I tried that in the past but for some reason I gave up. I'll check what I did back then. |
@AndyAyersMS I didn't investigate anything quite as complex as flowing context that i must be non-negative or backing i with a native int to begin with. In the quick changes I experimented with, there was still a zero-extension (the |
Yes. I tried that in the past with array indices. It was working but in some cases involving pointer arithmetic there was a regression due to CSE no longer picking up the casts, those from array indices where zero extending and those from pointer arithmetic were sign extending. |
@AndyAyersMS FWIW I have this in mikedn/coreclr@e0a6e91 It does seem to work (diff corelib -> -368 bytes) but I don't remember if the change was "done" or if there was some kind of problem that made me abandon it. It could be that it was just my general dislike of RangeCheck, I generally don't trust that code. I'll try to figure out what's up with it. |
Ran a diff on the entire FX (after patching a strange issue with missing assertions):
Not a lot, as this saves at most one byte per cast (sometimes PIN data doesn't look too good, a 0.5% regression. Didn't check memory usage but I don't think it will be good either. I was afraid of that, |
We're in the 3.0 endgame for the jit, and there doesn't seem to be any cheap / safe way to fix this, so marking as future. |
Related to dotnet/coreclr#21553. |
@BruceForstall @AndyAyersMS Is this perhaps a dupe of #7312? |
Yes, it's a case where IV widening would help. |
@AndyAyersMS I'm still not sure if this is a true dupe of 7312 or a secondary issue. If it's a true dupe then please feel free to close this issue. :) |
This was fixed with #81055
|
When passing a non-constant value into the
Span<T>
andReadOnlySpan<T>
indexer, the JIT will emit an unnecessarymovsxd
instruction on x64. The repro is fairly simple:Current codegen:
I prototyped the below change in my local branch by modifying the logic in
importer.cpp
to use zero-extension instead of signed-extension for the span indexer and ran a benchmark. The modified code took approximately one-third less time to run. This optimization may be worth investigating if we believe that developers are iterating over spans in hot loops. (Admittedly, any more complex logic within the loop would almost certainly overwhelm these benchmark results.)/cc @dotnet/jit-contrib
category:cq
theme:basic-cq
skill-level:expert
cost:medium
impact:medium
The text was updated successfully, but these errors were encountered: