#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*/ c;

/* Variables and functions */
int /*<<< orphan*/ assert(int);
int /*<<< orphan*/ assign_bit(unsigned char *, int, int);
int /*<<< orphan*/ clear_bit(unsigned char *, int);
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ set_bit(unsigned char *, int);
int test_bit(unsigned char *, int);
void test_byte() {
  printf("test one byte start...\n");
  unsigned char c = 0;
  int i;
  for (i = 0; i < sizeof(c) * 8; i++) {
    set_bit(&c, i);
  }
  assert(c == 0xff);
  for (i = 0; i < sizeof(c) * 8; i++) {
    assert(test_bit(&c, i) == 1);
  }
  for (i = 0; i < sizeof(c) * 8; i++) {
    clear_bit(&c, i);
  }
  assert(c == 0);
  for (i = 0; i < sizeof(c) * 8; i++) {
    assign_bit(&c, i, 1);
  }
  assert(c == 0xff);
  for (i = 0; i < sizeof(c) * 8; i++) {
    assign_bit(&c, i, 0);
  }
  assert(c == 0);
}


x86 assembly (clang, -O0):
<test_byte>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
lea    0xe91(%rip),%rdi
call   1030 <printf@plt>
movb   $0x0,-0x1(%rbp)
movl   $0x0,-0x8(%rbp)
movslq -0x8(%rbp),%rax
cmp    $0x8,%rax
jae    11a7 <test_byte+0x47>
mov    -0x8(%rbp),%esi
lea    -0x1(%rbp),%rdi
call   1050 <set_bit@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    117f <test_byte+0x1f>
movzbl -0x1(%rbp),%eax
cmp    $0xff,%eax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
movl   $0x0,-0x8(%rbp)
movslq -0x8(%rbp),%rax
cmp    $0x8,%rax
jae    11fc <test_byte+0x9c>
mov    -0x8(%rbp),%esi
lea    -0x1(%rbp),%rdi
call   1070 <test_bit@plt>
cmp    $0x1,%eax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    11c4 <test_byte+0x64>
movl   $0x0,-0x8(%rbp)
movslq -0x8(%rbp),%rax
cmp    $0x8,%rax
jae    122b <test_byte+0xcb>
mov    -0x8(%rbp),%esi
lea    -0x1(%rbp),%rdi
call   1040 <clear_bit@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1203 <test_byte+0xa3>
movzbl -0x1(%rbp),%eax
cmp    $0x0,%eax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
movl   $0x0,-0x8(%rbp)
movslq -0x8(%rbp),%rax
cmp    $0x8,%rax
jae    1273 <test_byte+0x113>
mov    -0x8(%rbp),%esi
lea    -0x1(%rbp),%rdi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1246 <test_byte+0xe6>
movzbl -0x1(%rbp),%eax
cmp    $0xff,%eax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
movl   $0x0,-0x8(%rbp)
movslq -0x8(%rbp),%rax
cmp    $0x8,%rax
jae    12ba <test_byte+0x15a>
mov    -0x8(%rbp),%esi
lea    -0x1(%rbp),%rdi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1290 <test_byte+0x130>
movzbl -0x1(%rbp),%eax
cmp    $0x0,%eax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_byte>:
push   %rbx
sub    $0x10,%rsp
lea    0xe94(%rip),%rdi
call   1030 <puts@plt>
movb   $0x0,0xf(%rsp)
lea    0xf(%rsp),%rbx
mov    %rbx,%rdi
xor    %esi,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x1,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x2,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x4,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x5,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x6,%esi
call   1050 <set_bit@plt>
mov    %rbx,%rdi
mov    $0x7,%esi
call   1050 <set_bit@plt>
xor    %edi,%edi
cmpb   $0xff,0xf(%rsp)
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
xor    %esi,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x1,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x2,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x4,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x5,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x6,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
mov    $0x7,%esi
call   1070 <test_bit@plt>
xor    %edi,%edi
cmp    $0x1,%eax
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
xor    %esi,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x1,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x2,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x4,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x5,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x6,%esi
call   1040 <clear_bit@plt>
mov    %rbx,%rdi
mov    $0x7,%esi
call   1040 <clear_bit@plt>
xor    %edi,%edi
cmpb   $0x0,0xf(%rsp)
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
xor    %esi,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x1,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x2,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x4,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x5,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x6,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x7,%esi
mov    $0x1,%edx
call   1080 <assign_bit@plt>
xor    %edi,%edi
cmpb   $0xff,0xf(%rsp)
sete   %dil
call   1060 <assert@plt>
mov    %rbx,%rdi
xor    %esi,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x1,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x2,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x4,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x5,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x6,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
mov    %rbx,%rdi
mov    $0x7,%esi
xor    %edx,%edx
call   1080 <assign_bit@plt>
xor    %edi,%edi
cmpb   $0x0,0xf(%rsp)
sete   %dil
call   1060 <assert@plt>
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [24 x i8] c"test one byte start...\0A\00"
define void @test_byte() {
%1 = alloca i8
%2 = alloca i32
%3 = call i32 @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i64 0, i64 0))
store i8 0, i8* %1
store i32 0, i32* %2
br label %4
4: ; preds = %11, %0
%5 = load i32, i32* %2
%6 = sext i32 %5 to i64
%7 = icmp ult i64 %6, 8
br i1 %7, label %8, label %14
8: ; preds = %4
%9 = load i32, i32* %2
%10 = call i32 @set_bit(i8* %1, i32 %9)
br label %11
11: ; preds = %8
%12 = load i32, i32* %2
%13 = add nsw i32 %12, 1
store i32 %13, i32* %2
br label %4
14: ; preds = %4
%15 = load i8, i8* %1
%16 = zext i8 %15 to i32
%17 = icmp eq i32 %16, 255
%18 = zext i1 %17 to i32
%19 = call i32 @assert(i32 %18)
store i32 0, i32* %2
br label %20
20: ; preds = %30, %14
%21 = load i32, i32* %2
%22 = sext i32 %21 to i64
%23 = icmp ult i64 %22, 8
br i1 %23, label %24, label %33
24: ; preds = %20
%25 = load i32, i32* %2
%26 = call i32 @test_bit(i8* %1, i32 %25)
%27 = icmp eq i32 %26, 1
%28 = zext i1 %27 to i32
%29 = call i32 @assert(i32 %28)
br label %30
30: ; preds = %24
%31 = load i32, i32* %2
%32 = add nsw i32 %31, 1
store i32 %32, i32* %2
br label %20
33: ; preds = %20
store i32 0, i32* %2
br label %34
34: ; preds = %41, %33
%35 = load i32, i32* %2
%36 = sext i32 %35 to i64
%37 = icmp ult i64 %36, 8
br i1 %37, label %38, label %44
38: ; preds = %34
%39 = load i32, i32* %2
%40 = call i32 @clear_bit(i8* %1, i32 %39)
br label %41
41: ; preds = %38
%42 = load i32, i32* %2
%43 = add nsw i32 %42, 1
store i32 %43, i32* %2
br label %34
44: ; preds = %34
%45 = load i8, i8* %1
%46 = zext i8 %45 to i32
%47 = icmp eq i32 %46, 0
%48 = zext i1 %47 to i32
%49 = call i32 @assert(i32 %48)
store i32 0, i32* %2
br label %50
50: ; preds = %57, %44
%51 = load i32, i32* %2
%52 = sext i32 %51 to i64
%53 = icmp ult i64 %52, 8
br i1 %53, label %54, label %60
54: ; preds = %50
%55 = load i32, i32* %2
%56 = call i32 @assign_bit(i8* %1, i32 %55, i32 1)
br label %57
57: ; preds = %54
%58 = load i32, i32* %2
%59 = add nsw i32 %58, 1
store i32 %59, i32* %2
br label %50
60: ; preds = %50
%61 = load i8, i8* %1
%62 = zext i8 %61 to i32
%63 = icmp eq i32 %62, 255
%64 = zext i1 %63 to i32
%65 = call i32 @assert(i32 %64)
store i32 0, i32* %2
br label %66
66: ; preds = %73, %60
%67 = load i32, i32* %2
%68 = sext i32 %67 to i64
%69 = icmp ult i64 %68, 8
br i1 %69, label %70, label %76
70: ; preds = %66
%71 = load i32, i32* %2
%72 = call i32 @assign_bit(i8* %1, i32 %71, i32 0)
br label %73
73: ; preds = %70
%74 = load i32, i32* %2
%75 = add nsw i32 %74, 1
store i32 %75, i32* %2
br label %66
76: ; preds = %66
%77 = load i8, i8* %1
%78 = zext i8 %77 to i32
%79 = icmp eq i32 %78, 0
%80 = zext i1 %79 to i32
%81 = call i32 @assert(i32 %80)
ret void
}

