Clang/LLVM is much better at SLP autovectorisation than MSVC and GCC, so when compiling for an architecture that has vector instructions, they'll appear a lot in straight-line code even if it's not got any loops and isn't doing any maths. AMD64 guarantees that SSE2 instructions are available, so they get emitted. As an example, the vsg::Options default constructor uses an SSE2 128-bit move (specifically MOVAPS) to zero-initialise two consecutive pointers in one of its std::map members. This instruction requires its target address to be aligned to a 16 byte boundary, and because alignof(vsg::Options) is 16, that's guaranteed by the language...
Except the VSG allocator still uses eight byte alignment by default, so when it's used to allocate storage for vsg::Options, it can be misaligned, and its constructor explodes because an instruction operates on an illegal address.
Either the default alignment needs increasing to sixteen (and we need to hope that the VSG allocator is never used for a type with a wider alignment and that Clang never notices that and attempts to use a wider vector instruction that requires stronger alignment), or the allocator needs to start respecting alignof(WhateverTypeItIsAllocatingStorageFor).
This problem is widespread enough that none of the VSG examples that construct any VSG types launch when compiled with a recent version of Clang on my machine. This is likely related to the Arm MacOS crashes that prompted the alignment being increased from four to eight as Macs use (Apple's fork of an old version of) Clang, although there are some minor details around why eight was enough that I've not dug into - ARM NEON SIMD instructions support eight-byte alignment, but go faster when given a flag to expect sixteen-byte alignment, which I'd expect Clang to use if it thought it could rely on that like it does on AMD64. Possibly it's just one of the quirks of Apple's implementation that it doesn't abort if the alignment hint is incorrect.
Clang/LLVM is much better at SLP autovectorisation than MSVC and GCC, so when compiling for an architecture that has vector instructions, they'll appear a lot in straight-line code even if it's not got any loops and isn't doing any maths. AMD64 guarantees that SSE2 instructions are available, so they get emitted. As an example, the
vsg::Optionsdefault constructor uses an SSE2 128-bit move (specificallyMOVAPS) to zero-initialise two consecutive pointers in one of itsstd::mapmembers. This instruction requires its target address to be aligned to a 16 byte boundary, and becausealignof(vsg::Options)is16, that's guaranteed by the language...Except the VSG allocator still uses eight byte alignment by default, so when it's used to allocate storage for
vsg::Options, it can be misaligned, and its constructor explodes because an instruction operates on an illegal address.Either the default alignment needs increasing to sixteen (and we need to hope that the VSG allocator is never used for a type with a wider alignment and that Clang never notices that and attempts to use a wider vector instruction that requires stronger alignment), or the allocator needs to start respecting
alignof(WhateverTypeItIsAllocatingStorageFor).This problem is widespread enough that none of the VSG examples that construct any VSG types launch when compiled with a recent version of Clang on my machine. This is likely related to the Arm MacOS crashes that prompted the alignment being increased from four to eight as Macs use (Apple's fork of an old version of) Clang, although there are some minor details around why eight was enough that I've not dug into - ARM NEON SIMD instructions support eight-byte alignment, but go faster when given a flag to expect sixteen-byte alignment, which I'd expect Clang to use if it thought it could rely on that like it does on AMD64. Possibly it's just one of the quirks of Apple's implementation that it doesn't abort if the alignment hint is incorrect.