dotnet / runtime

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

Merge nested branches into AND test #101820

Open reflectronic opened 2 months ago

reflectronic commented 2 months ago

Consider:

public static void M1(bool b1, bool b2) 
{
    if (b1)
    {
        if (b2)
        {
            Console.WriteLine(100);
        }
    }
}

public static void M2(bool b1, bool b2) 
{
    if (b1 & b2)
    {
        Console.WriteLine(100);
    }
}

The following code is generated:

;; coreclr trunk-20240502+71f8fb65a5a28018901823c19de57fe9451ab3b1

D:M1(ubyte,ubyte) (FullOpts):
G_M7125_IG01:  ;; offset=0x0000
       push     rbp
       mov      rbp, rsp
G_M7125_IG02:  ;; offset=0x0004
       test     dil, dil
       je       SHORT G_M7125_IG05
G_M7125_IG03:  ;; offset=0x0009
       test     sil, sil
       je       SHORT G_M7125_IG05
       mov      edi, 100
G_M7125_IG04:  ;; offset=0x0013
       pop      rbp
       tail.jmp [System.Console:WriteLine(int)]
G_M7125_IG05:  ;; offset=0x001A
       pop      rbp
       ret      

D:M2(ubyte,ubyte) (FullOpts):
G_M31862_IG01:  ;; offset=0x0000
G_M31862_IG02:  ;; offset=0x0000
       movzx    rdi, dil
       movzx    rax, sil
       test     edi, eax
       je       SHORT G_M31862_IG05
G_M31862_IG03:  ;; offset=0x000C
       mov      edi, 100
G_M31862_IG04:  ;; offset=0x0011
       tail.jmp [System.Console:WriteLine(int)]
G_M31862_IG05:  ;; offset=0x0017
       ret      

Though the two methods behave identically, M1 contains an extra test and branch (and frame, due to more complex control flow). The nested branches could be transformed into one AND test to optimize this automatically.

dotnet-policy-service[bot] commented 2 months ago

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

reflectronic commented 2 months ago

Though the two methods behave identically

Hm. They do not for non-normalized bool values. That makes it more complicated than this (though perhaps still cheaply possible).