Skip to content

Extra bound checks are not eliminated for pinning #35748

Closed
@EgorBo

Description

@EgorBo

The following "array pinning" syntax

public static void Test(int[] array)
{
    fixed (int* p = array)
        DoWork(p);
}

is a С# 7(?) syntax sugar for:

public static void Test(int[] array)
{
    if (array != null && array.Length > 0)
    {
        fixed (int* p = &array[0]) // array is always not empty at this point
            DoWork(p);
    }
}

As you can see, there is no way this code can throw an out of bounds exception.

Codegen (master):

; Method Test(System.Int32[])
G_M31592_IG01:
       4883EC28             sub      rsp, 40
       33C0                 xor      rax, rax
       4889442420           mov      qword ptr [rsp+20H], rax
G_M31592_IG02:
       48894C2420           mov      gword ptr [rsp+20H], rcx
       4885C9               test     rcx, rcx
       740B                 je       SHORT G_M31592_IG04
G_M31592_IG03:
       488B4C2420           mov      rcx, gword ptr [rsp+20H]
       83790800             cmp      dword ptr [rcx+8], 0    ;; we already check Length here
       7504                 jne      SHORT G_M31592_IG05
G_M31592_IG04:
       33C9                 xor      rcx, rcx
       EB14                 jmp      SHORT G_M31592_IG06
G_M31592_IG05:
       488B4C2420           mov      rcx, gword ptr [rsp+20H]
       83790800             cmp      dword ptr [rcx+8], 0     ;; redundant
       761A                 jbe      SHORT G_M31592_IG08      ;; redundant
       488B4C2420           mov      rcx, gword ptr [rsp+20H]
       4883C110             add      rcx, 16
G_M31592_IG06:
       E8EB60FFFF           call     EgorClass:DoWork(long)
       33C0                 xor      rax, rax
       4889442420           mov      gword ptr [rsp+20H], rax
G_M31592_IG07:
       4883C428             add      rsp, 40
       C3                   ret      
G_M31592_IG08:   ;; not needed
       E872C0485F           call     CORINFO_HELP_RNGCHKFAIL   ;; redundant
       CC                   int3                               ;; redundant
; Total bytes of code: 79

Unfortunately, Assertion prop doesn't optimize the bound check away.

category:cq
theme:pinning
skill-level:expert
cost:extra-large
impact:medium

Metadata

Metadata

Assignees

No one assigned

    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