mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-24 05:51:34 +00:00
simd fix; generator fix
This commit is contained in:
@@ -726,13 +726,19 @@ namespace lbAbiAmd64SysV {
|
||||
gb_internal bool is_aggregate(LLVMTypeRef type) {
|
||||
// A single-member wrapper is passed like its member, but only while that
|
||||
// member still fits one eightbyte. `struct{i128}` needs two registers and
|
||||
// goes to memory when they are gone, where a bare `i128` does not -- clang
|
||||
// emits `byval align 16` for the struct and a plain `i128` for the scalar.
|
||||
// goes to memory when they are gone. A bare `i128` does not; clang emits
|
||||
// `byval align 16` for the struct and a plain `i128` for the scalar.
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMStructTypeKind:
|
||||
if (LLVMCountStructElementTypes(type) == 1) {
|
||||
LLVMTypeRef elem = LLVMStructGetTypeAtIndex(type, 0);
|
||||
// A VECTOR member keeps the wrapper an aggregate whatever its size:
|
||||
// LLVM gives a vector its own oversized stack slot, so an unwrapped
|
||||
// `struct{#simd[2]f32}` takes 16 bytes where the ABI wants 8.
|
||||
if (LLVMGetTypeKind(elem) == LLVMVectorTypeKind) {
|
||||
return true;
|
||||
}
|
||||
return lb_sizeof(elem) > 8 || is_aggregate(elem);
|
||||
}
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user