Skip to content

NAOT: isinst with multiple guesses without fallback #97602

@EgorBo

Description

@EgorBo
interface IMyInterface { }

public class MyImplementation1 : IMyInterface { }
public class MyImplementation2 : IMyInterface { }

class Program
{

    static void Main()
    {
        Test(new MyImplementation1());
        Test(new MyImplementation2());
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static void Test(object o)
    {
        if (o is IMyInterface)
            Console.WriteLine("MyInterface!");
    }
}

Since there are only 2 classes implementing IMyInterface, JIT should be able to optimize Test as follows:

if (o != null && ((o.GetType() == typeof(MyImplementation1) || o.GetType() == typeof(MyImplementation2))
{
}

without any helper call fallback. Similar to what NAOT already does for virtual calls.

Current codegen for Test:

; Assembly listing for method Program:Test(System.Object) (FullOpts)
       sub      rsp, 40
       mov      rdx, rcx
       lea      rcx, [(reloc 0x4000000000422460)] ; IMyInterface
       call     CORINFO_HELP_ISINSTANCEOFINTERFACE
       test     rax, rax
       je       SHORT G_M3485_IG04
       lea      rcx, gword ptr [(reloc 0x4000000000422478)] ; '"MyInterface!"'
       call     System.Console:WriteLine(System.String)
G_M3485_IG04:
       nop      
       add      rsp, 40
       ret      
; Total bytes of code 42

Expected codegen:

; Assembly listing for method Program:Test(System.Object) (FullOpts)
       sub      rsp, 40
       test     rcx, rcx
       je       SHORT G_M3485_IG05
       mov      rcx, qword ptr [rcx]
       lea      rax, [(reloc 0x40000000004224f8)] ; MyImplementation1
       cmp      rcx, rax
       je       SHORT G_M3485_IG04
       lea      rax, [(reloc 0x4000000000422518)] ; MyImplementation2
       cmp      rcx, rax
       jne      SHORT G_M3485_IG05
G_M3485_IG04: 
       lea      rcx, gword ptr [(reloc 0x4000000000422520)] ; '"MyInterface!"'
       call     System.Console:WriteLine(System.String)
G_M3485_IG05: 
       nop      
       add      rsp, 40
       ret      
; Total bytes of code 54

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions