-
-
Notifications
You must be signed in to change notification settings - Fork 253
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
Introduce DtoAlignment() and overload DtoAlloca() for VarDeclarations #1159
Conversation
Trying to get the alignment right by using the first non-default one in the following order of descending priority: VarDeclaration::alignment [variables only of course] Type::alignment() Type::alignsize() This fixes `align(x) struct S { ... }`.
An error in struct Buggy
{
align(1):
uint a = 0x0a0a0a0a;
ulong b = 0x0b0b0b0b0b0b0b0b;
} The offset is computed correctly in Buggy packed;
ulong raw = *cast(ulong*)(cast(ubyte*)&packed + packed.b.offsetof); and the LL type Anyway, with this PR, the size used when initializing Oh, I've just noted that the upstream IR uses a slightly different type: |
We need the type's natural alignment for that.
To verify the PR, it's useful to inspect the generated .ll for: align(16) struct Struct { int[2] a; }
struct S { align(16) int a; }
void main()
{
align(32) int[2] x;
align(32) Struct s;
S s2;
//void foo() { x[0] = 666; s.a[0] = 123; }
//foo();
} => %align.Struct = type { [2 x i32], [8 x i8] }
%align.S = type { i32, [12 x i8] }
...
%x = alloca [2 x i32], align 4 ; [#uses = 1, size/byte = 8]
%s = alloca %align.Struct, align 16 ; [#uses = 2, size/byte = 16]
%s2 = alloca %align.S, align 16 ; [#uses = 1, size/byte = 16] When uncommenting %nest.main = type { [2 x i32], [8 x i8], %align.Struct }
...
%.frame = alloca %nest.main, align 16 ; [#uses = 3, size/byte = 32]
%s2 = alloca %align.S, align 16 ; [#uses = 1, size/byte = 16]
%x = getelementptr %nest.main, %nest.main* %.frame, i32 0, i32 0 ; [#uses = 1, type = [2 x i32]*]
%s = getelementptr %nest.main, %nest.main* %.frame, i32 0, i32 2 ; [#uses = 1, type = %align.Struct*]
... in foo():
%s = getelementptr %nest.main, %nest.main* %5, i32 0, i32 2 ; [#uses = 1, type = %align.Struct*] What's still not working is the explicit alignment for local variables, i.e., |
https://github.com/ldc-developers/phobos/blob/ldc/std/conv.d#L5105 fails due to an insufficiently aligned (1-bytes on IR level, 4 bytes on the Travis boxes) static byte[] array when trying to emplace a class instance in it (8-bytes aligned). I need to fix the alignment of these globals. |
…obals This is apparently assumed by a std.conv unittest. Using DtoAlignment() here instead of checking for an explicit vd->alignment != STRUCTALIGN_DEFAULT is not only nice for consistency, but also leads to a `struct S { align(16) int a; }` global being correctly aligned on a 16-bytes boundary. The struct itself has no explicit alignment, but alignsize() is 16; so the upstream code doesn't set any explicit alignment for the global.
Wrt. the locals, I assumed their |
Introduce DtoAlignment() and overload DtoAlloca() for VarDeclarations
No tests? I just tried to translate _mm_loadu_ps to D, but the compiler keeps using an aligned load. import core.simd, ldc.simd;
align(1) struct Float4
{
align(1) float4 v;
}
float4 test(float* ptr)
{
return (cast(Float4*)ptr).v;
} |
@MartinNowak Tests are here: https://github.com/ldc-developers/ldc/blob/master/tests/codegen/align.d (there are some "CHECK" things in that testfile (disabled tests), about which there should be a D language discussion) |
@MartinNowak Could you report a new issue for this? |
Trying to get the alignment right by using the first non-default one in the following order of descending priority:
VarDeclaration::alignment
[variables only of course]Type::alignment()
Type::alignsize()
This fixes the alignment of
align(x) struct S { ... }
instances on the stack.Local variables with an explicit align attribute are still default-aligned though. :/