Skip to content
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

On x64 platform, "stelem.ref" ignores high bits of "native int" index #52817

Closed
kevinjwz opened this issue May 15, 2021 · 11 comments · Fixed by #71571
Closed

On x64 platform, "stelem.ref" ignores high bits of "native int" index #52817

kevinjwz opened this issue May 15, 2021 · 11 comments · Fixed by #71571

Comments

@kevinjwz
Copy link

kevinjwz commented May 15, 2021

IndexOutOfRangeException not thrown when index=0x100000000.
sharplab test

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label May 15, 2021
@teo-tsirpanis
Copy link
Contributor

Judging from the disassembly, the stelem.ref instruction calls System.Runtime.CompilerServices.CastHelpers.StelemRef helper method, which takes the index as a 32-bit integer. The index's high part is thrown away becoming zero, and the runtime happily stores your object to the array's zeroth position.

@GrabYourPitchforks
Copy link
Member

GrabYourPitchforks commented May 15, 2021

Regression from 3.1, introduced in 5.0.

@GrabYourPitchforks
Copy link
Member

Repathed to VM area, because that really seems like the closest thing to the true area owners.
/cc @VSadov

@SingleAccretion
Copy link
Contributor

Judging from the disassembly, the stelem.ref instruction calls System.Runtime.CompilerServices.CastHelpers.StelemRef helper method, which takes the index as a 32-bit integer. The index's high part is thrown away becoming zero, and the runtime happily stores your object to the array's zeroth position.

That's correct. It looks like we just import a call to the helper, and it is the helper's responsibility to check out of range conditions, which it does. I am wondering what would be needed here beyond changing the helper's signature to take nint instead of int.

@GrabYourPitchforks
Copy link
Member

I am wondering what would be needed here beyond changing the helper's signature to take nint instead of int.

That's why I pathed it under VM. Not sure if we require JIT changes to ensure 32-bit int indices (the 99.9999% case) are properly native word size extended before invoking the helper method. The VM area owners would know for sure.

@teo-tsirpanis
Copy link
Contributor

I also noticed that the native-sized index is first conv.i8ed. Is that done on purpose? The documentation of stelem.ref says that the index is of type native int. Why first convert it to an int64?

@SingleAccretion
Copy link
Contributor

Not sure if we require JIT changes to ensure 32-bit int indices (the 99.9999% case) are properly native word size extended before invoking the helper method.

I suspect changes will be needed, heh (looks like we don't sign extend right now), or an alternative version of the helper. Another note: seems like ldelema has the same problem.

@mangod9 mangod9 removed the untriaged New issue has not been triaged by the area owner label May 15, 2021
@VSadov
Copy link
Member

VSadov commented May 16, 2021

When I am running the Stelem_Ref repro with 3.1, I get the same results as on 5.0. I do not think this is a regression.

The previous implementation of the helper in x64 assembly truncated the index to 32bit as well - https://github.com/dotnet/runtime/pull/32722/files#r633023865

@am11
Copy link
Member

am11 commented May 17, 2021

It does not throw from Stelem_I4 either on 3.1 (linux-x64).

@mangod9 mangod9 modified the milestones: 6.0.0, 7.0.0 Jul 9, 2021
@davidwrighton
Copy link
Member

I've looked into this. We can't just extend the helper to take a nint, we'll need to have a parallel helper, or force the index to be sign extended to nint. The abi of several of our platforms doesn't reliably set the high bits to 0 when passing 32bit values.

davidwrighton added a commit to davidwrighton/runtime that referenced this issue Jul 2, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 2, 2022
davidwrighton added a commit that referenced this issue Jul 6, 2022
…of a native int index (#71571)

Add support for native int indices in stelem.ref and ldelema helper functions. This required changing the abi of these functions, which required bumping the major R2R version number. As we have already done that for .NET 7, this is a minor cost. Note that this is still broken on Mono, and that bug is #71656 

Fixes #52817
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 6, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Aug 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
8 participants