// #target: macos-x64

module test;

extern fn void printf(char*, ...);

fn void retest(foo...)
{
    test(...foo);
}
fn void test(foo...)
{
    printf("Foo1 was: %d\n", *((int*)foo[0]));
}
fn int main()
{
    int i = 1;
    test(1);
    retest(1);
    return 1;
}

/* #expect: test.ll

@"$ct.int" = linkonce global %.introspect { i8 2, i64 0, ptr null, i64 4, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8

define void @test.retest(ptr %0, i64 %1) #0 {
entry:
  %foo = alloca %"any[]", align 8
  store ptr %0, ptr %foo, align 8
  %ptradd = getelementptr inbounds i8, ptr %foo, i64 8
  store i64 %1, ptr %ptradd, align 8
  %lo = load ptr, ptr %foo, align 8
  %ptradd1 = getelementptr inbounds i8, ptr %foo, i64 8
  %hi = load i64, ptr %ptradd1, align 8
  call void @test.test(ptr %lo, i64 %hi)
  ret void
}

; Function Attrs:
define void @test.test(ptr %0, i64 %1) #0 {
entry:
  %foo = alloca %"any[]", align 8
  store ptr %0, ptr %foo, align 8
  %ptradd = getelementptr inbounds i8, ptr %foo, i64 8
  store i64 %1, ptr %ptradd, align 8
  %2 = load ptr, ptr %foo, align 8
  %3 = load ptr, ptr %2, align 8
  %4 = load i32, ptr %3, align 4
  call void (ptr, ...) @printf(ptr @.str, i32 %4)
  ret void
}

; Function Attrs:
define i32 @main() #0 {
entry:
  %i = alloca i32, align 4
  %varargslots = alloca [1 x %any], align 16
  %taddr = alloca i32, align 4
  %varargslots1 = alloca [1 x %any], align 16
  %taddr2 = alloca i32, align 4
  store i32 1, ptr %i, align 4
  store i32 1, ptr %taddr, align 4
  %0 = insertvalue %any undef, ptr %taddr, 0
  %1 = insertvalue %any %0, i64 ptrtoint (ptr @"$ct.int" to i64), 1
  store %any %1, ptr %varargslots, align 16
  call void @test.test(ptr %varargslots, i64 1)
  store i32 1, ptr %taddr2, align 4
  %2 = insertvalue %any undef, ptr %taddr2, 0
  %3 = insertvalue %any %2, i64 ptrtoint (ptr @"$ct.int" to i64), 1
  store %any %3, ptr %varargslots1, align 16
  call void @test.retest(ptr %varargslots1, i64 1)
  ret i32 1
}