int checksum(short unsigned int n[13]) {
  short unsigned int s = 0, i, expected_check_digit;
  for (i = 0; i < 12; i++) {
    s += n[i] * (1 + (i % 2) * 2);
  }
  expected_check_digit = 10 - s % 10;
  if (n[12] != expected_check_digit)
    return -1;
  else
    return 0;
}


x86 assembly (clang, -O0):
<checksum>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movw   $0x0,-0x12(%rbp)
movw   $0x0,-0x14(%rbp)
movzwl -0x14(%rbp),%eax
cmp    $0xc,%eax
jge    115f <checksum+0x5f>
mov    -0x10(%rbp),%rax
movzwl -0x14(%rbp),%ecx
movzwl (%rax,%rcx,2),%ecx
movzwl -0x14(%rbp),%eax
mov    $0x2,%esi
cltd
idiv   %esi
mov    %edx,%eax
shl    $0x1,%eax
add    $0x1,%eax
imul   %eax,%ecx
movzwl -0x12(%rbp),%eax
add    %ecx,%eax
mov    %ax,-0x12(%rbp)
mov    -0x14(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x14(%rbp)
jmp    1114 <checksum+0x14>
movzwl -0x12(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
mov    $0xa,%eax
sub    %edx,%eax
mov    %ax,-0x16(%rbp)
mov    -0x10(%rbp),%rax
movzwl 0x18(%rax),%eax
movzwl -0x16(%rbp),%ecx
cmp    %ecx,%eax
je     1196 <checksum+0x96>
movl   $0xffffffff,-0x4(%rbp)
jmp    119d <checksum+0x9d>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<checksum>:
movzwl 0x2(%rdi),%eax
lea    (%rax,%rax,2),%eax
add    (%rdi),%ax
add    0x4(%rdi),%ax
movzwl 0x6(%rdi),%ecx
lea    (%rcx,%rcx,2),%ecx
add    %eax,%ecx
add    0x8(%rdi),%cx
movzwl 0xa(%rdi),%eax
lea    (%rax,%rax,2),%eax
add    %ecx,%eax
add    0xc(%rdi),%ax
movzwl 0xe(%rdi),%ecx
lea    (%rcx,%rcx,2),%ecx
add    %eax,%ecx
add    0x10(%rdi),%cx
movzwl 0x12(%rdi),%eax
lea    (%rax,%rax,2),%eax
add    %ecx,%eax
add    0x14(%rdi),%ax
movzwl 0x16(%rdi),%ecx
lea    (%rcx,%rcx,2),%ecx
add    %eax,%ecx
movzwl %cx,%eax
imul   $0xcccd,%eax,%eax
shr    $0x12,%eax
and    $0xfffffffe,%eax
lea    (%rax,%rax,4),%edx
sub    %ecx,%edx
add    $0xa,%edx
xor    %eax,%eax
cmp    %dx,0x18(%rdi)
setne  %al
neg    %eax
ret

LLVM IR (-O0):
define i32 @checksum(i16* %0) {
%2 = alloca i32
%3 = alloca i16*
%4 = alloca i16
%5 = alloca i16
%6 = alloca i16
store i16* %0, i16** %3
store i16 0, i16* %4
store i16 0, i16* %5
br label %7
7: ; preds = %28, %1
%8 = load i16, i16* %5
%9 = zext i16 %8 to i32
%10 = icmp slt i32 %9, 12
br i1 %10, label %11, label %31
11: ; preds = %7
%12 = load i16*, i16** %3
%13 = load i16, i16* %5
%14 = zext i16 %13 to i64
%15 = getelementptr inbounds i16, i16* %12, i64 %14
%16 = load i16, i16* %15
%17 = zext i16 %16 to i32
%18 = load i16, i16* %5
%19 = zext i16 %18 to i32
%20 = srem i32 %19, 2
%21 = mul nsw i32 %20, 2
%22 = add nsw i32 1, %21
%23 = mul nsw i32 %17, %22
%24 = load i16, i16* %4
%25 = zext i16 %24 to i32
%26 = add nsw i32 %25, %23
%27 = trunc i32 %26 to i16
store i16 %27, i16* %4
br label %28
28: ; preds = %11
%29 = load i16, i16* %5
%30 = add i16 %29, 1
store i16 %30, i16* %5
br label %7
31: ; preds = %7
%32 = load i16, i16* %4
%33 = zext i16 %32 to i32
%34 = srem i32 %33, 10
%35 = sub nsw i32 10, %34
%36 = trunc i32 %35 to i16
store i16 %36, i16* %6
%37 = load i16*, i16** %3
%38 = getelementptr inbounds i16, i16* %37, i64 12
%39 = load i16, i16* %38
%40 = zext i16 %39 to i32
%41 = load i16, i16* %6
%42 = zext i16 %41 to i32
%43 = icmp ne i32 %40, %42
br i1 %43, label %44, label %45
44: ; preds = %31
store i32 -1, i32* %2
br label %46
45: ; preds = %31
store i32 0, i32* %2
br label %46
46: ; preds = %45, %44
%47 = load i32, i32* %2
ret i32 %47
}

LLVM IR (-O2):
define i32 @checksum(i16* nocapture %0) {
%2 = load i16, i16* %0
%3 = getelementptr inbounds i16, i16* %0, i64 1
%4 = load i16, i16* %3
%5 = mul i16 %4, 3
%6 = add i16 %5, %2
%7 = getelementptr inbounds i16, i16* %0, i64 2
%8 = load i16, i16* %7
%9 = add i16 %6, %8
%10 = getelementptr inbounds i16, i16* %0, i64 3
%11 = load i16, i16* %10
%12 = mul i16 %11, 3
%13 = add i16 %12, %9
%14 = getelementptr inbounds i16, i16* %0, i64 4
%15 = load i16, i16* %14
%16 = add i16 %13, %15
%17 = getelementptr inbounds i16, i16* %0, i64 5
%18 = load i16, i16* %17
%19 = mul i16 %18, 3
%20 = add i16 %19, %16
%21 = getelementptr inbounds i16, i16* %0, i64 6
%22 = load i16, i16* %21
%23 = add i16 %20, %22
%24 = getelementptr inbounds i16, i16* %0, i64 7
%25 = load i16, i16* %24
%26 = mul i16 %25, 3
%27 = add i16 %26, %23
%28 = getelementptr inbounds i16, i16* %0, i64 8
%29 = load i16, i16* %28
%30 = add i16 %27, %29
%31 = getelementptr inbounds i16, i16* %0, i64 9
%32 = load i16, i16* %31
%33 = mul i16 %32, 3
%34 = add i16 %33, %30
%35 = getelementptr inbounds i16, i16* %0, i64 10
%36 = load i16, i16* %35
%37 = add i16 %34, %36
%38 = getelementptr inbounds i16, i16* %0, i64 11
%39 = load i16, i16* %38
%40 = mul i16 %39, 3
%41 = add i16 %40, %37
%42 = urem i16 %41, 10
%43 = getelementptr inbounds i16, i16* %0, i64 12
%44 = load i16, i16* %43
%45 = sub nuw nsw i16 10, %42
%46 = icmp ne i16 %44, %45
%47 = sext i1 %46 to i32
ret i32 %47
}