Skip to content

Commit 0c86592

Browse files
[release/10.0] Fix assertions generated by optCreateJumpTableImpliedAssertions (#127003)
Backport of #123240 to release/10.0 /cc @EgorBo ## Customer Impact - [x] Customer reported - [ ] Found internally The JIT compiler could make invalid assumptions regarding the `default:` case in `switch` statements concerning the possible ranges of the checked variable. This could lead to incorrect constant folding and branch removal. The original bug reproduction is available here: #122254 ## Regression - [x] Yes - [ ] No Regressed via #113998 JIT optimization. ## Testing A test is added. ## Risk Low ## Package authoring no longer needed in .NET 9 **IMPORTANT**: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version. Keep in mind that we still need package authoring in .NET 8 and older versions. Co-authored-by: EgorBo <egorbo@gmail.com>
1 parent 9db47f0 commit 0c86592

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

src/coreclr/jit/assertionprop.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5714,7 +5714,8 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb)
57145714
// default: %name.Length is >= 8 here%
57155715
// }
57165716
//
5717-
if ((value > 0) && !vnStore->IsVNConstant(opVN))
5717+
// NOTE: if offset != 0, we only know that "X + offset >= maxJumpIdx", which is not very useful.
5718+
if ((offset == 0) && (value > 0) && !vnStore->IsVNConstant(opVN))
57185719
{
57195720
AssertionDsc dsc = {};
57205721
dsc.assertionKind = OAK_NOT_EQUAL;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 Xunit;
7+
8+
public class Runtime_122254
9+
{
10+
[Fact]
11+
public static void TestEntryPoint()
12+
{
13+
try
14+
{
15+
Test(new int[0]);
16+
}
17+
catch (InvalidOperationException)
18+
{
19+
return;
20+
}
21+
throw new InvalidOperationException();
22+
}
23+
24+
[MethodImpl(MethodImplOptions.NoInlining)]
25+
private static void Test(int[] arr)
26+
{
27+
int block = arr.Length;
28+
switch (block)
29+
{
30+
case 2:
31+
Console.WriteLine("2");
32+
break;
33+
case 3:
34+
Console.WriteLine("3");
35+
break;
36+
case 4:
37+
Console.WriteLine("4");
38+
break;
39+
default:
40+
if (block == 0)
41+
{
42+
throw new InvalidOperationException();
43+
}
44+
break;
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)