Skip to content

[RyuJIT] Unnecessary nullcheck in Exchange_long benchmark #44087

@EgorBo

Description

@EgorBo

dotnet/performance/Perf.Interlocked.cs#L39:

private long _long = 0;

[MethodImpl(MethodImplOptions.NoInlining)]
public long Exchange_long() => Interlocked.Exchange(ref _long, 1);

Codegen for Exchange_long:

       cmp      dword ptr [rcx], ecx ;; <--- nullcheck
       lea      rax, bword ptr [rcx+8]
       mov      edx, 1
       xchg     qword ptr [rax], rdx
       mov      rax, rdx
       ret

this code never throws NRE.
Is it #define CONSERVATIVE_NULL_CHECK_BYREF_CREATION 1's fault?

/cc @dotnet/jit-contrib @sandreenko

UPD: Same in MONO:

   0:   50                      push   %rax
   1:   48 85 ff                test   %rdi,%rdi  ;; <----
   4:   74 0b                   je     11 <xchange_long___+0x11>
   6:   b8 01 00 00 00          mov    $0x1,%eax
   b:   48 87 47 10             xchg   %rax,0x10(%rdi)
   f:   59                      pop    %rcx
  10:   c3                      retq
  11:   48 b8 60 e9 74 54 13    movabs $0x56135474e960,%rax
  18:   56 00 00
  1b:   bf 32 01 00 00          mov    $0x132,%edi
  20:   ff 10                   callq  *(%rax)

category:cq
theme:optimization
skill-level:beginner
cost:small
impact:small

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

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions