// #target: macos-x64

module struct2;

// <{ i64, i8, [3 x i8] }>
struct Foo1 @packed @align(4)
{
    long bar;
    char foo;
}

$assert Foo1.sizeof == 12;
Foo1 foo1 = { 1, 2 };

// <{ i8, i64, [3 x i8] }>
struct Foo2 @packed @align(4)
{
    char foo;
    long bar;
}

$assert Foo2.sizeof == 12;
Foo2 foo2 = { 1, 2 };

// <{ i8, i64, [7 x i8] }>
struct Foo3 @packed @align(8)
{
    char foo;
    long bar;
}

Foo3 foo3 = { 1, 2 };
$assert Foo3.sizeof == 16;

// <{ i8, i64 }>
struct Foo4 @packed
{
    char foo;
    long bar;
}

$assert Foo4.sizeof == 9;
Foo4 foo4 = { 1, 2 };

// { i32, [12 x i8], i8, [15 x i8] }
struct Foo5
{
    int bar @align(16);
    ichar foo @align(16);
}

$assert Foo5.sizeof == 32;
Foo5 foo5 = { 1, 2 };

fn int test5(ichar x)
{
    Foo5 y = { .foo = x };
    return y.foo + y.bar;
}

// <{ i32, i16, i16 }>
struct Foo6 @packed
{
    int a;
    short b;
    short c;
}

$assert Foo6.sizeof == 8;
Foo6 foo6 = { 1, 2, 3 };

/* #expect: struct2.ll

%Foo1 = type <{ i64, i8, [3 x i8] }>
%Foo2 = type <{ i8, i64, [3 x i8] }>
%Foo3 = type <{ i8, i64, [7 x i8] }>
%Foo4 = type <{ i8, i64 }>
%Foo5 = type { i32, [12 x i8], i8, [15 x i8] }
%Foo6 = type <{ i32, i16, i16 }>

@struct2.foo1 = local_unnamed_addr global %Foo1 <{ i64 1, i8 2, [3 x i8] undef }>, align 4
@struct2.foo2 = local_unnamed_addr global %Foo2 <{ i8 1, i64 2, [3 x i8] undef }>, align 4
@struct2.foo3 = local_unnamed_addr global %Foo3 <{ i8 1, i64 2, [7 x i8] undef }>, align 8
@struct2.foo4 = local_unnamed_addr global %Foo4 <{ i8 1, i64 2 }>, align 1
@struct2.foo5 = local_unnamed_addr global %Foo5 { i32 1, [12 x i8] undef, i8 2, [15 x i8] undef }, align 16
@struct2.foo6 = local_unnamed_addr global %Foo6 <{ i32 1, i16 2, i16 3 }>, align 1

define i32 @struct2.test5(i8 signext %0) #0 {
entry:
  %y = alloca %Foo5, align 16
  call void @llvm.memset.p0.i64(ptr align 16 %y, i8 0, i64 32, i1 false)
  %ptradd = getelementptr inbounds i8, ptr %y, i64 16
  store i8 %0, ptr %ptradd, align 16
  %ptradd1 = getelementptr inbounds i8, ptr %y, i64 16
  %1 = load i8, ptr %ptradd1, align 16
  %sext = sext i8 %1 to i32
  %2 = load i32, ptr %y, align 16
  %add = add i32 %sext, %2
  ret i32 %add
}
