-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
I maintain a tool that generates performance-critical code, so I spend some time looking at JIT dumps to make sure the code that I'm generating is JIT-friendly (bounds-check eliding, etc).
I am by no means an authority in assembly, but I've come across something that mystifies me and makes me think there may be a bug with some redundant instructions.
My configuration is:
- .NET 5.0 x64 on Win10 x64, fully updated
- AMD Ryzen 5950x (Zen 3, AVX2 supported)
I'm unable to get a succinct reproduction of the issue (it may only happen when the method uses more variables than there are registers), so I'll share high-level details and add a link to a gist later. The code is basically trying to write an aligned integer at a 4-byte boundary:
checked
{
int offset;
...
// align to 4 byte boundary
offset += (-offset) & (sizeof(int) - 1);
int location = offset;
offset += sizeof(int);
// write the value at location.
...
}G_M47529_IG13:
8BC3 mov eax, ebx
F7D8 neg eax
83E003 and eax, 3
03C3 add eax, ebx
0F80A3000000 jo G_M47529_IG25
8BD8 mov ebx, eax
// These two mov's appear entirely redundant.
8BC3 mov eax, ebx
8BD8 mov ebx, eax
83C304 add ebx, 4
0F8094000000 jo G_M47529_IG25
8B5708 mov edx, dword ptr [rdi+8]
3BC2 cmp eax, edx
0F878E000000 ja G_M47529_IG26Unless I'm very mistaken (always possible 🙂), My question is that after the first mov, we know for sure that the eax and ebx registers carry the same value, which should mean that the next two instructions could be eliminated with no adverse side effects, right?
The full repro is available here. I've tried to remove all of the code that isn't essential to view the issue: https://gist.github.com/jamescourtney/5000bec600493d7dc08633a07ba2dd06