Skip to content

Unsafe.As doesn't update type information in JIT #84377

@EgorBo

Description

@EgorBo

Noticed in #84370 (comment)

public class ClassA
{
    public virtual int GetVal() => 1;
}

public sealed class ClassB : ClassA
{
    public override int GetVal() => 42;
}


void GetValUnsafe(ClassA tc) => Unsafe.As<ClassB>(tc).GetVal();

Current codegen:

; Method GetValUnsafe(ClassA):this
       sub      rsp, 40
       mov      rcx, rdx
       mov      rax, qword ptr [rdx]
       mov      rax, qword ptr [rax+48H]
       call     [rax+20H]ClassA:GetVal():int:this
       nop      
       add      rsp, 40
       ret      
; Total bytes of code: 23

Expected codegen:

; Method GetValUnsafe(ClassB):this
       cmp      byte  ptr [rdx], dl
       ret      
; Total bytes of code: 3

The idea that Unsafe.As JIT intrinsic should spill its input to a local and set class for that local based on signature.

case NI_SRCS_UNSAFE_As:
{
assert((sig->sigInst.methInstCount == 1) || (sig->sigInst.methInstCount == 2));
// ldarg.0
// ret
return impPopStack().val;
}

Metadata

Metadata

Assignees

Labels

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

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions