https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93031
Bug ID: 93031 Summary: Wish: When the underlying ISA does not force pointer alignment, option to make GCC not assume it Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pascal_cuoq at hotmail dot com Target Milestone: --- GCC assumes that pointers must be aligned as part of its optimizations, even if the ISA does not force it (for instance, x86-64 without the vector instructions). The present feature wish as for an option to make it not make this assumption. Since the late 1990s, GCC has been adding optimizations based on undefined behavior, and “breaking” existing C programs that used to “work” by relying on the assumption that since they were compiled for architecture X, they would be fine. The reasonable developers have been kept happy by giving them options to preserve the old behavior. These options are -fno-strict-aliasing, -fwrapv, ... and I think there should be another one. In 2016, Pavel Zemtsov showed that a C program that was written assuming that misaligned pointer accesses are allowed could be compiled by GCC to code that did not work as intended: http://pzemtsov.github.io/2016/11/06/bug-story-alignment-on-x86.html This was an interesting development, but GCC's behavior was fair: Pavel had not disabled the vector instructions, GCC had automatically inserted these instructions in the generated code, so the target architecture was not really one that allowed all misaligned pointer accesses. Using -mno-sse would have fixed the behavior. I have recently noticed that since at least version 8.1, GCC assumes that all pointers are aligned even when the target ISA really has no such restriction. This can be seen by compiling the two functions below (Compiler Explorer link: https://gcc.godbolt.org/z/UBBD2Y ) int h(int *p, int *q){ *p = 1; *q = 1; return *p; } typedef __attribute__((__may_alias__)) int I; I k(I *p, I *q){ *p = 1; *q = 1; return *p; } Compiling with GCC 8.1 or 9.2, with either the options “-O2” or “-O2 -fno-strict-aliasing”, GCC generates code that assumes that the functions will always return 1. It does so because it assumes both p and q to be aligned pointers. I would like to have an option in order to make it not make this assumption. (This feature wish is not related to strict aliasing. I have only used the option and the attribute in order to show that the optimization at play here is not related to strict aliasing, and that there is currently no documented way (that I know of) to disable it after having passed “-O2”.) A context in which the functions are called may be: int main(void) { char t[6]; return h((int*)t, (int*)(t+2)); } This context violates strict aliasing, but when using __attribute__((__may_alias__)) or -fno-strict-aliasing, this should not be relevant. The idea here would be to have an option to keep legacy code that used to work working. Modern C code should probably use memcpy to access sequences of bytes that are to be treated as a word but may not be aligned in memory, since both Clang and GCC usually makes these memcpy free. This feature wish is partially related to the bug report about packed structs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628 which ended with the addition of a new warning -Waddress-of-packed-member, but it is concerned with architectures on which misaligned accesses are allowed, not with architectures on which they are not.