// #target: macos-x64
module foo;

module foo;

bitstruct BitField3 : char[4] @bigendian
{
    uint c : 4..19;
}

bitstruct BitField4 : char[4]
{
    uint c : 4..19;
}

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

fn void main()
{
    test3();
}
fn void test3()
{
    //BitField3 xx = { 0xdeadbeef };
    BitField3 xx = { 0xbeaf };
    printf("%x = beaf\n", xx.c);
    BitField4 xy = { 0xbeaf };
    void *abc = &xy;
    char[4]* z = abc;
    printf("%x = beaf\n", xy.c);
    xy.c = 0xbeef;
    printf("%x = beef\n", xy.c);
    xx.c = 0xbeef;
    printf("%x = beef\n", xx.c);
}


/* #expect: foo.ll

define void @foo.test3() #0 {
entry:
  %xx = alloca [4 x i8], align 1
  %xy = alloca [4 x i8], align 1
  %abc = alloca ptr, align 8
  %z = alloca ptr, align 8
  store [4 x i8] c"\E0\FB\0A\00", ptr %xx, align 1
  %0 = load i8, ptr %xx, align 1
  %zext = zext i8 %0 to i32
  %lshrl = lshr i32 %zext, 4
  %ptradd = getelementptr inbounds i8, ptr %xx, i64 1
  %1 = load i8, ptr %ptradd, align 1
  %zext1 = zext i8 %1 to i32
  %shl = shl i32 %zext1, 4
  %2 = or i32 %shl, %lshrl
  %ptradd2 = getelementptr inbounds i8, ptr %xx, i64 2
  %3 = load i8, ptr %ptradd2, align 1
  %zext3 = zext i8 %3 to i32
  %shl4 = shl i32 %zext3, 12
  %4 = or i32 %shl4, %2
  %shl5 = shl i32 %4, 16
  %5 = call i32 @llvm.bswap.i32(i32 %shl5)
  %6 = and i32 65535, %5
  call void (ptr, ...) @printf(ptr @.str, i32 %6)
  store [4 x i8] c"\F0\EA\0B\00", ptr %xy, align 1
  store ptr %xy, ptr %abc, align 8
  %7 = load ptr, ptr %abc, align 8
  store ptr %7, ptr %z, align 8
  %8 = load i8, ptr %xy, align 1
  %zext6 = zext i8 %8 to i32
  %lshrl7 = lshr i32 %zext6, 4
  %ptradd8 = getelementptr inbounds i8, ptr %xy, i64 1
  %9 = load i8, ptr %ptradd8, align 1
  %zext9 = zext i8 %9 to i32
  %shl10 = shl i32 %zext9, 4
  %10 = or i32 %shl10, %lshrl7
  %ptradd11 = getelementptr inbounds i8, ptr %xy, i64 2
  %11 = load i8, ptr %ptradd11, align 1
  %zext12 = zext i8 %11 to i32
  %shl13 = shl i32 %zext12, 12
  %12 = or i32 %shl13, %10
  %13 = and i32 65535, %12
  call void (ptr, ...) @printf(ptr @.str.1, i32 %13)
  %14 = load i8, ptr %xy, align 1
  %15 = and i8 %14, 15
  %16 = or i8 %15, -16
  store i8 %16, ptr %xy, align 1
  %ptradd14 = getelementptr inbounds i8, ptr %xy, i64 1
  store i8 -18, ptr %ptradd14, align 1
  %ptradd15 = getelementptr inbounds i8, ptr %xy, i64 2
  %17 = load i8, ptr %ptradd15, align 1
  %18 = and i8 %17, -16
  %19 = or i8 %18, 11
  store i8 %18, ptr %ptradd15, align 1
  %20 = load i8, ptr %xy, align 1
  %zext16 = zext i8 %20 to i32
  %lshrl17 = lshr i32 %zext16, 4
  %ptradd18 = getelementptr inbounds i8, ptr %xy, i64 1
  %21 = load i8, ptr %ptradd18, align 1
  %zext19 = zext i8 %21 to i32
  %shl20 = shl i32 %zext19, 4
  %22 = or i32 %shl20, %lshrl17
  %ptradd21 = getelementptr inbounds i8, ptr %xy, i64 2
  %23 = load i8, ptr %ptradd21, align 1
  %zext22 = zext i8 %23 to i32
  %shl23 = shl i32 %zext22, 12
  %24 = or i32 %shl23, %22
  %25 = and i32 65535, %24
  call void (ptr, ...) @printf(ptr @.str.2, i32 %25)
  %26 = load i8, ptr %xx, align 1
  %27 = and i8 %26, 15
  %28 = or i8 %27, -32
  store i8 %28, ptr %xx, align 1
  %ptradd24 = getelementptr inbounds i8, ptr %xx, i64 1
  store i8 -5, ptr %ptradd24, align 1
  %ptradd25 = getelementptr inbounds i8, ptr %xx, i64 2
  %29 = load i8, ptr %ptradd25, align 1
  %30 = and i8 %29, -16
  %31 = or i8 %30, 14
  store i8 %30, ptr %ptradd25, align 1
  %32 = load i8, ptr %xx, align 1
  %zext26 = zext i8 %32 to i32
  %lshrl27 = lshr i32 %zext26, 4
  %ptradd28 = getelementptr inbounds i8, ptr %xx, i64 1
  %33 = load i8, ptr %ptradd28, align 1
  %zext29 = zext i8 %33 to i32
  %shl30 = shl i32 %zext29, 4
  %34 = or i32 %shl30, %lshrl27
  %ptradd31 = getelementptr inbounds i8, ptr %xx, i64 2
  %35 = load i8, ptr %ptradd31, align 1
  %zext32 = zext i8 %35 to i32
  %shl33 = shl i32 %zext32, 12
  %36 = or i32 %shl33, %34
  %shl34 = shl i32 %36, 16
  %37 = call i32 @llvm.bswap.i32(i32 %shl34)
  %38 = and i32 65535, %37
  call void (ptr, ...) @printf(ptr @.str.3, i32 %38)
  ret void
}