Skip to content

JIT: Switch should create assertions #113992

@EgorBo

Description

@EgorBo
static void Test(int x)
{
    switch (x)
    {
        case 1:
            Console.WriteLine(x == 1);
            break;
        case 2:
            Console.WriteLine(x == 2);
            break;
        case 3:
            Console.WriteLine(x == 3);
            break;
    }
}

Currently, JIT can't fold these x == y checks, but should be able to. This is a minimal repro for a popular case when Span/Array Length is used for switch and then all legs use that span.

For example, any attempt to remove unsafe code from the following function will hit regressions because of it:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ulong GetKey(ReadOnlySpan<byte> name)
{
ref byte reference = ref MemoryMarshal.GetReference(name);
int length = name.Length;
ulong key = (ulong)(byte)length << 56;
switch (length)
{
case 0: goto ComputedKey;
case 1: goto OddLength;
case 2: key |= Unsafe.ReadUnaligned<ushort>(ref reference); goto ComputedKey;
case 3: key |= Unsafe.ReadUnaligned<ushort>(ref reference); goto OddLength;
case 4: key |= Unsafe.ReadUnaligned<uint>(ref reference); goto ComputedKey;
case 5: key |= Unsafe.ReadUnaligned<uint>(ref reference); goto OddLength;
case 6: key |= Unsafe.ReadUnaligned<uint>(ref reference) | (ulong)Unsafe.ReadUnaligned<ushort>(ref Unsafe.Add(ref reference, 4)) << 32; goto ComputedKey;
case 7: key |= Unsafe.ReadUnaligned<uint>(ref reference) | (ulong)Unsafe.ReadUnaligned<ushort>(ref Unsafe.Add(ref reference, 4)) << 32; goto OddLength;
default: key |= Unsafe.ReadUnaligned<ulong>(ref reference) & 0x00ffffffffffffffL; goto ComputedKey;

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIin-prThere is an active PR which will close this issue when it is mergedreduce-unsafe

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions