Skip to content

Incorrect result when using Unsafe.Add in Release mode #71601

@GaryHuan9

Description

@GaryHuan9

Description

The following piece of code prints 11 11 under Debug mode, but it prints 11 10 under Release mode. Upon observation, we can see that 11 11 is the correct value, and Release mode's strong optimizations incorrectly inlined the stored values.

P p = new P(10);

System.Console.WriteLine(p.i1.data);
System.Console.WriteLine(p[1].data);

struct P
{
    public P(int value)
    {
        i0 = new I(value);
        i1 = new I(value + 1);
    }
    
    public I i0;
    public I i1;
    
    public I this[int index] => System.Runtime.CompilerServices.Unsafe.Add(ref i0, index);
}

readonly struct I
{
    public I(int data) => this.data = data;
    
    public readonly int data;
}

The output of the JIT compiler shows that under Release mode, it directly feeds the constants 0xA and 0xB into the WriteLine method (the 0xA value is incorrect):

L000e: mov dword ptr [ebp-8], 0xa
L0015: mov dword ptr [ebp-4], 0xb
L001c: mov ecx, [ebp-4]
L001f: call System.Console.WriteLine(Int32)
L0024: mov ecx, [ebp-8]
L0027: call System.Console.WriteLine(Int32)

SharpLab

Reproduction Steps

  1. Create a dotnet project using the most recent commit on the main branch as of this writing (5961604).
  2. Copy and paste the code snippet.
  3. Build and run the project in Debug mode.
  4. Build and run the project in Release mode.
  5. Observe the difference.

Expected behavior

The build under Release mode prints 11 10.

Actual behavior

It should print 11 11.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Labels

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

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions