-
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
Assertion failed '!node->OperIs(GT_CALL) || (node->AsCall()->gtCallType == CT_HELPER)' during 'Optimize index checks' #91862
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue Detailsusing System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Numerics;
public class TestClass
{
public struct S1
{
public struct S1_D1_F3
{
}
}
public struct S2
{
}
static byte s_byte_5 = 127;
static Vector128<ushort> s_v128_ushort_21 = Vector128.Create((ushort)2, 2, 5, 32767, 2, 5, 54, 5);
static Vector128<int> s_v128_int_22 = Vector128<int>.Zero;
static S1.S1_D1_F3 s_s1_s1_d1_f3_51 = new S1.S1_D1_F3();
static S1 s_s1_52 = new S1();
static S2 s_s2_53 = new S2();
S1.S1_D1_F3 s1_s1_d1_f3_101 = new S1.S1_D1_F3();
S1 s1_102 = new S1();
S2 s2_103 = new S2();
public S1 Method54(out S1 p_s1_1625, out S1.S1_D1_F3 p_s1_s1_d1_f3_1626, ref S1.S1_D1_F3 p_s1_s1_d1_f3_1627, S1 p_s1_1628, S1 p_s1_1629, ref S1 p_s1_1630, ref S1.S1_D1_F3 p_s1_s1_d1_f3_1631, out S2 p_s2_1632, out S2 p_s2_1633)
{
unchecked
{
byte byte_1635 = 2;
int int_1640 = 2;
ushort ushort_1645 = 54;
if (15<=4)
{
}
else
{
ushort_1645 += Vector128.GetElement(Sse2.ShiftRightLogical128BitLane(s_v128_ushort_21 = s_v128_ushort_21, s_byte_5 = s_byte_5), Sse41.Extract(s_v128_int_22, byte_1635) + (int_1640 *= 15-4)& 5);
}
return s_s1_52;
}
}
public void Method0()
{
unchecked
{
S1.S1_D1_F3 s1_s1_d1_f3_2935 = new S1.S1_D1_F3();
S1 s1_2936 = new S1();
s1_2936 = Method54(out s_s1_52, out s1_s1_d1_f3_2935, ref s1_s1_d1_f3_101, s_s1_52, s_s1_52, ref s1_102, ref s_s1_s1_d1_f3_51, out s_s2_53, out s2_103);
return;
}
}
public static void Main(string[] args)
{
new TestClass().Method0();
}
}
/*
Environment:
set DOTNET_TieredCompilation=0
Assert failure(PID 27016 [0x00006988], Thread: 45140 [0xb054]): Assertion failed '!node->OperIs(GT_CALL) || (node->AsCall()->gtCallType == CT_HELPER)' in 'TestClass:Method54(byref,byref,byref,TestClass+S1,TestClass+S1,byref,byref,byref,byref):TestClass+S1:this' during 'Optimize index checks' (IL size 69; hash 0x879627a5; FullOpts)
File: D:\git\runtime\src\coreclr\jit\gentree.cpp Line: 16783
Image: D:\git\runtime\artifacts\tests\coreclr\windows.x64.Checked\tests\Core_Root\CoreRun.exe
*/
|
We tend to extract the side-effect for
Since runtime/src/coreclr/jit/gentree.cpp Lines 16780 to 16783 in f18d6b6
|
It does have It looks like in this case we are looking at I'm not sure why we wouldn't see the same issue with regular array indexing, like for example |
Looks like |
@jakobbotsch Can you take this one? |
optRemoveRangeCheck extracts only GTF_ASG from the bounds check. If the BOUNDS_CHECK is complex, that results in silently dropping side effects on the floor (see the example case). The ideal fix is that we should always extract all side effects from the index and length operands, however this has large regressions because the length typically has an ARR_LENGTH that we then extract. This PR instead has a surgical fix for the problem case that can be backported to .NET 8. It extracts all side effects from the index, but keeps extracting only GTF_ASG from the length to get around the issue mentioned above. Fix dotnet#91862
…2116) optRemoveRangeCheck extracts only GTF_ASG from the bounds check. If the BOUNDS_CHECK is complex, that results in silently dropping side effects on the floor (see the example case). The ideal fix is that we should always extract all side effects from the index and length operands, however this has large regressions because the length typically has an ARR_LENGTH that we then extract. This PR instead has a surgical fix for the problem case that can be backported to .NET 8. It extracts all side effects from the index, but keeps extracting only GTF_ASG from the length to get around the issue mentioned above. Fix #91862
optRemoveRangeCheck extracts only GTF_ASG from the bounds check. If the BOUNDS_CHECK is complex, that results in silently dropping side effects on the floor (see the example case). The ideal fix is that we should always extract all side effects from the index and length operands, however this has large regressions because the length typically has an ARR_LENGTH that we then extract. This PR instead has a surgical fix for the problem case that can be backported to .NET 8. It extracts all side effects from the index, but keeps extracting only GTF_ASG from the length to get around the issue mentioned above. Fix #91862
…2210) optRemoveRangeCheck extracts only GTF_ASG from the bounds check. If the BOUNDS_CHECK is complex, that results in silently dropping side effects on the floor (see the example case). The ideal fix is that we should always extract all side effects from the index and length operands, however this has large regressions because the length typically has an ARR_LENGTH that we then extract. This PR instead has a surgical fix for the problem case that can be backported to .NET 8. It extracts all side effects from the index, but keeps extracting only GTF_ASG from the length to get around the issue mentioned above. Fix #91862 Co-authored-by: Jakob Botsch Nielsen <jakob.botsch.nielsen@gmail.com>
The text was updated successfully, but these errors were encountered: