Earlier quoted context omitted.
This is documented as not working[1] in all but the most recent GCC versions. E.g. gcc-5.4 documents: > "The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well. See below." but gcc-6.2 documentation adds: > "When used as part of a typedef, the aligned attribute can both increase and decrease alignment, and specifying the packed attribute generates a warning." FWIW,…
Must have been supported for a while because this stuff is even used in Linux: #define __packed2__ __attribute__((packed, aligned(2))) /* * SystemV FS comes in two variants: * sysv2: System V Release 2 (e.g. Microport), structure elements aligned(2). * sysv4: System V Release 4 (e.g. Consensys), structure elements aligned(4). */ struct sysv2_super_block { __fs16 s_isize; /* index of first data zone */ __fs32 s_fsize…
A bug story: data alignment on x86
71–80 of 111 posts
Re: A bug story: data alignment on x86
#72Note that even if you try to manually correct the pointer to work on aligned data (read any initial bytes via char pointer and read the rest via uint32_t pointer), you still generally have undefined behavior: strict-aliasing violation. And the worst thing here is that whether you do have a violation depends on how other code accesses the same data / how the object is initially declared. E.g., you're fine if the origi…
Re: A bug story: data alignment on x86
#73Earlier quoted context omitted.
Must have been supported for a while because this stuff is even used in Linux: #define __packed2__ __attribute__((packed, aligned(2))) /* * SystemV FS comes in two variants: * sysv2: System V Release 2 (e.g. Microport), structure elements aligned(2). * sysv4: System V Release 4 (e.g. Consensys), structure elements aligned(4). */ struct sysv2_super_block { __fs16 s_isize; /* index of first data zone */ __fs32 s_fsize…
Note the use of `packed`. `packed` causes the alignment to be set as small as possible (1 byte). The aligned(2) that follows then increases the alignment from 1 byte to 2 bytes.
Re: A bug story: data alignment on x86
#74Earlier quoted context omitted.
Have you actually tried and verified that? Reading the docs I've had an impression that it says that the "aligned" is for the alignment inside of the structures , and you here declare the simple type?
I wouldn't have posted this without checking. And as far as documentation goes, they say this attribute applies to "types" and the example they give is struct S { short f[3]; } __attribute__ ((aligned (8))); where it actually is used outside of a struct so that this whole 6B thing is aligned to 8B instead of the default 2B.
.L13:
movdqa (%r8), %xmm2
...Re: A bug story: data alignment on x86
#75Note that even if you try to manually correct the pointer to work on aligned data (read any initial bytes via char pointer and read the rest via uint32_t pointer), you still generally have undefined behavior: strict-aliasing violation. And the worst thing here is that whether you do have a violation depends on how other code accesses the same data / how the object is initially declared. E.g., you're fine if the origi…
http://cellperformance.beyond3d.com/articles/2006/06/underst...
Re: A bug story: data alignment on x86
#76Earlier quoted context omitted.
I wouldn't have posted this without checking. And as far as documentation goes, they say this attribute applies to "types" and the example they give is struct S { short f[3]; } __attribute__ ((aligned (8))); where it actually is used outside of a struct so that this whole 6B thing is aligned to 8B instead of the default 2B.
Thanks! Are you able to post how the generated asm of their innermost loop looks like with SSE2 turned on? I mean the equivalent of theirs .L13: movdqa (%r8), %xmm2 ...
Re: A bug story: data alignment on x86
#77Earlier quoted context omitted.
The correct and portable solution is to not use uint32_t, but to use uint8_t, and construct the integers manually.
Well, portable except for `uint8_t` not being guaranteed to exist. =)
At least that would be a failure at compile-time, rather than run-time.
Re: A bug story: data alignment on x86
#78Compiler is allowed to assume alignment of pointers (what are you doing is creating a pointer to a value with invalid alignment, hence undefined behaviour (just creating a pointer is undefined behaviour)). The correct solution would be to read values indirectly. For example, a function like that could be used to replace every access to "q" variable. static uint32_t read(const char *p, size_t index) { uint32_t out; me…
static uint32 read(const void *ptr) {
const uint8 *b = (const uint8 *)ptr;
return (b[3] Re: A bug story: data alignment on x86
#79I suggest this because it would be portable without any compiler specific stuff.