dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.72k forks source link

NAOT: fold "always false" typechecks #97601

Closed EgorBo closed 7 months ago

EgorBo commented 8 months ago

If an interface/abstract class has no subclasses or they were trimmed out - all typechecks against that subclass should be folded, e.g.:

interface IMyInterface { }

class Program
{
    static void Main()
    {
        Test(null);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static void Test(object o)
    {
        if (o is IMyInterface) // there are no types implementing this interface
            Console.WriteLine("MyInterface!");
    }
}

Current codegen with NativeAOT for Test:

; Assembly listing for method Program:Test(System.Object) (FullOpts)
       sub      rsp, 40
       mov      rdx, rcx
       lea      rcx, [(reloc 0x4000000000422e10)] ; IMyInterface
       call     CORINFO_HELP_ISINSTANCEOFINTERFACE
       test     rax, rax
       je       SHORT G_M3485_IG04
       lea      rcx, gword ptr [(reloc 0x4000000000422e28)] ; '"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)
       ret      
; Total bytes of code 1,

cc @MichalStrehovsky. I presume for that we need to make 0 a meaningful result for getExactClasses API.

ghost commented 8 months ago

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.

Issue Details
If an interface/abstract class has no subclasses or they were trimmed out - all typechecks against that subclass should be folded, e.g.: ```cs interface IMyInterface { } class Program { static void Main() { Test(null); } [MethodImpl(MethodImplOptions.NoInlining)] static void Test(object o) { if (o is IMyInterface) // there are no types implementing this interface Console.WriteLine("MyInterface!"); } } ``` Current codegen: ```asm ; Assembly listing for method Program:Test(System.Object) (FullOpts) sub rsp, 40 mov rdx, rcx lea rcx, [(reloc 0x4000000000422e10)] ; IMyInterface call CORINFO_HELP_ISINSTANCEOFINTERFACE test rax, rax je SHORT G_M3485_IG04 lea rcx, gword ptr [(reloc 0x4000000000422e28)] ; '"MyInterface!"' call System.Console:WriteLine(System.String) G_M3485_IG04: nop add rsp, 40 ret ; Total bytes of code 42 ``` Expected codegen: ```asm ; Assembly listing for method Program:Test(System.Object) (FullOpts) ret ; Total bytes of code 1, ``` cc @MichalStrehovsky. I presume for that we need to make 0 a meaningful result for `getExactClasses` API.
Author: EgorBo
Assignees: -
Labels: `area-CodeGen-coreclr`, `untriaged`
Milestone: -