Skip to content

Conversation

@jakobbotsch
Copy link
Member

The JIT has an optimization to recognize recomputations of field offsets, but this optimization failed to trigger in certain cases when the struct was promoted with old promotion.

public unsafe nint Test()
{
    MyStruct dummy;
    return (nint)((byte*)&dummy.Field - (byte*)&dummy);
}

private struct MyStruct
{
    public int A;
    public int Field;
}

Before:

G_M27992_IG01:  ;; offset=0x0000
       push     rax
       xor      eax, eax
       mov      qword ptr [rsp], rax
						;; size=7 bbWeight=1 PerfScore 2.25

G_M27992_IG02:  ;; offset=0x0007
       lea      rax, [rsp+0x04]
       lea      rcx, [rsp]
       sub      rax, rcx
						;; size=12 bbWeight=1 PerfScore 1.25

G_M27992_IG03:  ;; offset=0x0013
       add      rsp, 8
       ret
						;; size=5 bbWeight=1 PerfScore 1.25

After:

G_M27992_IG02:  ;; offset=0x0000
       mov      eax, 4
						;; size=5 bbWeight=1 PerfScore 0.25

G_M27992_IG03:  ;; offset=0x0005
       ret
						;; size=1 bbWeight=1 PerfScore 1.00

The JIT has an optimization to recognize recomputations of field
offsets, but this optimization failed to trigger in certain cases when
the struct was promoted with old promotion.

```csharp
public unsafe nint Test()
{
    MyStruct dummy;
    return (nint)((byte*)&dummy.Field - (byte*)&dummy);
}
```
Before:
```asm
G_M27992_IG01:  ;; offset=0x0000
       push     rax
       xor      eax, eax
       mov      qword ptr [rsp], rax
						;; size=7 bbWeight=1 PerfScore 2.25

G_M27992_IG02:  ;; offset=0x0007
       lea      rax, [rsp+0x04]
       lea      rcx, [rsp]
       sub      rax, rcx
						;; size=12 bbWeight=1 PerfScore 1.25

G_M27992_IG03:  ;; offset=0x0013
       add      rsp, 8
       ret
						;; size=5 bbWeight=1 PerfScore 1.25
```
After:
```asm
G_M27992_IG02:  ;; offset=0x0000
       mov      eax, 4
						;; size=5 bbWeight=1 PerfScore 0.25

G_M27992_IG03:  ;; offset=0x0005
       ret
						;; size=1 bbWeight=1 PerfScore 1.00
```
@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Dec 8, 2025
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@jakobbotsch jakobbotsch marked this pull request as ready for review December 9, 2025 10:52
Copilot AI review requested due to automatic review settings December 9, 2025 10:52
@jakobbotsch
Copy link
Member Author

PTAL @dotnet/jit-contrib

Minor improvements

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the JIT compiler's optimization to recognize and fold struct field offset computations when structs are promoted using old promotion. Previously, the optimization only worked when computing offsets between the same local variable, but failed when promoted struct fields were involved.

  • Extends the SUB node optimization to resolve parent local variables and aggregate field offsets for promoted struct fields
  • Enables compile-time constant folding of field offset patterns that previously required runtime computation
  • Significantly improves code generation by eliminating unnecessary address arithmetic

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant