dotnet/roslyn

Suboptimal codegen for `is` pattern compared to .NET 6/7

Open

#80052 opened on Aug 26, 2025

View on GitHub
 (3 comments) (1 reaction) (1 assignee)C# (20,414 stars) (4,257 forks)batch import
Area-CompilersCode Gen QualityOngoing-Quality-Candidatehelp wanted

Description

A simple method with a pattern match is generates less efficient code starting from .NET 8 compared to .NET 6/7.

Repro: godbolt

public static bool HasLeadingSlash(ReadOnlySpan<char> path)
{
    if (path.Length > 0 && path[0] is '/' or '\\')
        return true;

    return false;
}

.NET 8,9,10 (IL size: 49 bytes):

public static bool HasLeadingSlash(ReadOnlySpan<char> path)
{
    bool flag = path.Length > 0;
    if (flag)
    {
        char c = path[0];
        bool flag2 = ((c == '/' || c == '\\') ? true : false);
        flag = flag2;
    }

    if (flag)
    {
        return true;
    }

    return false;
}

.NET 6,7 (IL size: 34 bytes):

public static bool HasLeadingSlash(ReadOnlySpan<char> path)
{
    if (path.Length > 0)
    {
        char c = path[0];
        if (c == '/' || c == '\\')
        {
            return true;
        }
    }
    return false;
}

Roslyn now introduces unnecessary temporary bool variables and extra conditional branches. The JIT is unable to untangle this pattern, resulting in larger, slower code.

Contributor guide