Skip to content

Inefficient recursive pattern matching (?) native code generated #37986

Open
@myblindy

Description

@myblindy

Version Used:

VS 16.6

Steps to Reproduce:

I'm using the following code:

using System;
public class C 
{
    public void M() 
    {
        object o = new System.Data.DataTable().Rows[0][0];
        //if (o is object obj) Console.WriteLine($"obj {o}");
        //if (o is string s) Console.WriteLine($"str {s}");
        //if (o is DateTime dt) Console.WriteLine($"dt {dt}");
        if (o is string { Length: 3 } ss) 
            if (ss is { Length: 3 } s40) 
                Console.WriteLine($"arf {s40}");
    }
}

And the issue is that while the code generated is correct, it is indeed checking for null and for the Length property twice, even in release mode, in both ILASM and native assembly (so the JIT is also failing to optimize this):

    L0060: mov edx, eax
    L0062: test edx, edx
    L0064: je short L0070
    L0066: cmp dword ptr [edx], 0x34aacd0
    L006c: je short L0070
    L006e: xor edx, edx
    L0070: test edx, edx
    L0072: je short L0093
    L0074: mov ecx, [edx+4]
    L0077: cmp ecx, 3
    L007a: jne short L0093
    L007c: cmp ecx, 3
    L007f: jne short L0093
    L0081: mov ecx, [0xb7d2270]
    L0087: call System.String.Concat(System.String, System.String)
    L008c: mov ecx, eax
    L008e: call System.Console.WriteLine(System.String)
    L0093: lea esp, [ebp-4]

Expected Behavior:

I would expect the 2nd check to be eliminated, since it's checking exactly the same conditions as the first.

category:cq
theme:basic-cq
skill-level:intermediate
cost:medium

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIoptimization

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions