(Sorry in advance for not having managed to reduce my problem to a simple failing test case...)
I have faced issues with upgrading to GCC 6.3.0 to build our codebase (relevant flags: -O3 -m32
).
Specifically, my application segfaults within a struct ctor call because of GCC optimizations.
In this ctor, GCC used movaps
:
movaps %xmm0,0x30a0(%ebx)
movaps
requires the operand to be 16-byte aligned. But at this point in time, %ebx
points to my object, which is not necessarily 16-byte aligned. From glibc :
“The address of a block returned by malloc or realloc in GNU systems is always a multiple of eight (or sixteen on 64-bit systems).“
Hence the segfault (when built with -O3 -m32
).
Why does it seem like GCC assumed the allocated object would be 16-byte aligned ? Am I misunderstanding something ?
Notes:
- No alignment hints or attributes on this struct
- Object has been initialized via default
new
operator - Depends on the level of optimization:
- PASS:
-m32 -O2
- FAIL:
-m32 -O2 -ftree-slp-vectorize
- PASS:
-m32 -O3 -fno-tree-slp-vectorize
- FAIL:
-m32 -O3
- PASS:
This other project, seem to have hit similar issues : https://github.com/godotengine/godot/issues/4623
Their investigation points to -fvect-cost-model=dynamic
. Investigation on my codebase rather points to -ftree-slp-vectorize
.
alignof
on your object would tell you what alignment the compiler thinks it needs. Sounds like it should not be ≥16, but would hurt to check. – Skinkalignof==16
but that would mean you couldn't use glibc'smalloc
. Then again, the Standard restricts the implementation'smalloc
, not the OS'esmalloc
. GCC might need to wrap glibc. (Which I think should be done anyway) – Orthostichyalignof
returns64
.alignof(max_align_t)
returns8
(expected). There is no user requirement on alignment on either the object or its members; why wouldalignof
be64
? I am not usingmalloc
directly but assumed thatnew
was using it. – Punishalignof==64
on the whole thing. And it also means, as both @Skink and @Orthostichy pointed out, that I cannot use 8-byte alignednew
. Used to work by chance with previous versions and lesser optimizations because GCC was not taking advantage of the overall alignment... – Punish