int alive_neighbours(char **tab, int i, int j, int width, int height) {
  int n = 0;
  for (int k = i - 1; k < i + 2; k++)
    if (k >= 0 && k < width)
      for (int l = j - 1; l < j + 2; l++)
        if (l >= 0 && l < height && (k != i || l != j) && tab[k][l])
          n++;
  return n;
}


x86 assembly (clang, -O0):
<alive_neighbours>:
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)
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    -0xc(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
jge    11e5 <alive_neighbours+0xe5>
cmpl   $0x0,-0x20(%rbp)
jl     11d2 <alive_neighbours+0xd2>
mov    -0x20(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11d2 <alive_neighbours+0xd2>
mov    -0x10(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    -0x10(%rbp),%ecx
add    $0x2,%ecx
cmp    %ecx,%eax
jge    11cd <alive_neighbours+0xcd>
cmpl   $0x0,-0x24(%rbp)
jl     11ba <alive_neighbours+0xba>
mov    -0x24(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    11ba <alive_neighbours+0xba>
mov    -0x20(%rbp),%eax
cmp    -0xc(%rbp),%eax
jne    1194 <alive_neighbours+0x94>
mov    -0x24(%rbp),%eax
cmp    -0x10(%rbp),%eax
je     11ba <alive_neighbours+0xba>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x24(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     11ba <alive_neighbours+0xba>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11bf <alive_neighbours+0xbf>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1155 <alive_neighbours+0x55>
jmp    11d2 <alive_neighbours+0xd2>
jmp    11d7 <alive_neighbours+0xd7>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1125 <alive_neighbours+0x25>
mov    -0x1c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<alive_neighbours>:
push   %r15
push   %r14
push   %rbx
lea    -0x1(%rsi),%r11d
lea    -0x1(%rdx),%r10d
movslq %r11d,%r9
test   %r9d,%r9d
js     116a <alive_neighbours+0x6a>
cmp    %ecx,%r11d
jge    116a <alive_neighbours+0x6a>
xor    %eax,%eax
test   %edx,%edx
jle    1136 <alive_neighbours+0x36>
cmp    %r8d,%edx
jg     1136 <alive_neighbours+0x36>
mov    (%rdi,%r9,8),%r14
mov    %r10d,%ebx
xor    %eax,%eax
cmpb   $0x0,(%r14,%rbx,1)
setne  %al
test   %edx,%edx
js     114d <alive_neighbours+0x4d>
cmp    %r8d,%edx
jge    114d <alive_neighbours+0x4d>
mov    (%rdi,%r9,8),%r14
mov    %edx,%ebx
cmpb   $0x1,(%r14,%rbx,1)
sbb    $0xffffffff,%eax
cmp    $0xffffffff,%edx
jl     1178 <alive_neighbours+0x78>
lea    0x1(%rdx),%ebx
cmp    %r8d,%ebx
jge    1178 <alive_neighbours+0x78>
mov    (%rdi,%r9,8),%r14
mov    %ebx,%ebx
cmpb   $0x1,(%r14,%rbx,1)
sbb    $0xffffffff,%eax
jmp    1178 <alive_neighbours+0x78>
xor    %eax,%eax
cmp    $0x80000000,%esi
je     123d <alive_neighbours+0x13d>
movslq %ecx,%rbx
movslq %esi,%r14
cmp    $0x80000000,%esi
ja     11df <alive_neighbours+0xdf>
lea    0x1(%r9),%rsi
cmp    %rbx,%rsi
jge    11df <alive_neighbours+0xdf>
test   %edx,%edx
jle    11a8 <alive_neighbours+0xa8>
cmp    %r8d,%edx
jg     11a8 <alive_neighbours+0xa8>
mov    0x8(%rdi,%r9,8),%r15
mov    %r10d,%ecx
cmpb   $0x1,(%r15,%rcx,1)
sbb    $0xffffffff,%eax
test   %edx,%edx
js     11c4 <alive_neighbours+0xc4>
cmp    %r8d,%edx
jge    11c4 <alive_neighbours+0xc4>
cmp    %r14,%rsi
je     11c4 <alive_neighbours+0xc4>
mov    0x8(%rdi,%r9,8),%rcx
mov    %edx,%esi
cmpb   $0x1,(%rcx,%rsi,1)
sbb    $0xffffffff,%eax
cmp    $0xffffffff,%edx
jl     11df <alive_neighbours+0xdf>
lea    0x1(%rdx),%esi
cmp    %r8d,%esi
jge    11df <alive_neighbours+0xdf>
mov    0x8(%rdi,%r9,8),%rcx
mov    %esi,%esi
cmpb   $0x1,(%rcx,%rsi,1)
sbb    $0xffffffff,%eax
cmp    $0xfffffffe,%r11d
jl     123d <alive_neighbours+0x13d>
lea    0x2(%r9),%rsi
cmp    %rbx,%rsi
jge    123d <alive_neighbours+0x13d>
test   %edx,%edx
jle    1206 <alive_neighbours+0x106>
cmp    %r8d,%edx
jg     1206 <alive_neighbours+0x106>
mov    0x10(%rdi,%r9,8),%rcx
mov    %r10d,%ebx
cmpb   $0x1,(%rcx,%rbx,1)
sbb    $0xffffffff,%eax
test   %edx,%edx
js     1222 <alive_neighbours+0x122>
cmp    %r8d,%edx
jge    1222 <alive_neighbours+0x122>
cmp    %r14,%rsi
je     1222 <alive_neighbours+0x122>
mov    0x10(%rdi,%r9,8),%rcx
mov    %edx,%esi
cmpb   $0x1,(%rcx,%rsi,1)
sbb    $0xffffffff,%eax
cmp    $0xffffffff,%edx
jl     123d <alive_neighbours+0x13d>
add    $0x1,%edx
cmp    %r8d,%edx
jge    123d <alive_neighbours+0x13d>
mov    0x10(%rdi,%r9,8),%rcx
mov    %edx,%edx
cmpb   $0x1,(%rcx,%rdx,1)
sbb    $0xffffffff,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
define i32 @alive_neighbours(i8** nocapture %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = add i32 %1, -1
%7 = add nsw i32 %2, -1
%8 = sext i32 %6 to i64
%9 = sext i32 %3 to i64
%10 = sext i32 %1 to i64
%11 = icmp sgt i32 %6, -1
%12 = icmp slt i32 %6, %3
%13 = and i1 %11, %12
br i1 %13, label %16, label %55
14: ; preds = %105, %139, %145, %55
%15 = phi i32 [ 0, %55 ], [ %106, %105 ], [ %140, %139 ], [ %152, %145 ]
ret i32 %15
16: ; preds = %5
%17 = getelementptr inbounds i8*, i8** %0, i64 %8
%18 = icmp sgt i32 %2, 0
%19 = icmp sle i32 %2, %4
%20 = and i1 %18, %19
br i1 %20, label %21, label %28
21: ; preds = %16
%22 = load i8*, i8** %17
%23 = zext i32 %7 to i64
%24 = getelementptr inbounds i8, i8* %22, i64 %23
%25 = load i8, i8* %24
%26 = icmp ne i8 %25, 0
%27 = zext i1 %26 to i32
br label %28
28: ; preds = %16, %21
%29 = phi i32 [ 0, %16 ], [ %27, %21 ]
%30 = icmp sgt i32 %2, -1
%31 = icmp slt i32 %2, %4
%32 = and i1 %30, %31
br i1 %32, label %33, label %41
33: ; preds = %28
%34 = load i8*, i8** %17
%35 = zext i32 %2 to i64
%36 = getelementptr inbounds i8, i8* %34, i64 %35
%37 = load i8, i8* %36
%38 = icmp ne i8 %37, 0
%39 = zext i1 %38 to i32
%40 = add nuw nsw i32 %29, %39
br label %41
41: ; preds = %33, %28
%42 = phi i32 [ %29, %28 ], [ %40, %33 ]
%43 = add nsw i32 %2, 1
%44 = icmp sgt i32 %2, -2
%45 = icmp slt i32 %43, %4
%46 = and i1 %44, %45
br i1 %46, label %47, label %57
47: ; preds = %41
%48 = load i8*, i8** %17
%49 = zext i32 %43 to i64
%50 = getelementptr inbounds i8, i8* %48, i64 %49
%51 = load i8, i8* %50
%52 = icmp ne i8 %51, 0
%53 = zext i1 %52 to i32
%54 = add nuw nsw i32 %42, %53
br label %57
55: ; preds = %5
%56 = icmp eq i32 %1, -2147483648
br i1 %56, label %14, label %57
57: ; preds = %41, %47, %55
%58 = phi i32 [ 0, %55 ], [ %54, %47 ], [ %42, %41 ]
%59 = add nsw i64 %8, 1
%60 = icmp ult i32 %1, -2147483647
%61 = icmp slt i64 %59, %9
%62 = and i1 %60, %61
br i1 %62, label %63, label %105
63: ; preds = %57
%64 = icmp eq i64 %59, %10
%65 = getelementptr inbounds i8*, i8** %0, i64 %59
%66 = icmp sgt i32 %2, 0
%67 = icmp sle i32 %2, %4
%68 = and i1 %66, %67
br i1 %68, label %69, label %77
69: ; preds = %63
%70 = load i8*, i8** %65
%71 = zext i32 %7 to i64
%72 = getelementptr inbounds i8, i8* %70, i64 %71
%73 = load i8, i8* %72
%74 = icmp ne i8 %73, 0
%75 = zext i1 %74 to i32
%76 = add nuw nsw i32 %58, %75
br label %77
77: ; preds = %63, %69
%78 = phi i32 [ %58, %63 ], [ %76, %69 ]
%79 = icmp slt i32 %2, 0
%80 = icmp sge i32 %2, %4
%81 = or i1 %79, %80
%82 = select i1 %81, i1 true, i1 %64
br i1 %82, label %91, label %83
83: ; preds = %77
%84 = load i8*, i8** %65
%85 = zext i32 %2 to i64
%86 = getelementptr inbounds i8, i8* %84, i64 %85
%87 = load i8, i8* %86
%88 = icmp ne i8 %87, 0
%89 = zext i1 %88 to i32
%90 = add nuw nsw i32 %78, %89
br label %91
91: ; preds = %77, %83
%92 = phi i32 [ %78, %77 ], [ %90, %83 ]
%93 = add nsw i32 %2, 1
%94 = icmp sgt i32 %2, -2
%95 = icmp slt i32 %93, %4
%96 = and i1 %94, %95
br i1 %96, label %97, label %105
97: ; preds = %91
%98 = load i8*, i8** %65
%99 = zext i32 %93 to i64
%100 = getelementptr inbounds i8, i8* %98, i64 %99
%101 = load i8, i8* %100
%102 = icmp ne i8 %101, 0
%103 = zext i1 %102 to i32
%104 = add nuw nsw i32 %92, %103
br label %105
105: ; preds = %97, %91, %57
%106 = phi i32 [ %58, %57 ], [ %92, %91 ], [ %104, %97 ]
%107 = add nsw i64 %8, 2
%108 = icmp sgt i32 %6, -3
%109 = icmp slt i64 %107, %9
%110 = and i1 %108, %109
br i1 %110, label %111, label %14
111: ; preds = %105
%112 = icmp eq i64 %107, %10
%113 = getelementptr inbounds i8*, i8** %0, i64 %107
%114 = icmp sgt i32 %2, 0
%115 = icmp sle i32 %2, %4
%116 = and i1 %114, %115
br i1 %116, label %117, label %125
117: ; preds = %111
%118 = load i8*, i8** %113
%119 = zext i32 %7 to i64
%120 = getelementptr inbounds i8, i8* %118, i64 %119
%121 = load i8, i8* %120
%122 = icmp ne i8 %121, 0
%123 = zext i1 %122 to i32
%124 = add nuw nsw i32 %106, %123
br label %125
125: ; preds = %111, %117
%126 = phi i32 [ %106, %111 ], [ %124, %117 ]
%127 = icmp slt i32 %2, 0
%128 = icmp sge i32 %2, %4
%129 = or i1 %127, %128
%130 = select i1 %129, i1 true, i1 %112
br i1 %130, label %139, label %131
131: ; preds = %125
%132 = load i8*, i8** %113
%133 = zext i32 %2 to i64
%134 = getelementptr inbounds i8, i8* %132, i64 %133
%135 = load i8, i8* %134
%136 = icmp ne i8 %135, 0
%137 = zext i1 %136 to i32
%138 = add nuw nsw i32 %126, %137
br label %139
139: ; preds = %125, %131
%140 = phi i32 [ %126, %125 ], [ %138, %131 ]
%141 = add nsw i32 %2, 1
%142 = icmp sgt i32 %2, -2
%143 = icmp slt i32 %141, %4
%144 = and i1 %142, %143
br i1 %144, label %145, label %14
145: ; preds = %139
%146 = load i8*, i8** %113
%147 = zext i32 %141 to i64
%148 = getelementptr inbounds i8, i8* %146, i64 %147
%149 = load i8, i8* %148
%150 = icmp ne i8 %149, 0
%151 = zext i1 %150 to i32
%152 = add nuw nsw i32 %140, %151
br label %14
}