-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
There is no syntax for struct alignment #325
Comments
welp, I can't edit this one. - The only way to hack around this is to build a same-sized type out of SIMD types and transmute it when necessary.
+ The only way to hack around this is to prepend your struct with a zero-length array of a SIMD type. |
@edef1c I updated it for you. |
@edef1c it's information added to each load/store/manipulation, it's not an inherent property of the LLVM "type", e.g. struct Foo {
int x;
} __attribute__((__aligned__(1024)));
struct Foo f(struct Foo x) {
struct Foo y;
return x;
} compiles to ( ; ModuleID = 'alignment.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
%struct.Foo = type { i32, [1020 x i8] }
; Function Attrs: nounwind uwtable
define void @f(%struct.Foo* noalias sret %agg.result, %struct.Foo* byval align 1024 %x) #0 {
%y = alloca %struct.Foo, align 1024
%1 = bitcast %struct.Foo* %agg.result to i8*
%2 = bitcast %struct.Foo* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* %2, i64 1024, i32 1024, i1 false)
ret void
}
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #1
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind } |
See also rust-lang/rust#4578 |
@huonw Yep, I discovered that — though Clang seems to get it horribly wrong for my struct (an array of internal align(64) structs has padding /next/ to it — gcc gets it right though) |
The information added to the loads / stores / parameters is just an optimization. |
Idly, it would be convenient for some usecases if the checks done for transmute (statically verifying that its two type parameters have the same alignment and size) would be useful in some cases for custom allocators (both would be independently useful, actually--in the case I'm thinking of I would only care about alignment). Then instead of requiring the allocator to track the different size class / aligment pools at runtime, you could explicitly allocate a pool with the class you needed and safely verify it at compile time. It would also allow transmute to be used on types with type parameters as long as they could be bounded to have the same size and alignment. I guess such a type would require associated constants in order to be representable, though. Right now there's no way to provide an interface like this without requiring the client to use unsafe code to transmute his or her type. Looking up, it seems like this has more to do with the closed issue (rust-lang/rust#4578) than this one. |
I'd like to mention that in some cases the workaround of using a simd type doesn't work. For example in Windows API where some types will have packing specified to be 2, which is greater than what I'd get with |
Stream::chain
It would also be nice to have something similar to C++’s |
Does #1358 not fulfill the needs of this? Or is there something more (besides that RFC) that needs to be implemented in order to close this issue? |
@Mark-Simulacrum I don't believe it's possible to write |
You could always do that with |
@eddyb Had no idea that was possible. Thanks! Edit: Still need a way to declare an array of |
@Mark-Simulacrum I believe #1358 did solve the issue. Still waiting for the feature to stabilize, but it does at least exist. |
With #1358 merged, I'm going to close this to reduce issue volume. Comment if you disagree! |
Issue by edef1c
Thursday Sep 25, 2014 at 18:20 GMT
For earlier discussion, see rust-lang/rust#17537
This issue was labelled with: in the Rust repository
Currently, a C struct definition including an alignment hint (
ALIGN(64)
) cannot be translated to Rust.Our inability to translate this makes some C ABIs impossible to adhere to, causing crashes and undefined behaviour.
The only way to hack around this is to prepend your struct with a zero-length array of a SIMD type.
We should have some kind of syntax for this. Perhaps
#[align(64)]
?@eddyb proposed
#[repr(align(64))]
, but I fear that complicates therepr
attribute a bit much.The text was updated successfully, but these errors were encountered: