| Issue |
61620
|
| Summary |
Aliasing failure to remove unnecessary store/reload
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
RKSimon
|
https://gcc.godbolt.org/z/j77ePhjaT
```c
struct Cache {
static int k_ref;
int m_data;
Cache& init() {
__builtin_memcpy(&m_data, &k_ref, sizeof(m_data));
return *this;
}
Cache& set(int i) {
m_data = k_ref + i;
return *this;
}
};
void reset(Cache &data) {
data.init().set(1);
}
void alias() {
Cache *data = "" *)&Cache::k_ref;
reset(*data);
}
```
clang -g0 -O2
```asm
reset(Cache&): # @reset(Cache&)
movq Cache::k_ref@GOTPCREL(%rip), %rax
movl (%rax), %ecx
movl %ecx, (%rdi)
movl (%rax), %eax // <-- UNNECESSARY RELOAD OF k_ref ???
incl %eax
movl %eax, (%rdi)
retq
alias(): # @alias()
movq Cache::k_ref@GOTPCREL(%rip), %rax
incl (%rax)
retq
```
In this reduced test case, the reset() call fails to recognise that the static k_ref value and m_data shouldn't alias (as this would be UB via the __builtin_memcpy), meaning that it shouldn't be necessary to reload the k_ref value after the initial copy, meaning that the original store would be entirely superfluous.
Interestingly the alias() call, which I THINK counts as UB, gets a lot closer to what I'd expect the codegen to simplify to.
(I might have missed some particular hidden lore regarding c/c++ aliasing here.....)
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs