Skip to content

JIT optimization breaks pointer/ref arithmetic #61510

@AndrejStanisev

Description

@AndrejStanisev

Description

We allocate some unmanaged memory that we then manipulate via references rather than raw pointers. We use the following trick to get a ref byte from an address stored as nint.

public static ref byte GetReference(nint addr) => ref Unsafe.AddByteOffset(ref Unsafe.NullRef<byte>(), addr);

This works correctly in .NET 5, but returns a null pointer in .NET 6, where this code gets JITed to return 0 unconditionally, as follows:

00007FFF71040FB0  xor         eax,eax  
00007FFF71040FB2  ret  

Reproduction Steps

class Program
{

    public static void Main()
    {
        ref var a = ref GetReference(10_000);
        Console.WriteLine(a);
    }

    [MethodImpl(MethodImplOptions.AggressiveOptimization)]
    public static ref byte GetReference(nint addr) => ref Unsafe.AddByteOffset(ref Unsafe.NullRef<byte>(), addr);
}

Expected behavior

The JIT should output code performing arithmetic with the given parameter.

Actual behavior

JIT outputs code returning 0 unconditionally.

Regression?

The example works correctly in .NET 5.

Known Workarounds

No response

Configuration

.NET Version 6.0.100
Windows Version 10.0.19042 Build 19042
x64

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions