-
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
Should System.Int64.GetHashCode()
avoid dereferencing m_value
twice?
#105142
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
Hmm, this really comes down to the implementation of runtime/src/libraries/System.Private.CoreLib/src/System/Int64.cs Lines 106 to 109 in f8bcd05
I wonder if we should introduce a 64-bit implementation that only has a single load. |
System.Int64.GetHashCode()
avoid dereferencing m_value
twice?
Tagging subscribers to this area: @dotnet/area-system-runtime |
@jakobbotsch Other methods like CompareTo, etc and in all other primitives we do that. Why don't these load get the same VN? |
Meaning just changing the impl to be: public override int GetHashCode()
{
long value = m_value;
return unchecked((int)value ^ (int)(value >> 32);
} ? We certainly can, but it'd be nice if it weren't necessary. The value isn't volatile; why can't the JIT eliminate the duplicate load? |
I guess the minimal repro is: int Test(long* ptr)
{
return (*ptr).GetHashCode();
} mov eax, dword ptr [rdx]
mov rcx, qword ptr [rdx]
sar rcx, 32
xor eax, ecx |
Yeah, something like that.
Most likely because we optimize one of the indirection to a 32-bit indirection, and then we aren't Even if we did collapse them that optimization would likely only happen in Tier-1, while this seems like a reliability thing we would want to guarantee? |
Do you mean the current C# code is potentially not thread-safe? |
I don't think we make any guarantees about such operations in the face of concurrent reads/writes / tearing (which presumably is what you're alluding to). |
Yeah, that's what I was thinking. I agree it's be nice if the JIT optimized this in some way, but I came at this from the perspective of "it's illegal to duplicate loads in the memory model", and this looked to me like illegal behavior from the JIT initially. In reality what looks like a dereference in the C# source code is not actually one. |
Legality of the existing C# impl aside, I am curious what would be a proper optimization in JIT, we have a tree like this:
So far so good, both IND should be CSE'd just fine (without violating our MM), but then |
I agree with this. At the same time it would be pretty trivial to update the managed code and make this "better" (at least for 64-bit) for the core
Like I mentioned on Discord, I think this one feels like the Alternatively, it feels like we might be missing a simpler opt that looks for common aliases from the same address. That is, we're allowed to fold neighboring loads and the like and we already peephole optimize to |
@tannergooding I'm assigning this to you, but I wasn't sure if this is something we'd still consider for .NET 9 or if we should punt it out. If it is something we should do in .NET 9, please coordinate who can take it on and make sure the assignment matches that. Thanks. |
This isn't a correctness thing and is relatively low priority, moving to 10 |
runtime/src/tests/JIT/Regression/JitBlue/GitHub_19149/GitHub_19149.cs
Lines 44 to 56 in f8bcd05
In this test we seem to end up duplicating the loads of
x
:The text was updated successfully, but these errors were encountered: