#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ st1;

/* Variables and functions */
int /*<<< orphan*/ printf(char *, ...);
void bitfield_test(void) {
  int a;
  struct sbf1 {
    int f1 : 3;
    int : 2;
    int f2 : 1;
    int : 0;
    int f3 : 5;
    int f4 : 7;
    unsigned int f5 : 7;
  } st1;
  printf("bitfield_test:");
  printf("sizeof(st1) = %d\n", sizeof(st1));
  st1.f1 = 3;
  st1.f2 = 1;
  st1.f3 = 15;
  a = 120;
  st1.f4 = a;
  st1.f5 = a;
  st1.f5++;
  printf("%d %d %d %d %d\n", st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
}


x86 assembly (clang, -O0):
<bitfield_test>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
lea    0xee1(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
lea    0xee2(%rip),%rdi
mov    $0x8,%esi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x10(%rbp),%al
and    $0xf8,%al
or     $0x3,%al
mov    %al,-0x10(%rbp)
mov    -0x10(%rbp),%al
and    $0xdf,%al
or     $0x20,%al
mov    %al,-0x10(%rbp)
mov    -0xc(%rbp),%eax
and    $0xffffffe0,%eax
or     $0xf,%eax
mov    %eax,-0xc(%rbp)
movl   $0x78,-0x4(%rbp)
mov    -0x4(%rbp),%ecx
mov    -0xc(%rbp),%eax
and    $0x7f,%ecx
shl    $0x5,%ecx
and    $0xfffff01f,%eax
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0x4(%rbp),%ecx
mov    -0xc(%rbp),%eax
and    $0x7f,%ecx
shl    $0xc,%ecx
and    $0xfff80fff,%eax
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%ecx
shr    $0xc,%ecx
and    $0x7f,%ecx
add    $0x1,%ecx
mov    -0xc(%rbp),%eax
and    $0x7f,%ecx
shl    $0xc,%ecx
and    $0xfff80fff,%eax
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%al
shl    $0x5,%al
sar    $0x5,%al
movsbl %al,%esi
mov    -0x10(%rbp),%al
shl    $0x2,%al
sar    $0x7,%al
movsbl %al,%edx
mov    -0xc(%rbp),%ecx
shl    $0x1b,%ecx
sar    $0x1b,%ecx
mov    -0xc(%rbp),%r8d
shl    $0x14,%r8d
sar    $0x19,%r8d
mov    -0xc(%rbp),%r9d
shr    $0xc,%r9d
and    $0x7f,%r9d
lea    0xe36(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bitfield_test>:
push   %rax
lea    0xee8(%rip),%rdi
xor    %eax,%eax
call   1030 <printf@plt>
lea    0xee9(%rip),%rdi
mov    $0x8,%esi
xor    %eax,%eax
call   1030 <printf@plt>
lea    0xee8(%rip),%rdi
mov    $0x3,%esi
mov    $0xffffffff,%edx
mov    $0xf,%ecx
mov    $0xfffffff8,%r8d
mov    $0x79,%r9d
xor    %eax,%eax
pop    %r11
jmp    1030 <printf@plt>

LLVM IR (-O0):
%struct.sbf1 = type { i8, i24 }
@.str = [15 x i8] c"bitfield_test:\00"
@.str.1 = [18 x i8] c"sizeof(st1) = %d\0A\00"
@.str.2 = [16 x i8] c"%d %d %d %d %d\0A\00"
define void @bitfield_test() {
%1 = alloca i32
%2 = alloca %struct.sbf1
%3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0))
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i64 0, i64 0), i64 8)
%5 = bitcast %struct.sbf1* %2 to i8*
%6 = load i8, i8* %5
%7 = and i8 %6, -8
%8 = or i8 %7, 3
store i8 %8, i8* %5
%9 = bitcast %struct.sbf1* %2 to i8*
%10 = load i8, i8* %9
%11 = and i8 %10, -33
%12 = or i8 %11, 32
store i8 %12, i8* %9
%13 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%14 = bitcast i24* %13 to i32*
%15 = load i32, i32* %14
%16 = and i32 %15, -32
%17 = or i32 %16, 15
store i32 %17, i32* %14
store i32 120, i32* %1
%18 = load i32, i32* %1
%19 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%20 = bitcast i24* %19 to i32*
%21 = load i32, i32* %20
%22 = and i32 %18, 127
%23 = shl i32 %22, 5
%24 = and i32 %21, -4065
%25 = or i32 %24, %23
store i32 %25, i32* %20
%26 = shl i32 %22, 25
%27 = ashr i32 %26, 25
%28 = load i32, i32* %1
%29 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%30 = bitcast i24* %29 to i32*
%31 = load i32, i32* %30
%32 = and i32 %28, 127
%33 = shl i32 %32, 12
%34 = and i32 %31, -520193
%35 = or i32 %34, %33
store i32 %35, i32* %30
%36 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%37 = bitcast i24* %36 to i32*
%38 = load i32, i32* %37
%39 = lshr i32 %38, 12
%40 = and i32 %39, 127
%41 = add i32 %40, 1
%42 = load i32, i32* %37
%43 = and i32 %41, 127
%44 = shl i32 %43, 12
%45 = and i32 %42, -520193
%46 = or i32 %45, %44
store i32 %46, i32* %37
%47 = bitcast %struct.sbf1* %2 to i8*
%48 = load i8, i8* %47
%49 = shl i8 %48, 5
%50 = ashr i8 %49, 5
%51 = sext i8 %50 to i32
%52 = bitcast %struct.sbf1* %2 to i8*
%53 = load i8, i8* %52
%54 = shl i8 %53, 2
%55 = ashr i8 %54, 7
%56 = sext i8 %55 to i32
%57 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%58 = bitcast i24* %57 to i32*
%59 = load i32, i32* %58
%60 = shl i32 %59, 27
%61 = ashr i32 %60, 27
%62 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%63 = bitcast i24* %62 to i32*
%64 = load i32, i32* %63
%65 = shl i32 %64, 20
%66 = ashr i32 %65, 25
%67 = getelementptr inbounds %struct.sbf1, %struct.sbf1* %2, i32 0, i32 1
%68 = bitcast i24* %67 to i32*
%69 = load i32, i32* %68
%70 = lshr i32 %69, 12
%71 = and i32 %70, 127
%72 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i32 %51, i32 %56, i32 %61, i32 %66, i32 %71)
ret void
}

LLVM IR (-O2):
@.str = [15 x i8] c"bitfield_test:\00"
@.str.1 = [18 x i8] c"sizeof(st1) = %d\0A\00"
@.str.2 = [16 x i8] c"%d %d %d %d %d\0A\00"
define void @bitfield_test() {
%1 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @.str, i64 0, i64 0))
%2 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i64 0, i64 0), i64 8)
%3 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([16 x i8], [16 x i8]* @.str.2, i64 0, i64 0), i32 3, i32 -1, i32 15, i32 -8, i32 121)
ret void
}