LLVM IR (-O2):
@str = [23 x i8] c"test one byte start...\00"
define void @test_byte() {
%1 = alloca i8
%2 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @str, i64 0, i64 0))
store i8 0, i8* %1
%3 = call i32 @set_bit(i8* %1, i32 0)
%4 = call i32 @set_bit(i8* %1, i32 1)
%5 = call i32 @set_bit(i8* %1, i32 2)
%6 = call i32 @set_bit(i8* %1, i32 3)
%7 = call i32 @set_bit(i8* %1, i32 4)
%8 = call i32 @set_bit(i8* %1, i32 5)
%9 = call i32 @set_bit(i8* %1, i32 6)
%10 = call i32 @set_bit(i8* %1, i32 7)
%11 = load i8, i8* %1
%12 = icmp eq i8 %11, -1
%13 = zext i1 %12 to i32
%14 = call i32 @assert(i32 %13)
%15 = call i32 @test_bit(i8* %1, i32 0)
%16 = icmp eq i32 %15, 1
%17 = zext i1 %16 to i32
%18 = call i32 @assert(i32 %17)
%19 = call i32 @test_bit(i8* %1, i32 1)
%20 = icmp eq i32 %19, 1
%21 = zext i1 %20 to i32
%22 = call i32 @assert(i32 %21)
%23 = call i32 @test_bit(i8* %1, i32 2)
%24 = icmp eq i32 %23, 1
%25 = zext i1 %24 to i32
%26 = call i32 @assert(i32 %25)
%27 = call i32 @test_bit(i8* %1, i32 3)
%28 = icmp eq i32 %27, 1
%29 = zext i1 %28 to i32
%30 = call i32 @assert(i32 %29)
%31 = call i32 @test_bit(i8* %1, i32 4)
%32 = icmp eq i32 %31, 1
%33 = zext i1 %32 to i32
%34 = call i32 @assert(i32 %33)
%35 = call i32 @test_bit(i8* %1, i32 5)
%36 = icmp eq i32 %35, 1
%37 = zext i1 %36 to i32
%38 = call i32 @assert(i32 %37)
%39 = call i32 @test_bit(i8* %1, i32 6)
%40 = icmp eq i32 %39, 1
%41 = zext i1 %40 to i32
%42 = call i32 @assert(i32 %41)
%43 = call i32 @test_bit(i8* %1, i32 7)
%44 = icmp eq i32 %43, 1
%45 = zext i1 %44 to i32
%46 = call i32 @assert(i32 %45)
%47 = call i32 @clear_bit(i8* %1, i32 0)
%48 = call i32 @clear_bit(i8* %1, i32 1)
%49 = call i32 @clear_bit(i8* %1, i32 2)
%50 = call i32 @clear_bit(i8* %1, i32 3)
%51 = call i32 @clear_bit(i8* %1, i32 4)
%52 = call i32 @clear_bit(i8* %1, i32 5)
%53 = call i32 @clear_bit(i8* %1, i32 6)
%54 = call i32 @clear_bit(i8* %1, i32 7)
%55 = load i8, i8* %1
%56 = icmp eq i8 %55, 0
%57 = zext i1 %56 to i32
%58 = call i32 @assert(i32 %57)
%59 = call i32 @assign_bit(i8* %1, i32 0, i32 1)
%60 = call i32 @assign_bit(i8* %1, i32 1, i32 1)
%61 = call i32 @assign_bit(i8* %1, i32 2, i32 1)
%62 = call i32 @assign_bit(i8* %1, i32 3, i32 1)
%63 = call i32 @assign_bit(i8* %1, i32 4, i32 1)
%64 = call i32 @assign_bit(i8* %1, i32 5, i32 1)
%65 = call i32 @assign_bit(i8* %1, i32 6, i32 1)
%66 = call i32 @assign_bit(i8* %1, i32 7, i32 1)
%67 = load i8, i8* %1
%68 = icmp eq i8 %67, -1
%69 = zext i1 %68 to i32
%70 = call i32 @assert(i32 %69)
%71 = call i32 @assign_bit(i8* %1, i32 0, i32 0)
%72 = call i32 @assign_bit(i8* %1, i32 1, i32 0)
%73 = call i32 @assign_bit(i8* %1, i32 2, i32 0)
%74 = call i32 @assign_bit(i8* %1, i32 3, i32 0)
%75 = call i32 @assign_bit(i8* %1, i32 4, i32 0)
%76 = call i32 @assign_bit(i8* %1, i32 5, i32 0)
%77 = call i32 @assign_bit(i8* %1, i32 6, i32 0)
%78 = call i32 @assign_bit(i8* %1, i32 7, i32 0)
%79 = load i8, i8* %1
%80 = icmp eq i8 %79, 0
%81 = zext i1 %80 to i32
%82 = call i32 @assert(i32 %81)
ret void
}