Skip to content

Branches guarded by type checks not being trimmed in generic types/methods #7423

@stephentoub

Description

@stephentoub

Consider this code:

using System;

public class Test
{
    public static void Main() => Bar<bool>.Foo();
}

internal class Bar<T>
{
    public static void Foo()
    {
        if (typeof(T) == typeof(bool))
        {
            Console.WriteLine("bool");
        }
        else if (typeof(T) == typeof(int))
        {
            Console.WriteLine("int");
        }
    }
}

Since this code should be specialized per value type, I was expecting Foo to compile down to effectively "Console.WriteLine("bool")", but instead I get this:

; Assembly listing for method Bar`1[Boolean][System.Boolean]:Foo()
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; fully interruptible
; Final local variable assignments
;
;  V00 tmp0         [V00,T00] (  2,   4  )     ref  ->  rsi
;  V01 tmp1         [V01,T01] (  2,   2  )     ref  ->  rsi
;  V02 OutArgs      [V02    ] (  1,   1  )  lclBlk (32) [rsp+0x00]
;
; Lcl frame size = 32

G_M20354_IG01:
       56                   push     rsi
       4883EC20             sub      rsp, 32

G_M20354_IG02:
       48B9081BE1B9FB7F0000 mov      rcx, 0x7FFBB9E11B08
       E850BBF65E           call     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
       488BF0               mov      rsi, rax
       48B9081BE1B9FB7F0000 mov      rcx, 0x7FFBB9E11B08
       E83EBBF65E           call     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
       483BC6               cmp      rax, rsi
       751F                 jne      SHORT G_M20354_IG04
       48B9205728EFA5020000 mov      rcx, 0x2A5EF285720
       488B09               mov      rcx, gword ptr [rcx]
       48B850010CBAFB7F0000 mov      rax, 0x7FFBBA0C0150

G_M20354_IG03:
       4883C420             add      rsp, 32
       5E                   pop      rsi
       48FFE0               rex.jmp  rax

G_M20354_IG04:
       48B9081BE1B9FB7F0000 mov      rcx, 0x7FFBB9E11B08
       E80BBBF65E           call     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
       488BF0               mov      rsi, rax
       48B98099E1B9FB7F0000 mov      rcx, 0x7FFBB9E19980
       E8F9BAF65E           call     CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE
       483BC6               cmp      rax, rsi
       751F                 jne      SHORT G_M20354_IG06
       48B9285728EFA5020000 mov      rcx, 0x2A5EF285728
       488B09               mov      rcx, gword ptr [rcx]
       48B850010CBAFB7F0000 mov      rax, 0x7FFBBA0C0150

G_M20354_IG05:
       4883C420             add      rsp, 32
       5E                   pop      rsi
       48FFE0               rex.jmp  rax

G_M20354_IG06:
       4883C420             add      rsp, 32
       5E                   pop      rsi
       C3                   ret

; Total bytes of code 149, prolog size 5 for method Bar`1[Boolean][System.Boolean]:Foo()
; ============================================================

This is a simplification of code we have in the async/await infrastructure, for getting cached tasks for certain return types, and it used to produce the correct code on desktop... has something changed here recently? Is this not supposed to remove code in the manner I expected?

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions