[arm][RFC] PR target/88469 fix incorrect argument passing with 64-bit bitfields
Richard Earnshaw (lists)
Richard.Earnshaw@arm.com
Thu Feb 28 13:18:00 GMT 2019
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.
More information about the Gcc-patches
mailing list