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

Reply via email to