Skip to content

Incorrect (?) optimizations of overlapped struct copy in unsafe code #7539

Open

Description

The JIT assumes that structs cannot overlap when generating code for struct copies. This assumption is not guaranteed in unsafe code. I have noticed it while looking at dotnet/coreclr#9786.

Compile with /o+ on x64:

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

[StructLayout(LayoutKind.Sequential, Size = 64)]
struct Block64 { }

unsafe class Test
{
    [MethodImpl(MethodImplOptions.NoInlining)]
    static void Copy(Block64* pDest, Block64* pSrc)
    {
        *pDest = *pSrc;
    }

    static void Main()
    {
        byte[] buf = new byte[65];
        for (int i = 0; i < buf.Length; i++) buf[i] = (byte)i;

        fixed (byte* p = buf)
        {
            Copy((Block64*)(p + 1), (Block64*)p);
        }

        Console.Write("Expected: 16 Actual: " + buf[17].ToString());
    }
}

Result: Expected: 16 Actual: 15
category:correctness
theme:block-opts
skill-level:expert
cost:small
impact:small

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions