Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect stack alignment of 16byte aligned aggregates on linux #3557

Open
MrSmith33 opened this issue Sep 7, 2020 · 1 comment
Open

Incorrect stack alignment of 16byte aligned aggregates on linux #3557

MrSmith33 opened this issue Sep 7, 2020 · 1 comment

Comments

@MrSmith33
Copy link
Contributor

MrSmith33 commented Sep 7, 2020

When struct is passed on the stack and alignment of struct is 16 bytes compiler does not align the struct properly. Here is a comparison between ldc, dmd and gcc. Both ldc and dmd miss the alignment.

https://godbolt.org/z/xKc8WK

D code:

align(16)
struct s { long a; }
extern(C) void foo(int, int, int, int, int, int, s, s);
void bar() {
    // push    10
    // push     7
    // call    foo@PLT
    foo(1,2,3,4,5,6, s(7),s(10));
}

C code:

struct __attribute__((aligned(16))) s { long a; };
void foo(int, int, int, int, int, int, s, s);
void bar() {
    // push     0
    // push    10
    // push     0
    // push     7
    foo(1,2,3,4,5,6, s{7},s{10});
}

However alignment starts to work if you replace 16 with 32.

https://godbolt.org/z/6r7GbW

dmd issue: https://issues.dlang.org/show_bug.cgi?id=21230

@kinke
Copy link
Member

kinke commented Sep 7, 2020

This is... problematic. The problem is https://github.com/dlang/dmd/blob/f3a588f41c63a1655fcb733c06ef08e152da0125/src/dmd/argtypes_sysv_x64.d#L399-L404, which I've analyzed back then with such a struct being passed as the first arg (i.e., in registers), where it only occupies one register, despite its padded size of 16 bytes. If it is spilled to the stack, it's pushed as full 16-bytes struct with appropriate alignment. So the toArgTypes machinery doesn't work well in this case, as it doesn't account for such special cases, where the passed payload size depends on the parameter position.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants