-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Assertion failed '!nodeInfo.IsLclVarWrite() || !unusedLclVarReads.Contains(nodeInfo.LclNum())' #57919
Comments
Tagging subscribers to this area: @JulieLeeMSFT Issue Details// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// This file is auto-generated.
// Seed: -1
//
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public class TestClass20045 {
public struct S2 {
public ulong uint64_1;
}
public struct S3 {
}
public struct S4 {
public ulong uint64_2;
public S2 s2_4;
}
public struct S5 {
}
static bool s_boolean_0 = true;
static S2 s_s2_16 = new S2();
static S3 s_s3_17 = new S3();
public S3 Method1(out S5 p_s5_0, ref S2 p_s2_1) {
unchecked {
S4 s4_4 = new S4();
do {
try {
try {
try {
s4_4.uint64_2 = s4_4.s2_4.uint64_1;
{
}
} catch (TypeAccessException) {
} finally {
}
} catch (RankException) {
} catch (NotImplementedException) {
} finally {
}
} catch (InvalidCastException) {
} finally {
}
}
while (15 > 4 || (s_boolean_0 = 15 <= 4));
return s_s3_17;
}
}
public void Method0() {
unchecked {
S5 s5_3 = new S5();
s_s3_17 = Method1(out s5_3, ref s_s2_16);
return;
}
}
public static void Main(string[] args) {
TestClass20045 objTestClass20045 = new TestClass20045();
objTestClass20045.Method0();
}
}
/*
Got output diff:
--------- Baseline ---------
Environment:
--------- Test ---------
Environment:
Assert failure(PID 12228 [0x00002fc4], Thread: 7360 [0x1cc0]): Assertion failed '!nodeInfo.IsLclVarWrite() || !unusedLclVarReads.Contains(nodeInfo.LclNum())' in 'TestClass20045:Method1(byref,byref):S3:this' during 'Lowering nodeinfo' (IL size 45)
File: D:\git\runtime\src\coreclr\jit\lir.cpp Line: 1369
Image: D:\git\runtime\artifacts\tests\coreclr\windows.x86.Checked\tests\Core_Root\CoreRun.exe
*/
|
Repros on windows/x86 @dotnet/jit-contrib |
Simpler repro case: using System;
using System.Runtime.CompilerServices;
public class TestClass20045 {
public struct S2 {
public ulong uint64_2;
}
public struct S4 {
public ulong uint64_1;
public S2 s2;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static ulong Method1(bool b) {
S4 s = new S4();
do {
s.uint64_1 = s.s2.uint64_2;
} while (b);
return s.s2.uint64_2;
}
public static void Main(string[] args) {
ulong u = Method1(false);
Console.WriteLine(u);
}
} |
This also fails in 5.0. Moving out to 7.0. |
Do we do something reasonable in release jits? |
Yes, at least for this case. LIR is trying to assert that if you have a local var store, there aren't any outstanding reads of that var that are "contained" and thus won't generate code until the "user" of the read. E.g.,
Specifically, the comment says:
In this case, it's not an issue because we don't have a LCL_VAR; we have non-overlapping LCL_FLD. But The long decomposition looks like:
In this case, the first STORE_LCL_FLD writing V01 doesn't trash the non-overlapping t43, reading V01 at a different offset/size, used by the second STORE_LCL_FLD. It seems like the LIR checking should consider all non-overlapping LCL_FLD reads/writes as independent, like each was a LCL_VAR. But that would be a huge change. We could simply (temporarily?) ignore this assert for LCL_FLD. We could possibly change decomposition to try to avoid creating this form; maybe by creating copies through temps, which would presumably create worse CQ. |
Another repro, in debug mode/with tiering enabled: // Generated by Fuzzlyn v1.5 on 2021-10-19 13:43:00
// Run on .NET 6.0.0-rc.2.21480.5 on X64 Windows
// Seed: 248268849421871353
// Reduced from 18.2 KiB to 0.2 KiB in 00:03:35
// Exits with error:
//
// Assert failure(PID 8056 [0x00001f78], Thread: 30444 [0x76ec]): Assertion failed '!nodeInfo.IsLclVarWrite() || !unusedLclVarReads.Contains(nodeInfo.LclNum())' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Lowering nodeinfo' (IL size 30)
//
// File: C:\dev\dotnet\runtime2\src\coreclr\jit\lir.cpp Line: 1367
// Image: C:\dev\dotnet\runtime2\artifacts\tests\coreclr\windows.x86.Checked\Tests\Core_Root\corerun.exe
//
//
public struct S0
{
public long F2;
}
public struct S1
{
public S0 F0;
}
public class Program
{
public static void Main()
{
var vr3 = new S1();
var vr6 = vr3.F0;
vr6.F2 = vr6.F2;
}
} |
For LIR we verify that we can really consider locals to be used at their user by having a checker that looks for interfering stores to the same locals. However, in some cases we may have "interfering" GT_LCL_FLD/GT_STORE_LCL_FLD, in the sense that they work on the same local but on a disjoint range of bytes. Add support to validate this. This fixes dotnet#57919 which made the fuzzer jobs very noisy and made it easy to miss actual new examples (e.g. dotnet#63720 was just merged even though there were real examples found there). Fix dotnet#57919
For LIR we verify that we can really consider locals to be used at their user by having a checker that looks for interfering stores to the same locals. However, in some cases we may have "interfering" GT_LCL_FLD/GT_STORE_LCL_FLD, in the sense that they work on the same local but on a disjoint range of bytes. Add support to validate this. This fixes #57919 which made the fuzzer jobs very noisy and made it easy to miss actual new examples (e.g. #63720 was just merged even though there were real examples found there). Fix #57919
The text was updated successfully, but these errors were encountered: