https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103427
Bug ID: 103427 Summary: Alignment of C++ references and 'this' pointer not used by optimizer Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <stdint.h> void* f(int& i) { // should be no-op, &i is aligned to alignof(int) return (void*)((((uintptr_t)&i) + 3) & ~3); } struct My { int value; void* Test1(); void* Test2(); }; void* My::Test1() { return this; } void* My::Test2() { // should be no-op, 'this' is aligned to alignof(My) return (void*)((((uintptr_t)this) + 3) & ~3); } GCC fails to optimize away the redundant arithmetic to "fix" the alignment: f(int&): lea rax, [rdi+3] and rax, -4 ret My::Test1(): mov rax, rdi ret My::Test2(): lea rax, [rdi+3] and rax, -4 ret Since https://reviews.llvm.org/D99790 Clang optimizes it: Although an int* might not actually point to a valid int, and so could be misaligned, and int& must be bound to a valid object, which means it cannot be misaligned. It would be undefined to bind a reference to a misaligned object. Similarly, although a My* could contain an arbitrary address, inside a member function the 'this' pointer must point to a valid object, which cannot be misaligned. It would be undefined to Pragmas and attributes and -fpack-struct=n can break those rules, but by default we should be able to assume they're true. This will break some code which has undefined behaviour (and would be diagnosed by -fsanitize=alignment) but currently "works" e.g. https://github.com/dotnet/runtime/issues/61671 was caused by the Clang change. So maybe there should be a specific flag to enable/disable this optimization, like we do for -fdelete-null-pointer-checks etc.