void incr(unsigned char block[16]) {
  block[15]++;
  if (block[15] == 0) {
    block[14]++;
    if (block[14] == 0) {
      block[13]++;
      if (block[13] == 0) {
        block[12]++;
      }
    }
  }
}


x86 assembly (clang, -O0):
<incr>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    0xf(%rax),%cl
add    $0x1,%cl
mov    %cl,0xf(%rax)
mov    -0x8(%rbp),%rax
movzbl 0xf(%rax),%eax
cmp    $0x0,%eax
jne    1179 <incr+0x79>
mov    -0x8(%rbp),%rax
mov    0xe(%rax),%cl
add    $0x1,%cl
mov    %cl,0xe(%rax)
mov    -0x8(%rbp),%rax
movzbl 0xe(%rax),%eax
cmp    $0x0,%eax
jne    1174 <incr+0x74>
mov    -0x8(%rbp),%rax
mov    0xd(%rax),%cl
add    $0x1,%cl
mov    %cl,0xd(%rax)
mov    -0x8(%rbp),%rax
movzbl 0xd(%rax),%eax
cmp    $0x0,%eax
jne    116f <incr+0x6f>
mov    -0x8(%rbp),%rax
mov    0xc(%rax),%cl
add    $0x1,%cl
mov    %cl,0xc(%rax)
jmp    1174 <incr+0x74>
jmp    1179 <incr+0x79>
pop    %rbp
ret

x86 assembly (clang, -O2):
<incr>:
addb   $0x1,0xf(%rdi)
jne    1116 <incr+0x16>
addb   $0x1,0xe(%rdi)
jne    1116 <incr+0x16>
addb   $0x1,0xd(%rdi)
jne    1116 <incr+0x16>
addb   $0x1,0xc(%rdi)
ret

LLVM IR (-O0):
define void @incr(i8* %0) {
%2 = alloca i8*
store i8* %0, i8** %2
%3 = load i8*, i8** %2
%4 = getelementptr inbounds i8, i8* %3, i64 15
%5 = load i8, i8* %4
%6 = add i8 %5, 1
store i8 %6, i8* %4
%7 = load i8*, i8** %2
%8 = getelementptr inbounds i8, i8* %7, i64 15
%9 = load i8, i8* %8
%10 = zext i8 %9 to i32
%11 = icmp eq i32 %10, 0
br i1 %11, label %12, label %39
12: ; preds = %1
%13 = load i8*, i8** %2
%14 = getelementptr inbounds i8, i8* %13, i64 14
%15 = load i8, i8* %14
%16 = add i8 %15, 1
store i8 %16, i8* %14
%17 = load i8*, i8** %2
%18 = getelementptr inbounds i8, i8* %17, i64 14
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = icmp eq i32 %20, 0
br i1 %21, label %22, label %38
22: ; preds = %12
%23 = load i8*, i8** %2
%24 = getelementptr inbounds i8, i8* %23, i64 13
%25 = load i8, i8* %24
%26 = add i8 %25, 1
store i8 %26, i8* %24
%27 = load i8*, i8** %2
%28 = getelementptr inbounds i8, i8* %27, i64 13
%29 = load i8, i8* %28
%30 = zext i8 %29 to i32
%31 = icmp eq i32 %30, 0
br i1 %31, label %32, label %37
32: ; preds = %22
%33 = load i8*, i8** %2
%34 = getelementptr inbounds i8, i8* %33, i64 12
%35 = load i8, i8* %34
%36 = add i8 %35, 1
store i8 %36, i8* %34
br label %37
37: ; preds = %32, %22
br label %38
38: ; preds = %37, %12
br label %39
39: ; preds = %38, %1
ret void
}

LLVM IR (-O2):
define void @incr(i8* nocapture %0) {
%2 = getelementptr inbounds i8, i8* %0, i64 15
%3 = load i8, i8* %2
%4 = add i8 %3, 1
store i8 %4, i8* %2
%5 = icmp eq i8 %4, 0
br i1 %5, label %6, label %20
6: ; preds = %1
%7 = getelementptr inbounds i8, i8* %0, i64 14
%8 = load i8, i8* %7
%9 = add i8 %8, 1
store i8 %9, i8* %7
%10 = icmp eq i8 %9, 0
br i1 %10, label %11, label %20
11: ; preds = %6
%12 = getelementptr inbounds i8, i8* %0, i64 13
%13 = load i8, i8* %12
%14 = add i8 %13, 1
store i8 %14, i8* %12
%15 = icmp eq i8 %14, 0
br i1 %15, label %16, label %20
16: ; preds = %11
%17 = getelementptr inbounds i8, i8* %0, i64 12
%18 = load i8, i8* %17
%19 = add i8 %18, 1
store i8 %19, i8* %17
br label %20
20: ; preds = %6, %16, %11, %1
ret void
}