x86/64 alignment, optimization, -Wcast-align

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

According to this:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65709#c17
GCC is assuming (according to the C standard) accesses through
pointers must have correct alignment, otherwise it is undefined
behaviour. Based on this, when certain optimizations are enabled (like
vectorization with avx2), GCC is allowed to generate code which may
crash even if the machine would allow unaligned access in general,
like x86/64.

There is a switch, -Wcast-align:
"Warn whenever a pointer is cast such that the required alignment of
the target is increased. For example, warn if a char * is cast to an
int * on machines where integers can only be accessed at two- or
four-byte boundaries."

However, this switch does not warn on x86/64. Which is becoming
problematic, as according to the comment on the bug above, GCC takes
alignment seriously, so even on x86/64, where unaligned access in
general (for int, etc.) is allowed, it becomes disallowed, as GCC
takes the C standard first.

I recently have been bitten by this with GCC 6.2. And yes, according
to the C standard, I wrote buggy code, which accessed a char* array,
through casting to an int*, and the memory turned out to be unaligned,
and as GCC vectorized it on the assumption (according to the C
standard) that int* must have proper alignment, it crashed, but only
with -O3 and avx2 turned on, and only in cases where the memory I got
was unaligned (memory comes from outside, I write a module, I do not
allocate the memory).

I believe -Wcast-align should be made to warn on x86/64 as well, in
the light of the above, as now it is the most dangerous territory,
where you only get crashes if the compiler decides to vectorize code
AND you get unaligned memory (the crash I got was VERY hard to
reproduce).

The problem I see is a conflict between the C standard (accesses must
be aligned for int, etc.) and the x86/64 machine (accesses need not be
aligned for int, etc.), and GCC optimizations using the former, while
the warning flag (-Wcast-align) taking the latter.

I would like more comments, ideas on this in general as well.
Also, ideas on given things like:

char* cmemory = ...; /* coming from outside */
int* imemory = (int*) cmemory;

how can we safely access imemory on x86/64 without getting bitten by
vectorization on x86/64.

The above is for x86/64 only.

Greets,
Balázs




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux