unsigned int vecinos(unsigned char *a, unsigned int i, unsigned int j,
                     unsigned int M, unsigned int N) {
  unsigned int vecinos = 0;
  int x, y;
  for (x = -1; x < 2; x++) {
    for (y = -1; y < 2; y++) {
      if (x + i >= 0 && x + i < N && y + j >= 0 && y + j < M) {
        if ((!(x == 0 && y == 0)) && a[N * (x + i) + (y + j)] == '1') {
          vecinos++;
        }
      }
    }
  }
  return vecinos;
}


x86 assembly (clang, -O0):
<vecinos>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0xffffffff,-0x20(%rbp)
cmpl   $0x2,-0x20(%rbp)
jge    11e9 <vecinos+0xe9>
movl   $0xffffffff,-0x24(%rbp)
cmpl   $0x2,-0x24(%rbp)
jge    11d6 <vecinos+0xd6>
mov    -0x20(%rbp),%eax
add    -0xc(%rbp),%eax
cmp    $0x0,%eax
jb     11c3 <vecinos+0xc3>
mov    -0x20(%rbp),%eax
add    -0xc(%rbp),%eax
cmp    -0x18(%rbp),%eax
jae    11c3 <vecinos+0xc3>
mov    -0x24(%rbp),%eax
add    -0x10(%rbp),%eax
cmp    $0x0,%eax
jb     11c3 <vecinos+0xc3>
mov    -0x24(%rbp),%eax
add    -0x10(%rbp),%eax
cmp    -0x14(%rbp),%eax
jae    11c3 <vecinos+0xc3>
cmpl   $0x0,-0x20(%rbp)
jne    118e <vecinos+0x8e>
cmpl   $0x0,-0x24(%rbp)
je     11be <vecinos+0xbe>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    -0x20(%rbp),%edx
add    -0xc(%rbp),%edx
imul   %edx,%ecx
mov    -0x24(%rbp),%edx
add    -0x10(%rbp),%edx
add    %edx,%ecx
mov    %ecx,%ecx
movzbl (%rax,%rcx,1),%eax
cmp    $0x31,%eax
jne    11be <vecinos+0xbe>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11c3 <vecinos+0xc3>
jmp    11c8 <vecinos+0xc8>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1134 <vecinos+0x34>
jmp    11db <vecinos+0xdb>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1123 <vecinos+0x23>
mov    -0x1c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<vecinos>:
lea    -0x1(%rsi),%r9d
xor    %eax,%eax
cmp    %r8d,%r9d
jae    1159 <vecinos+0x59>
imul   %r8d,%r9d
lea    -0x1(%rdx),%r10d
xor    %eax,%eax
cmp    %ecx,%r10d
jae    1127 <vecinos+0x27>
add    %r9d,%r10d
xor    %eax,%eax
cmpb   $0x31,(%rdi,%r10,1)
sete   %al
cmp    %ecx,%edx
jae    113e <vecinos+0x3e>
lea    (%r9,%rdx,1),%r10d
xor    %r11d,%r11d
cmpb   $0x31,(%rdi,%r10,1)
sete   %r11b
add    %r11d,%eax
lea    0x1(%rdx),%r10d
cmp    %ecx,%r10d
jae    1159 <vecinos+0x59>
add    %r9d,%r10d
xor    %r9d,%r9d
cmpb   $0x31,(%rdi,%r10,1)
sete   %r9b
add    %r9d,%eax
cmp    %r8d,%esi
jae    119b <vecinos+0x9b>
mov    %esi,%r9d
imul   %r8d,%r9d
lea    -0x1(%rdx),%r10d
cmp    %ecx,%r10d
jae    1180 <vecinos+0x80>
add    %r9d,%r10d
xor    %r11d,%r11d
cmpb   $0x31,(%rdi,%r10,1)
sete   %r11b
add    %r11d,%eax
lea    0x1(%rdx),%r10d
cmp    %ecx,%r10d
jae    119b <vecinos+0x9b>
add    %r9d,%r10d
xor    %r9d,%r9d
cmpb   $0x31,(%rdi,%r10,1)
sete   %r9b
add    %r9d,%eax
add    $0x1,%esi
cmp    %r8d,%esi
jae    11ed <vecinos+0xed>
imul   %r8d,%esi
lea    -0x1(%rdx),%r8d
cmp    %ecx,%r8d
jae    11c2 <vecinos+0xc2>
add    %esi,%r8d
xor    %r9d,%r9d
cmpb   $0x31,(%rdi,%r8,1)
sete   %r9b
add    %r9d,%eax
cmp    %ecx,%edx
jae    11d9 <vecinos+0xd9>
lea    (%rsi,%rdx,1),%r8d
xor    %r9d,%r9d
cmpb   $0x31,(%rdi,%r8,1)
sete   %r9b
add    %r9d,%eax
add    $0x1,%edx
cmp    %ecx,%edx
jae    11ed <vecinos+0xed>
add    %esi,%edx
xor    %ecx,%ecx
cmpb   $0x31,(%rdi,%rdx,1)
sete   %cl
add    %ecx,%eax
ret

