Skip to content

RyuJIT generates unnecessary null check #4324

Closed
@mikedn

Description

@mikedn

An unnecessary null check of this is generated even if it is known to be non-null due to a previous explicit check:

using System.Collections.Generic;
class Info {
    List<int> slice = new List<int>();
    public bool IsTracked(int x) {
        return slice != null && slice.Contains(x);
    }
}
class Visitor {
    Info info = new Info();
    [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
    public int Test(int x) {
        if (info.IsTracked(x))
            return 0;
        return x;
    }
}
class Program {
    static int Main(string[] args) {
        var v = new Visitor();
        return v.Test(args.Length);
    }
}

Generated code for the relevant block in the Test method:

G_M2972_IG02:
       488B4908             mov      rcx, gword ptr [rcx+8]
       488B4908             mov      rcx, gword ptr [rcx+8]
       4885C9               test     rcx, rcx                 ;explicit null check
       740B                 je       SHORT G_M2972_IG03
       8BD6                 mov      edx, esi
       3909                 cmp      dword ptr [rcx], ecx     ;redundant null check
       E85389AA5E           call     System.Collections.Generic.List`1[Int32][System.Int32]:Contains(int):bool:this
       EB02                 jmp      SHORT G_M2972_IG04

This does not happen if info is copied into a local variable and used for both the null check and the Contains call. The null check optimization behaves as if the slice field is loaded twice and in that case the null check would be required to avoid a race condition. Probably there's another part of the optimizer which later decides to (correctly) eliminate the second load but it's too late for the null check to be removed.

category:cq
theme:cse
skill-level:intermediate
cost:small
impact:small

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsoptimizationtenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions