Skip to content
This repository was archived by the owner on Jun 19, 2026. It is now read-only.

Commit 698f10b

Browse files
committed
llvm: lower array params as aggregate byval
1 parent eee6f6a commit 698f10b

3 files changed

Lines changed: 30 additions & 1 deletion

File tree

internal/backend/llvm/link.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ func FunctionReturnIsScalar(fn *mir.Function) bool {
110110
// Returns an error for aggregate (named struct) types.
111111
func llvmBaseType(typ typeinfo.Type) (string, error) {
112112
switch base := backend.UnwrapNamed(typ).(type) {
113+
case *typeinfo.ApproxType:
114+
return llvmBaseType(base.Inner)
113115
case *typeinfo.BuiltinType:
114116
if _, bits, ok := tokens.ParseIntegerBuiltin(base.Name); ok {
115117
return fmt.Sprintf("i%d", bits), nil

internal/backend/llvm/llvm.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5590,7 +5590,10 @@ func llvmFieldType(state *moduleState, typ typeinfo.Type) (string, error) {
55905590

55915591
// llvmABITypeName returns the LLVM type name for function signatures, calls, globals.
55925592
func llvmABITypeName(state *moduleState, typ typeinfo.Type) (string, error) {
5593-
if _, ok := backend.UnwrapNamed(typ).(*typeinfo.TupleType); ok {
5593+
switch t := backend.UnwrapNamed(typ).(type) {
5594+
case *typeinfo.ApproxType:
5595+
return llvmABITypeName(state, t.Inner)
5596+
case *typeinfo.TupleType, *typeinfo.ArrayType:
55945597
size, _, err := backend.AggregateSizeAlign(aggregateLayoutContext(state), typ)
55955598
if err != nil {
55965599
return "", err

internal/backend/llvm/lower_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,30 @@ fn main(items: []i32) -> usize {
13621362
}
13631363
}
13641364

1365+
func TestLowerProgramFunctionArrayParamUsesByValAggregate(t *testing.T) {
1366+
root := t.TempDir()
1367+
mustWrite(t, filepath.Join(root, "main.fer"), `
1368+
fn add(values: [2]i32) -> i32 {
1369+
return values[0] + values[1]
1370+
}
1371+
1372+
fn main() -> i32 {
1373+
return add([2]i32{1, 2})
1374+
}
1375+
`)
1376+
result := compiler.ParsePath(filepath.Join(root, "main.fer"))
1377+
if result.Diagnostics.HasErrors() {
1378+
t.Fatalf("unexpected diagnostics: %#v", result.Diagnostics.Diagnostics())
1379+
}
1380+
text, err := llvmbackend.LowerProgram(testUnits(result), false)
1381+
if err != nil {
1382+
t.Fatalf("lower llvm: %v", err)
1383+
}
1384+
if !strings.Contains(text, "define i32 @main__add(ptr byval([8 x i8]) align 4 %values)") {
1385+
t.Fatalf("expected array parameter lowered as byval aggregate:\n%s", text)
1386+
}
1387+
}
1388+
13651389
func TestLowerBuiltinLenStringToLLVM(t *testing.T) {
13661390
root := t.TempDir()
13671391
mustWrite(t, filepath.Join(root, "main.fer"), `

0 commit comments

Comments
 (0)