Skip to content

JIT: suboptimal generated code for struct overlapped field manipulation #69254

@hez2010

Description

@hez2010

Description

Repro (compile with roslyn features/ref-fields branch):

using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

var color = new Color { R = 1, G = 2, B = 3, A = 4 };
color.Raw[2] = 3;
color.SRaw[1] = 4;
Console.WriteLine(color.G);

[StructLayout(LayoutKind.Explicit)]
struct Color
{
    [FieldOffset(0)] public byte R;
    [FieldOffset(1)] public byte G;
    [FieldOffset(2)] public byte B;
    [FieldOffset(3)] public byte A;

    [FieldOffset(0)] public int Rgba;

    [UnscopedRef] public ColorView<byte> Raw => new(ref this);
    [UnscopedRef] public ColorView<short> SRaw => new(ref this);
}

ref struct ColorView<T> where T : unmanaged
{
    private ref Color color;

    public ColorView(ref Color color)
    {
        this.color = ref color;
    }
    private static ref T Throw() => throw new IndexOutOfRangeException();

    public ref T this[uint index]
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        get
        {
            unsafe
            {
                return ref sizeof(T) * index >= sizeof(Color) ?
                    ref Throw() :
                    ref Unsafe.Add(ref Unsafe.As<Color, T>(ref color), index);
            }
        }
    }
}

Codegen for Main (tier1):

G_M61237_IG01:  ;; offset=0000H
       sub      rsp, 56
						;; size=4 bbWeight=1 PerfScore 0.25

G_M61237_IG02:  ;; offset=0004H
       xor      ecx, ecx
       mov      dword ptr [rsp+28H], ecx
       mov      byte  ptr [rsp+28H], 1
       mov      byte  ptr [rsp+29H], 2
       mov      byte  ptr [rsp+2AH], 3
       mov      byte  ptr [rsp+2BH], 4
       mov      ecx, dword ptr [rsp+28H]
       mov      dword ptr [rsp+30H], ecx
       lea      rcx, bword ptr [rsp+30H]
       add      rcx, 2
       mov      byte  ptr [rcx], 3
       lea      rcx, bword ptr [rsp+30H]
       mov      word  ptr [rcx+02H], 4
       movzx    rcx, byte  ptr [rsp+31H]
       call     [System.Console:WriteLine(int)]
       nop      
						;; size=69 bbWeight=1 PerfScore 14.75

G_M61237_IG03:  ;; offset=0049H
       add      rsp, 56
       ret      
						;; size=5 bbWeight=1 PerfScore 1.25
; Total bytes of code: 78

G_M56640_IG02 can be folded into a constant.

Expected codegen of G_M56640_IG02:

mov ecx, 2
call [System.Console:WriteLine(int)]

Clang codegen: https://godbolt.org/z/W7416EsrT

Configuration

.NET: build from main

category:cq
theme:structs
skill-level:expert
cost:large
impact:medium

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

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions