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

128-bit integers are underaligned on x86-64 #13609

Open
HertzDevil opened this issue Jun 29, 2023 · 1 comment · May be fixed by #14310
Open

128-bit integers are underaligned on x86-64 #13609

HertzDevil opened this issue Jun 29, 2023 · 1 comment · May be fixed by #14310

Comments

@HertzDevil
Copy link
Contributor

HertzDevil commented Jun 29, 2023

Consider the following:

@[Extern]
struct Foo
  @x = 0_i64
  @y = 0_i128
end

foo = Foo.new
pointerof(foo.@x) # => Pointer(Int128)@0x7fffd4e08e60
pointerof(foo.@y) # => Pointer(Int128)@0x7fffd4e08e68
offsetof(Foo, @y) # => 8
sizeof(Foo)       # => 24
alignof(Foo)      # => 8

Instead, the address of foo.@y should end with a 0 instead, offsetof(Foo, @y) should be 16, sizeof(Foo) should be 32, and alignof(Foo) should be 16. Underalignment could lead to suboptimal code generation or totally incorrect lib bindings.

This is known to happen on x86-64 Windows and Linux. The Apple M2 (AArch64) does not have this issue:

pointerof(foo.@x) # => Pointer(Int64)@0x16f6d3340
pointerof(foo.@y) # => Pointer(Int128)@0x16f6d3350
offsetof(Foo, @y) # => 16
sizeof(Foo)       # => 32
alignof(Foo)      # => 16
@HertzDevil
Copy link
Contributor Author

HertzDevil commented Jan 30, 2024

This is fixed in LLVM 18, however alignof(Foo | Int32) or even alignof(Foo | Int128) is still 8, since the data storage for mixed unions has the same alignment as size_t:

llvm_value_type = size_t.array(max_size)
[@llvm_context.int32, llvm_value_type]

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

Successfully merging a pull request may close this issue.

1 participant