LLVM IR (-O0):
define i32 @vecinos(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
store i8* %0, i8** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
store i32 %4, i32* %10
store i32 0, i32* %11
store i32 -1, i32* %12
br label %14
14: ; preds = %74, %5
%15 = load i32, i32* %12
%16 = icmp slt i32 %15, 2
br i1 %16, label %17, label %77
17: ; preds = %14
store i32 -1, i32* %13
br label %18
18: ; preds = %70, %17
%19 = load i32, i32* %13
%20 = icmp slt i32 %19, 2
br i1 %20, label %21, label %73
21: ; preds = %18
%22 = load i32, i32* %12
%23 = load i32, i32* %7
%24 = add i32 %22, %23
%25 = icmp uge i32 %24, 0
br i1 %25, label %26, label %69
26: ; preds = %21
%27 = load i32, i32* %12
%28 = load i32, i32* %7
%29 = add i32 %27, %28
%30 = load i32, i32* %10
%31 = icmp ult i32 %29, %30
br i1 %31, label %32, label %69
32: ; preds = %26
%33 = load i32, i32* %13
%34 = load i32, i32* %8
%35 = add i32 %33, %34
%36 = icmp uge i32 %35, 0
br i1 %36, label %37, label %69
37: ; preds = %32
%38 = load i32, i32* %13
%39 = load i32, i32* %8
%40 = add i32 %38, %39
%41 = load i32, i32* %9
%42 = icmp ult i32 %40, %41
br i1 %42, label %43, label %69
43: ; preds = %37
%44 = load i32, i32* %12
%45 = icmp eq i32 %44, 0
br i1 %45, label %46, label %49
46: ; preds = %43
%47 = load i32, i32* %13
%48 = icmp eq i32 %47, 0
br i1 %48, label %68, label %49
49: ; preds = %46, %43
%50 = load i8*, i8** %6
%51 = load i32, i32* %10
%52 = load i32, i32* %12
%53 = load i32, i32* %7
%54 = add i32 %52, %53
%55 = mul i32 %51, %54
%56 = load i32, i32* %13
%57 = load i32, i32* %8
%58 = add i32 %56, %57
%59 = add i32 %55, %58
%60 = zext i32 %59 to i64
%61 = getelementptr inbounds i8, i8* %50, i64 %60
%62 = load i8, i8* %61
%63 = zext i8 %62 to i32
%64 = icmp eq i32 %63, 49
br i1 %64, label %65, label %68
65: ; preds = %49
%66 = load i32, i32* %11
%67 = add i32 %66, 1
store i32 %67, i32* %11
br label %68
68: ; preds = %65, %49, %46
br label %69
69: ; preds = %68, %37, %32, %26, %21
br label %70
70: ; preds = %69
%71 = load i32, i32* %13
%72 = add nsw i32 %71, 1
store i32 %72, i32* %13
br label %18
73: ; preds = %18
br label %74
74: ; preds = %73
%75 = load i32, i32* %12
%76 = add nsw i32 %75, 1
store i32 %76, i32* %12
br label %14
77: ; preds = %14
%78 = load i32, i32* %11
ret i32 %78
}

