-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
RyuJIT's loop cloning optimization has questionable CQ and a bug #4922
Comments
I took a quick look at the code and my initial impression is that this happens because the optimizer works on do-while loops and as such it doesn't "see" the But then the CQ is a minor issue, the real problem is [MethodImpl(MethodImplOptions.NoInlining)]
static void Copy(int[] src, int[] dst, int length)
{
int i = 50000;
do
{
dst[i] = src[i];
i++;
}
while (i < length);
}
static void Main()
{
Copy(new int[2], new int[2], 1);
} which promptly throws an AccessViolationException
|
I cannot repro that in .NET 4.6.1, I get an
It does not look like RyuJIT in .NET 4.6.1 does loop cloning for this case? Seems weird since history of the Git repo seems to indicate that loop cloning received no changes after .NET 4.6.1... EDIT: The |
Yes, for some reason .NET 4.6.1 doesn't do loop cloning for such do-while loops. It doesn't do it even if you change the do-while version to be equivalent to the for version: int i = 0;
if (i < length)
{
do
{
dst[i] = src[i];
i++;
}
while (i < length);
} The C# compiler generates slightly different IL for such a loop and .NET 4.6.1, unlike CoreCLR, doesn't like it. It's possible that a fix was already made in .NET 4.6.1 but it is yet to make it to this repository. |
@mikedn but it is a bug that the code throws an AV, right? Is this CoreCLR or .NET 4.6.1 also? |
@CppStars Yes, it's a bug and as far as I can tell it's present only in CoreCLR. The AV is just for the "show", I intentionally picked a large initial index to trigger an observable AV. For smaller values you'll end up with silent memory corruption. As far as I can tell this bug is triggered only by a do-while loop with a constant initial index. Those are rare circumstances I'd say. |
@mikedn dotnet/coreclr#2627 should have resolved the correctness issue. dotnet/coreclr#2634 opened to track the CQ issue. |
The following method
generates
@JanielS speculated in #4921 that the null checks may be there so the NullReferenceException will appears as if it was thrown from inside the loop instead of being thrown form hoisted code. But if you pass a null array to this method the debugger will point to the
i < length
loop condition when the exception is thrown, not todst[i] = src[i]
.The text was updated successfully, but these errors were encountered: