Skip to content

Copying of adjacent fields can be merged #144613

@hiraditya

Description

@hiraditya
Collaborator

Saw this on X(https://x.com/joseph_h_garvin/status/1934705584705843340) Assigning adjacent field of struct can be merged as a copy but clang does not recognize it when the data types are different.

Repro:

#include <functional>

struct handle {
    void* data; // Replacing it with int data works.
    int index;
};

void remove(handle* p, int idx, int& end)
{
    auto& item = p[idx];
    auto& last = p[end];
    item = last;
    --end;
}

void remove2(handle* p, int idx, int& end)
{
    auto& item = p[idx];
    auto& last = p[end];
    item.data = last.data;
    item.index = last.index;
    --end;
}

$ clang -O2

remove(handle*, int, int&):
        ldrsw   x8, [x2]
        ldr     q0, [x0, x8, lsl #4]
        str     q0, [x0, w1, sxtw #4]
        ldr     w8, [x2]
        sub     w8, w8, #1
        str     w8, [x2]
        ret

remove2(handle*, int, int&):
        ldrsw   x8, [x2]
        add     x9, x0, w1, sxtw #4
        add     x8, x0, x8, lsl #4
        ldr     w10, [x8, #8]
        ldr     x8, [x8]
        str     w10, [x9, #8]
        ldr     w10, [x2]
        str     x8, [x9]
        sub     w8, w10, #1
        str     w8, [x2]
        ret

https://godbolt.org/z/61avd145T

Activity

Backl1ght

Backl1ght commented on Jun 22, 2025

@Backl1ght
Member

It seems like we only perform the merge operation only when the data types are the same. For example, as for

struct handle {
    void* data;
    long long index;
    long long index2;
    long long index3;
};

We only merge copy of index and index2 currently. Make data a double results the same godbold. But I think we can merge copy operations as long as the memory matched exactly.

As for the case that the memory does not matched exactly, like the original reproducer, I'm afraid that it can not be resolved elegantly in llvm optimizer, as we do not have memory layout info in LLVM IR, like we don't know there is a 32 bits padding after index. But maybe we can make it in clang ir.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @hiraditya@EugeneZelenko@Backl1ght

        Issue actions

          Copying of adjacent fields can be merged · Issue #144613 · llvm/llvm-project