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.

Reply via email to