-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Open
Description
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
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
Backl1ght commentedon Jun 22, 2025
It seems like we only perform the merge operation only when the data types are the same. For example, as for
We only merge copy of
index
andindex2
currently. Makedata
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.