Skip to content

Fix bug in LowerCallMemmove#123907

Merged
EgorBo merged 10 commits intodotnet:mainfrom
EgorBo:fix-memmove-lowering
Feb 11, 2026
Merged

Fix bug in LowerCallMemmove#123907
EgorBo merged 10 commits intodotnet:mainfrom
EgorBo:fix-memmove-lowering

Conversation

@EgorBo
Copy link
Member

@EgorBo EgorBo commented Feb 2, 2026

Might fix (but not sure) #123748

LowerCallMemmove was initially written to inline SpanHelpers.Memmove into something that guarantees proper non-aliased move (load all data into separate registers first, then save them all at once) as opposite to what normal GT_STORE_BLK does - it's paired with genCodeForMemmove. That's why we sort of try to Lower BLK/STORE_BLK by hands there.

Later, CORINFO_HELP_MEMCPY was added as well (typical scenario: cpblk IL code (Unsafe.CopyBlocksUnaligned) with the length that becomes a constant in a late phase) and since it doesn't require the memmove semantics, we used GenTreeBlk::BlkOpKindUnroll, but in that case we either have to replace the call into a pre-Lower shape and call Lower on srcBlk+storeBlk since we're no longer paired with genCodeForMemmove, or just use the same memmove mode.
memmove mode is more expensive for LSRA and doesn't support addressing modes, but it seems that CORINFO_HELP_MEMCPY is rarely used.

Example of a changed codegen:

static void Test(ref byte a, ref byte b, uint len)
{
    if (len == 200)
    {
        Unsafe.CopyBlockUnaligned(ref a, ref b, len);
    }
}

Was:

       vmovdqu32 zmm0, zmmword ptr [rdx]
       vmovdqu32 zmmword ptr [rcx], zmm0
       vmovdqu32 zmm0, zmmword ptr [rdx+0x40]
       vmovdqu32 zmmword ptr [rcx+0x40], zmm0
       vmovdqu32 zmm0, zmmword ptr [rdx+0x80]
       vmovdqu32 zmmword ptr [rcx+0x80], zmm0
       mov      rax, qword ptr [rdx+0xC0]
       mov      qword ptr [rcx+0xC0], rax

Now:

       vmovdqu32 zmm0, zmmword ptr [rdx]
       vmovdqu32 zmm1, zmmword ptr [rdx+0x40]
       vmovdqu32 zmm2, zmmword ptr [rdx+0x80]
       vmovdqu  xmm3, xmmword ptr [rdx+0xB8]
       vmovdqu32 zmmword ptr [rcx], zmm0
       vmovdqu32 zmmword ptr [rcx+0x40], zmm1
       vmovdqu32 zmmword ptr [rcx+0x80], zmm2
       vmovdqu  xmmword ptr [rcx+0xB8], xmm3

No diffs

Copilot AI review requested due to automatic review settings February 2, 2026 18:31
@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 Feb 2, 2026
@dotnet-policy-service
Copy link
Contributor

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

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 pull request fixes a critical JIT crash (access violation) in LowerCallMemmove that occurs when compiling calls to C++/CLI functions returning structs with aggregate initialization, addressing issue #123748.

Changes:

  • Fixed LowerCallMemmove in src/coreclr/jit/lower.cpp to use proper helper functions (gtNewBlkIndir and gtNewStoreBlkNode) instead of manual tree construction
  • Corrected the *next pointer to point to the first node to be lowered (srcBlk) instead of accessing an uninitialized gtNext field
  • Added explicit GTF_IND_UNALIGNED to GTF_IND_FLAGS in src/coreclr/jit/gentree.h (redundant but harmless)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/coreclr/jit/lower.cpp Fixed the LowerCallMemmove function to use proper helper functions for tree construction and corrected the next pointer to avoid null dereference
src/coreclr/jit/gentree.h Added GTF_IND_UNALIGNED explicitly to GTF_IND_FLAGS (redundant as it's already included via GTF_IND_COPYABLE_FLAGS)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 2, 2026 18:51
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

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@EgorBo EgorBo marked this pull request as ready for review February 3, 2026 01:18
Copilot AI review requested due to automatic review settings February 3, 2026 01:18
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

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

…move-lowering

# Conflicts:
#	src/coreclr/jit/lower.cpp
…move-lowering

# Conflicts:
#	src/coreclr/jit/lower.cpp
Copilot AI review requested due to automatic review settings February 9, 2026 14:20
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

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

Copilot AI review requested due to automatic review settings February 10, 2026 13:32
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

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

@EgorBo
Copy link
Member Author

EgorBo commented Feb 11, 2026

PTAL @dotnet/jit-contrib simple fix for a potential problem

@EgorBo EgorBo requested a review from a team February 11, 2026 14:28
@EgorBo EgorBo merged commit 41472c4 into dotnet:main Feb 11, 2026
128 of 131 checks passed
@EgorBo EgorBo deleted the fix-memmove-lowering branch February 11, 2026 14:47
iremyux pushed a commit to iremyux/dotnet-runtime that referenced this pull request Mar 2, 2026
Might fix (but not sure) dotnet#123748

`LowerCallMemmove` was initially written to inline `SpanHelpers.Memmove`
into something that guarantees proper non-aliased move (load all data
into separate registers first, then save them all at once) as opposite
to what normal `GT_STORE_BLK` does - it's paired with
`genCodeForMemmove`. That's why we sort of try to Lower BLK/STORE_BLK by
hands there.

Later, `CORINFO_HELP_MEMCPY` was added as well (typical scenario:
`cpblk` IL code (`Unsafe.CopyBlocksUnaligned`) with the length that
becomes a constant in a late phase) and since it doesn't require the
memmove semantics, we used `GenTreeBlk::BlkOpKindUnroll`, but in that
case we either have to replace the call into a pre-Lower shape and call
Lower on srcBlk+storeBlk since we're no longer paired with
`genCodeForMemmove`, or just use the same memmove mode.
`memmove` mode is more expensive for LSRA and doesn't support addressing
modes, but it seems that `CORINFO_HELP_MEMCPY` is rarely used.

Example of a changed codegen:
```cs
static void Test(ref byte a, ref byte b, uint len)
{
    if (len == 200)
    {
        Unsafe.CopyBlockUnaligned(ref a, ref b, len);
    }
}
```
Was:
```asm
       vmovdqu32 zmm0, zmmword ptr [rdx]
       vmovdqu32 zmmword ptr [rcx], zmm0
       vmovdqu32 zmm0, zmmword ptr [rdx+0x40]
       vmovdqu32 zmmword ptr [rcx+0x40], zmm0
       vmovdqu32 zmm0, zmmword ptr [rdx+0x80]
       vmovdqu32 zmmword ptr [rcx+0x80], zmm0
       mov      rax, qword ptr [rdx+0xC0]
       mov      qword ptr [rcx+0xC0], rax
```
Now:
```asm
       vmovdqu32 zmm0, zmmword ptr [rdx]
       vmovdqu32 zmm1, zmmword ptr [rdx+0x40]
       vmovdqu32 zmm2, zmmword ptr [rdx+0x80]
       vmovdqu  xmm3, xmmword ptr [rdx+0xB8]
       vmovdqu32 zmmword ptr [rcx], zmm0
       vmovdqu32 zmmword ptr [rcx+0x40], zmm1
       vmovdqu32 zmmword ptr [rcx+0x80], zmm2
       vmovdqu  xmmword ptr [rcx+0xB8], xmm3
```


No
[diffs](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1287687&view=ms.vss-build-web.run-extensions-tab)

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

3 participants