int getNeighbours(int row_coord, int col_coord, int rows, int cols,
                  int univ[][cols]) {
  int i, j;
  int live_neighbours = 0;
  for (i = row_coord - 1; i <= row_coord + 1; i++) {
    for (j = col_coord - 1; j <= col_coord + 1; j++) {
      if (univ[(i + rows) % rows][(j + cols) % cols] == 1) {
        live_neighbours++;
      }
    }
  }
  if (univ[row_coord][col_coord] == 1) {
    live_neighbours--;
  }
  return live_neighbours;
}


x86 assembly (clang, -O0):
<getNeighbours>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
mov    %ecx,-0x10(%rbp)
mov    %r8,-0x18(%rbp)
mov    -0x10(%rbp),%eax
mov    %rax,-0x30(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x4(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x4(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jg     11ce <getNeighbours+0xce>
mov    -0x8(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x8(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jg     11bb <getNeighbours+0xbb>
mov    -0x18(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x1c(%rbp),%eax
add    -0xc(%rbp),%eax
cltd
idivl  -0xc(%rbp)
mov    -0x40(%rbp),%rax
mov    %edx,%ecx
mov    -0x30(%rbp),%rdx
movslq %ecx,%rcx
imul   %rdx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%eax
add    -0x10(%rbp),%eax
cltd
idivl  -0x10(%rbp)
mov    -0x38(%rbp),%rax
movslq %edx,%rcx
cmpl   $0x1,(%rax,%rcx,4)
jne    11a8 <getNeighbours+0xa8>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11ad <getNeighbours+0xad>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1145 <getNeighbours+0x45>
jmp    11c0 <getNeighbours+0xc0>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    112b <getNeighbours+0x2b>
mov    -0x30(%rbp),%rdx
mov    -0x18(%rbp),%rax
movslq -0x4(%rbp),%rcx
imul   %rdx,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
movslq -0x8(%rbp),%rcx
cmpl   $0x1,(%rax,%rcx,4)
jne    11fc <getNeighbours+0xfc>
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<getNeighbours>:
push   %r15
push   %r14
push   %rbx
mov    %edx,%r9d
mov    %ecx,%r10d
lea    (%rdi,%r9,1),%eax
add    $0xffffffff,%eax
cltd
idiv   %r9d
movslq %edx,%rax
imul   %r10,%rax
lea    (%r8,%rax,4),%r14
lea    (%rsi,%rcx,1),%eax
add    $0xffffffff,%eax
cltd
idiv   %ecx
movslq %edx,%r11
lea    (%rsi,%rcx,1),%eax
cltd
idiv   %ecx
movslq %edx,%rbx
lea    (%rsi,%rcx,1),%eax
add    $0x1,%eax
cltd
idiv   %ecx
movslq %edx,%r15
lea    (%rdi,%r9,1),%eax
cltd
idiv   %r9d
movslq %edx,%rax
imul   %r10,%rax
lea    (%r8,%rax,4),%rcx
lea    (%rdi,%r9,1),%eax
add    $0x1,%eax
cltd
idiv   %r9d
movslq %edx,%rax
imul   %r10,%rax
lea    (%r8,%rax,4),%rax
movd   (%r14,%r15,4),%xmm1
movd   (%rcx,%r11,4),%xmm0
punpckldq %xmm0,%xmm1
movd   (%r14,%r11,4),%xmm0
movd   (%r14,%rbx,4),%xmm2
punpckldq %xmm2,%xmm0
punpcklqdq %xmm1,%xmm0
movd   (%rcx,%r15,4),%xmm1
movd   (%rcx,%rbx,4),%xmm2
punpckldq %xmm1,%xmm2
movd   (%rax,%r11,4),%xmm1
movd   (%rax,%rbx,4),%xmm3
punpckldq %xmm3,%xmm1
punpcklqdq %xmm1,%xmm2
xor    %edx,%edx
cmpl   $0x1,(%rax,%r15,4)
sete   %dl
movslq %edi,%rax
imul   %r10,%rax
lea    (%r8,%rax,4),%rax
movslq %esi,%rsi
xor    %ecx,%ecx
cmpl   $0x1,(%rax,%rsi,4)
movdqa 0xe29(%rip),%xmm1
sete   %cl
pcmpeqd %xmm1,%xmm2
pcmpeqd %xmm1,%xmm0
packssdw %xmm2,%xmm0
packsswb %xmm0,%xmm0
pmovmskb %xmm0,%eax
mov    %eax,%ebx
shr    %bl
and    $0x55,%bl
sub    %bl,%al
mov    %eax,%ebx
and    $0x33,%bl
shr    $0x2,%al
and    $0x33,%al
add    %bl,%al
mov    %eax,%ebx
shr    $0x4,%bl
add    %al,%bl
and    $0xf,%bl
movzbl %bl,%eax
add    %edx,%eax
sub    %ecx,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
define i32 @getNeighbours(i32 %0, i32 %1, i32 %2, i32 %3, i32* nocapture %4) {
%6 = zext i32 %3 to i64
%7 = add nsw i32 %0, -1
%8 = add nsw i32 %1, -1
%9 = add nsw i32 %7, %2
%10 = srem i32 %9, %2
%11 = sext i32 %10 to i64
%12 = mul nsw i64 %11, %6
%13 = getelementptr inbounds i32, i32* %4, i64 %12
%14 = add nsw i32 %8, %3
%15 = srem i32 %14, %3
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i32, i32* %13, i64 %16
%18 = load i32, i32* %17
%19 = add nsw i32 %1, %3
%20 = srem i32 %19, %3
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds i32, i32* %13, i64 %21
%23 = load i32, i32* %22
%24 = add nsw i32 %1, 1
%25 = add nsw i32 %24, %3
%26 = srem i32 %25, %3
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i32, i32* %13, i64 %27
%29 = load i32, i32* %28
%30 = add nsw i32 %0, %2
%31 = srem i32 %30, %2
%32 = sext i32 %31 to i64
%33 = mul nsw i64 %32, %6
%34 = getelementptr inbounds i32, i32* %4, i64 %33
%35 = getelementptr inbounds i32, i32* %34, i64 %16
%36 = load i32, i32* %35
%37 = add nsw i32 %1, %3
%38 = srem i32 %37, %3
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i32, i32* %34, i64 %39
%41 = load i32, i32* %40
%42 = add nsw i32 %1, 1
%43 = add nsw i32 %42, %3
%44 = srem i32 %43, %3
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds i32, i32* %34, i64 %45
%47 = load i32, i32* %46
%48 = add nsw i32 %0, 1
%49 = add nsw i32 %48, %2
%50 = srem i32 %49, %2
%51 = sext i32 %50 to i64
%52 = mul nsw i64 %51, %6
%53 = getelementptr inbounds i32, i32* %4, i64 %52
%54 = getelementptr inbounds i32, i32* %53, i64 %16
%55 = load i32, i32* %54
%56 = add nsw i32 %1, %3
%57 = srem i32 %56, %3
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds i32, i32* %53, i64 %58
%60 = load i32, i32* %59
%61 = insertelement <8 x i32> poison, i32 %18, i64 0
%62 = insertelement <8 x i32> %61, i32 %23, i64 1
%63 = insertelement <8 x i32> %62, i32 %29, i64 2
%64 = insertelement <8 x i32> %63, i32 %36, i64 3
%65 = insertelement <8 x i32> %64, i32 %41, i64 4
%66 = insertelement <8 x i32> %65, i32 %47, i64 5
%67 = insertelement <8 x i32> %66, i32 %55, i64 6
%68 = insertelement <8 x i32> %67, i32 %60, i64 7
%69 = icmp eq <8 x i32> %68, <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
%70 = add nsw i32 %1, 1
%71 = add nsw i32 %70, %3
%72 = srem i32 %71, %3
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds i32, i32* %53, i64 %73
%75 = load i32, i32* %74
%76 = icmp eq i32 %75, 1
%77 = zext i1 %76 to i32
%78 = sext i32 %0 to i64
%79 = mul nsw i64 %6, %78
%80 = getelementptr inbounds i32, i32* %4, i64 %79
%81 = sext i32 %1 to i64
%82 = getelementptr inbounds i32, i32* %80, i64 %81
%83 = load i32, i32* %82
%84 = icmp eq i32 %83, 1
%85 = sext i1 %84 to i32
%86 = bitcast <8 x i1> %69 to i8
%87 = call i8 @llvm.ctpop.i8(i8 %86)
%88 = zext i8 %87 to i32
%89 = add nuw nsw i32 %88, %77
%90 = add nsw i32 %89, %85
ret i32 %90
}