Skip to content

Commit d054157

Browse files
authored
JIT: Extract all side effects of the index in optRemoveRangeCheck (#92116)
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
1 parent bc97b0a commit d054157

File tree

5 files changed

+64
-4
lines changed

5 files changed

+64
-4
lines changed

src/coreclr/jit/optimizer.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8888,9 +8888,15 @@ GenTree* Compiler::optRemoveRangeCheck(GenTreeBoundsChk* check, GenTree* comma,
88888888
}
88898889
#endif
88908890

8891-
// Extract side effects
8891+
// TODO-Bug: We really should be extracting all side effects from the
8892+
// length and index here, but the length typically involves a GT_ARR_LENGTH
8893+
// that we would preserve. Usually, as part of proving that the range check
8894+
// passes, we have also proven that the ARR_LENGTH is non-faulting. We need
8895+
// a good way to communicate to this function that it is ok to ignore side
8896+
// effects of the ARR_LENGTH.
88928897
GenTree* sideEffList = nullptr;
8893-
gtExtractSideEffList(check, &sideEffList, GTF_ASG);
8898+
gtExtractSideEffList(check->GetArrayLength(), &sideEffList, GTF_ASG);
8899+
gtExtractSideEffList(check->GetIndex(), &sideEffList);
88948900

88958901
if (sideEffList != nullptr)
88968902
{

src/tests/JIT/Regression/JitBlue/Runtime_91576/Runtime_91576.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Licensed to the .NET Foundation under one or more agreements.
2-
// The .NET Foundation licenses this file to you under the MIT license.aa
2+
// The .NET Foundation licenses this file to you under the MIT license.
33

44
// Generated by Fuzzlyn v1.6 on 2023-09-03 15:59:01
55
// Run on X64 Windows

src/tests/JIT/Regression/JitBlue/Runtime_91855/Runtime_91855.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Licensed to the .NET Foundation under one or more agreements.
2-
// The .NET Foundation licenses this file to you under the MIT license.aa
2+
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
55
using System.Runtime.CompilerServices;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.Intrinsics;
7+
using Xunit;
8+
9+
public class Runtime_91862
10+
{
11+
[Fact]
12+
public static int TestEntryPoint()
13+
{
14+
return Foo(default);
15+
}
16+
17+
[MethodImpl(MethodImplOptions.NoInlining)]
18+
private static int Foo(Vector128<float> v)
19+
{
20+
int result = 101;
21+
// This tree results in a BOUNDS_CHECK for Bar(...) & 3
22+
float x = Vector128.GetElement(v, Bar(ref result) & 3);
23+
24+
if (result != 100)
25+
{
26+
Console.WriteLine("FAIL");
27+
}
28+
29+
// After inlining x is DCE'd, which will extract side effects of its assignment above.
30+
// That results IR amenable to forward sub, and we end up with a BOUNDS_CHECK
31+
// with a complex index expression that we can still prove is within bounds.
32+
Baz(x);
33+
return result;
34+
}
35+
36+
[MethodImpl(MethodImplOptions.NoInlining)]
37+
private static int Bar(ref int result)
38+
{
39+
result = 100;
40+
return 0;
41+
}
42+
43+
private static void Baz(float x)
44+
{
45+
}
46+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<Compile Include="$(MSBuildProjectName).cs" />
7+
</ItemGroup>
8+
</Project>

0 commit comments

Comments
 (0)