From e621a924f5da07064eade2f7c1497b4f8b8bda96 Mon Sep 17 00:00:00 2001 From: kalsprite Date: Thu, 13 Aug 2026 00:04:19 -0700 Subject: [PATCH] darwin align(16) max --- src/llvm_abi.cpp | 6 +++++- src/types.cpp | 7 ++++++- tests/abi/gen.py | 14 +++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 37df13b2c..07a86e05d 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -335,7 +335,11 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) { i64 elem_size = lb_sizeof(elem); i64 count = LLVMGetVectorSize(type); i64 size = count * elem_size; - return gb_clamp(next_pow2(size), 1, build_context.max_simd_align); + i64 max_align = build_context.max_simd_align; + if (build_context.metrics.os == TargetOs_darwin && build_context.metrics.arch == TargetArch_amd64) { + max_align = gb_min(max_align, 16); // see type_align_of_internal + } + return gb_clamp(next_pow2(size), 1, max_align); } } diff --git a/src/types.cpp b/src/types.cpp index 942917e30..dda2ea2a1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4527,7 +4527,12 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) { case Type_SimdVector: { // IMPORTANT TODO(bill): Figure out the alignment of vector types - return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.max_simd_align*2); + i64 max_align = build_context.max_simd_align*2; + if (build_context.metrics.os == TargetOs_darwin && build_context.metrics.arch == TargetArch_amd64) { + // Darwin guarantees only 16-byte stack alignment + max_align = gb_min(max_align, 16); + } + return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, max_align); } case Type_Matrix: diff --git a/tests/abi/gen.py b/tests/abi/gen.py index 4a9c86163..f372e5add 100644 --- a/tests/abi/gen.py +++ b/tests/abi/gen.py @@ -190,7 +190,10 @@ def build(): # --- nesting: same leaves reached through another level for a, b in (("f32", "f32"), ("f64", "f64"), ("i32", "f32"), ("f32", "i64"), - ("f16", "f16"), ("f16", "i32")): + ("f16", "f16"), ("f16", "i32"), + # a lone f32 in eightbyte 0 reached through a level, then an f64: + # the shape #7292 was about + ("f32", "f64")): add(f"n_{a}_{b}", f"struct {{ i: struct {{ x: {SCALARS[a][0]}, y: {SCALARS[b][0]} }} }}", f"struct {{ struct {{ {SCALARS[a][1]} x; {SCALARS[b][1]} y; }} i; }}", @@ -211,6 +214,13 @@ def build(): f"struct {{ u: struct #raw_union {{ x: {SCALARS[a][0]} }}, y: {SCALARS[b][0]} }}", f"struct {{ union {{ {SCALARS[a][1]} x; }} u; {SCALARS[b][1]} y; }}", [leaf("u.x", a, 0), leaf("y", b, 1)], tier=tier_of(a, b)) + # TWO members in the nested union. The one-member form above is the case + # overlap alone cannot detect; this is its control, and it is the shape + # `test_issue_sysv_abi` pins. + add(f"su2_{a}_{b}", + f"struct {{ u: struct #raw_union {{ x, y: {SCALARS[a][0]} }}, z: {SCALARS[b][0]} }}", + f"struct {{ union {{ {SCALARS[a][1]} x, y; }} u; {SCALARS[b][1]} z; }}", + [leaf("u.x", a, 0), leaf("z", b, 1)], tier=tier_of(a, b)) # --- homogeneous float aggregates and the shapes that disqualify them for tag in ("f32", "f64", "f16"): @@ -477,6 +487,7 @@ ABI_MUTATE :: #config(ABI_MUTATE, false) ABI_VARARGS :: #config(ABI_VARARGS, false) + E32 :: enum i32 { LO = 0, HI = 0x7fffffff } BS :: bit_set[0..<31; u32] @@ -635,6 +646,7 @@ ABI_SKIP :: #config(ABI_SKIP, 0) ABI_VARARGS :: #config(ABI_VARARGS, false) + foreign import lib "../abi_corpus_c.o" """