On 27/01/2019 11:20, Bernd Edlinger wrote: > Hi, > > I know I am a bit late on the party.
Sorry for the delay replying, I've been off sick... > > But I have a question... > > Consider this test case: > > $ cat test.c > struct s { > int a, b; > } __attribute__((aligned(8))); > > struct s f0; > int f(int a, int b, int c, int d, int e, struct s f) > { > f0 = f; > return __alignof(f); This is equivalent to writing __alignof (struct s), so the returned value should be 8. HOWEVER, f itself is just a value in terms of the PCS, so it is correct for it to be passed at SP+4. > } > > $ arm-linux-gnueabihf-gcc -march=armv5te -O3 -S test.c > $ cat test.s > f: > @ args = 12, pretend = 0, frame = 0 > @ frame_needed = 0, uses_anonymous_args = 0 > @ link register save eliminated. > push {r4, r5} > mov r0, #8 > ldrd r4, [sp, #12] So this is wrong; before the compiler can use 'f' it has to copy it to a suitably aligned location; it can't directly reuse the value on the stack as that is not sufficiently aligned for the type. > ldr r3, .L4 > strd r4, [r3] > pop {r4, r5} > bx lr > > I am pretty sure, although there is no warning, this ABI changed in GCC 5.2 There was no explicit ABI for overaligned types in the past; so anything could have happened. > > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0473m/dom1361290002364.html > says: > > "In ARMv5TE, or in ARMv6 when SCTLR.U is 0, LDRD and STRD doubleword data > transfers must be > eight-byte aligned. Use ALIGN 8 before memory allocation directives such as > DCQ if the data > is to be accessed using LDRD or STRD. This is not required in ARMv6 when > SCTLR.U is 1, or in > ARMv7, because in these versions, doubleword data transfers can be > word-aligned." > > > So isn't this wrong code, returning 8 for alignof when it is really 4, > and wouldn't it crash on armv5 and armv6 with SCTLR.U=0 ? Returning 8 is correct; since that is the alignment of the type; but GCC does need to copy underaligned types to suitably aligned memory before it uses them; it must not use the *value* that is passed directly, unless it can prove that doing so is safe (and as you point out, on armv5 it is not). I think technically, this is separate bug from the PCS one that was fixed, so needs a new PR. > > > Bernd. > Thanks, R.