emit_llvm: bridge struct<->array ABI for 9..16-byte foreign structs
Resolves issue-0036 (LLVM verifier failure on 16-byte integer-only
struct by value through #foreign). The mismatch:
Call parameter type does not match function signature!
%load = load { i64, i64 }, ptr %alloca, align 8
[2 x i64] %call = call [2 x i64] @fn({ i64, i64 } %load)
`abiCoerceParamType` had already chosen `[2 x i64]` for 9..16-byte
non-HFA structs (the AAPCS64 / SysV AMD64 register-pair ABI slot for
that size class) on the foreign-decl side, but `coerceArg` only knew
how to bridge struct<->integer (the ≤8 B case) — not struct<->array.
LLVM's verifier rejects type-mismatched call args, so the call site
never landed.
Added the symmetric branches in coerceArg:
- Struct -> Array : alloca <array>; store <struct>; load <array>
- Array -> Struct : alloca <array>; store <array>; load <struct>
Both use the LLVM opaque-pointer memory-bitcast pattern already in
place for the integer case. They're paired with the existing
i64 <-> small-struct bridge so all four (≤8 B int, 9..16 B int,
16 B HFA, >16 B byval) ABI slots round-trip cleanly through
emit_llvm now.
File mechanics: promotes the issue-0036 repro to a focused feature
example per CLAUDE.md's issue-resolution workflow:
examples/issue-0036.sx -> examples/101-ffi-medium-struct.sx
tests/expected/issue-0036.{txt,exit} -> tests/expected/101-ffi-medium-struct.{txt,exit}
vendors/issue_0036/issue_0036.c -> vendors/ffi_medium_struct/ffi_medium_struct.c
Snapshot updated to the passing output. 89/89 regression tests pass;
chess Android build still clean.
This commit is contained in:
13
vendors/ffi_medium_struct/ffi_medium_struct.c
vendored
Normal file
13
vendors/ffi_medium_struct/ffi_medium_struct.c
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Companion to examples/101-ffi-medium-struct.sx — a single
|
||||
// roundtrip through a 16-byte integer-only struct. Pinned in a
|
||||
// dedicated example because integer aggregates in this size class
|
||||
// route through emit_llvm.zig's `[2 x i64]` ABI coercion slot, a
|
||||
// different path from the small (≤8 B) integer struct, the 16-byte
|
||||
// HFA, and the >16 B byval-pointer cases.
|
||||
|
||||
typedef struct { long long a; long long b; } Pair64;
|
||||
|
||||
Pair64 ffi_pair64_swap(Pair64 p) {
|
||||
Pair64 r = { p.b, p.a };
|
||||
return r;
|
||||
}
|
||||
Reference in New Issue
Block a user