LLVM IR (-O2):
define i32 @vecinos(i8* nocapture %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = add i32 %1, -1
%7 = icmp ult i32 %6, %4
%8 = mul i32 %6, %4
br i1 %7, label %9, label %42
9: ; preds = %5
%10 = add i32 %2, -1
%11 = icmp ult i32 %10, %3
br i1 %11, label %12, label %19
12: ; preds = %9
%13 = add i32 %10, %8
%14 = zext i32 %13 to i64
%15 = getelementptr inbounds i8, i8* %0, i64 %14
%16 = load i8, i8* %15
%17 = icmp eq i8 %16, 49
%18 = zext i1 %17 to i32
br label %19
19: ; preds = %12, %9
%20 = phi i32 [ %18, %12 ], [ 0, %9 ]
%21 = icmp ult i32 %2, %3
br i1 %21, label %22, label %30
22: ; preds = %19
%23 = add i32 %8, %2
%24 = zext i32 %23 to i64
%25 = getelementptr inbounds i8, i8* %0, i64 %24
%26 = load i8, i8* %25
%27 = icmp eq i8 %26, 49
%28 = zext i1 %27 to i32
%29 = add nuw nsw i32 %20, %28
br label %30
30: ; preds = %22, %19
%31 = phi i32 [ %29, %22 ], [ %20, %19 ]
%32 = add i32 %2, 1
%33 = icmp ult i32 %32, %3
br i1 %33, label %34, label %42
34: ; preds = %30
%35 = add i32 %32, %8
%36 = zext i32 %35 to i64
%37 = getelementptr inbounds i8, i8* %0, i64 %36
%38 = load i8, i8* %37
%39 = icmp eq i8 %38, 49
%40 = zext i1 %39 to i32
%41 = add nuw nsw i32 %31, %40
br label %42
42: ; preds = %5, %34, %30
%43 = phi i32 [ %31, %30 ], [ %41, %34 ], [ 0, %5 ]
%44 = icmp ult i32 %1, %4
%45 = mul i32 %1, %4
br i1 %44, label %46, label %69
46: ; preds = %42
%47 = add i32 %2, -1
%48 = icmp ult i32 %47, %3
br i1 %48, label %49, label %57
49: ; preds = %46
%50 = add i32 %47, %45
%51 = zext i32 %50 to i64
%52 = getelementptr inbounds i8, i8* %0, i64 %51
%53 = load i8, i8* %52
%54 = icmp eq i8 %53, 49
%55 = zext i1 %54 to i32
%56 = add nuw nsw i32 %43, %55
br label %57
57: ; preds = %46, %49
%58 = phi i32 [ %56, %49 ], [ %43, %46 ]
%59 = add i32 %2, 1
%60 = icmp ult i32 %59, %3
br i1 %60, label %61, label %69
61: ; preds = %57
%62 = add i32 %59, %45
%63 = zext i32 %62 to i64
%64 = getelementptr inbounds i8, i8* %0, i64 %63
%65 = load i8, i8* %64
%66 = icmp eq i8 %65, 49
%67 = zext i1 %66 to i32
%68 = add nuw nsw i32 %58, %67
br label %69
69: ; preds = %42, %61, %57
%70 = phi i32 [ %58, %57 ], [ %68, %61 ], [ %43, %42 ]
%71 = add i32 %1, 1
%72 = icmp ult i32 %71, %4
%73 = mul i32 %71, %4
br i1 %72, label %74, label %108
74: ; preds = %69
%75 = add i32 %2, -1
%76 = icmp ult i32 %75, %3
br i1 %76, label %77, label %85
77: ; preds = %74
%78 = add i32 %75, %73
%79 = zext i32 %78 to i64
%80 = getelementptr inbounds i8, i8* %0, i64 %79
%81 = load i8, i8* %80
%82 = icmp eq i8 %81, 49
%83 = zext i1 %82 to i32
%84 = add nuw nsw i32 %70, %83
br label %85
85: ; preds = %77, %74
%86 = phi i32 [ %84, %77 ], [ %70, %74 ]
%87 = icmp ult i32 %2, %3
br i1 %87, label %88, label %96
88: ; preds = %85
%89 = add i32 %73, %2
%90 = zext i32 %89 to i64
%91 = getelementptr inbounds i8, i8* %0, i64 %90
%92 = load i8, i8* %91
%93 = icmp eq i8 %92, 49
%94 = zext i1 %93 to i32
%95 = add nuw nsw i32 %86, %94
br label %96
96: ; preds = %88, %85
%97 = phi i32 [ %95, %88 ], [ %86, %85 ]
%98 = add i32 %2, 1
%99 = icmp ult i32 %98, %3
br i1 %99, label %100, label %108
100: ; preds = %96
%101 = add i32 %98, %73
%102 = zext i32 %101 to i64
%103 = getelementptr inbounds i8, i8* %0, i64 %102
%104 = load i8, i8* %103
%105 = icmp eq i8 %104, 49
%106 = zext i1 %105 to i32
%107 = add nuw nsw i32 %97, %106
br label %108
108: ; preds = %69, %100, %96
%109 = phi i32 [ %97, %96 ], [ %107, %100 ], [ %70, %69 ]
ret i32 %109
}