Skip to content

JIT might emit unnecessary null check when enumerating arrays of KVP #67739

@GrabYourPitchforks

Description

@GrabYourPitchforks

Reported via Discord. A null check is being emitted that we'd reasonably expect to have been elided. Repro code:

    public long EnumerateKvps(KeyValuePair<string, int>[] kvps)
    {
        long result = 0;
        
        foreach (var kvp in kvps)
        {
            result += kvp.Value;
        }
        
        return result;
    }

Codegen, x64 release (per sharplab):

C.EnumerateKvps(System.Collections.Generic.KeyValuePair`2<System.String,Int32>[])
    L0000: xor eax, eax
    L0002: xor ecx, ecx
    L0004: mov r8d, [rdx+8]
    L0008: test r8d, r8d
    L000b: jle short L0030
    L000d: nop [rax]
    L0010: movsxd r9, ecx
    L0013: shl r9, 4
    L0017: lea r9, [rdx+r9+0x10]
    L001c: cmp [r9], r9d  ; <-- this null check should have been elided
    L001f: mov r9d, [r9+8]
    L0023: movsxd r9, r9d
    L0026: add rax, r9
    L0029: inc ecx
    L002b: cmp r8d, ecx
    L002e: jg short L0010
    L0030: ret

L0017 - L0023 taken as a whole are interesting. It seems like all of those lines could have been the single instruction movsxd r9, [rdx + r9 + 0x18]. But for some reason, on L001f and L0023, the two instructions are not being folded into one another.

category:cq
theme:structs
skill-level:expert
cost:medium
impact:medium

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions