void laplacian(double *v1, double *v2, int dim_m, int dim_n) {
  int m = dim_m;
#pragma omp parallel for schedule(static)
  for (int j = 1; j < dim_m - 1; ++j) {
    for (int i = 1; i < dim_n - 1; ++i) {
      double phi_e = v1[(j + 0) * dim_m + i + 1];
      double phi_w = v1[(j + 0) * dim_m + i - 1];
      double phi_n = v1[(j + 1) * dim_m + i + 0];
      double phi_s = v1[(j - 1) * dim_m + i + 0];
      double phi = 0.25 * (phi_e + phi_w + phi_n + phi_s);
      v2[j * dim_m + i] = phi;
    }
  }
}


x86 assembly (clang, -O0):
<laplacian>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movl   $0x1,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    122d <laplacian+0x12d>
movl   $0x1,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    -0x18(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    121a <laplacian+0x11a>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x0,%ecx
imul   -0x14(%rbp),%ecx
add    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x0,%ecx
imul   -0x14(%rbp),%ecx
add    -0x24(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
imul   -0x14(%rbp),%ecx
add    -0x24(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
imul   -0x14(%rbp),%ecx
add    -0x24(%rbp),%ecx
add    $0x0,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x30(%rbp),%xmm1
addsd  -0x38(%rbp),%xmm1
addsd  -0x40(%rbp),%xmm1
addsd  -0x48(%rbp),%xmm1
movsd  0xe18(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
imul   -0x14(%rbp),%ecx
add    -0x24(%rbp),%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1137 <laplacian+0x37>
jmp    121f <laplacian+0x11f>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    111f <laplacian+0x1f>
pop    %rbp
ret

x86 assembly (clang, -O2):
<laplacian>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rsi,-0x50(%rsp)
mov    %rdi,-0x58(%rsp)
cmp    $0x3,%edx
jl     1333 <laplacian+0x233>
lea    -0x1(%rcx),%edi
mov    %edx,%eax
mov    %rax,-0x8(%rsp)
add    $0xffffffff,%edx
mov    -0x50(%rsp),%rax
lea    0x8(%rax),%rbp
lea    (%rax,%rdi,8),%rbx
mov    -0x58(%rsp),%rsi
lea    0x8(%rsi),%rax
mov    %rax,-0x40(%rsp)
lea    (%rsi,%rdi,8),%rax
mov    %rax,-0x28(%rsp)
lea    (%rsi,%rdi,8),%rax
add    $0x8,%rax
mov    %rbp,-0x18(%rsp)
cmp    %rax,%rbp
setb   %al
mov    %rbx,-0x20(%rsp)
cmp    %rsi,%rbx
seta   %bl
mov    %rdi,-0x10(%rsp)
add    $0xffffffffffffffff,%rdi
and    %al,%bl
mov    %bl,-0x59(%rsp)
mov    %rdi,%r11
and    $0xfffffffffffffffe,%r11
mov    %rdi,-0x48(%rsp)
or     $0x1,%rdi
mov    %rdi,-0x30(%rsp)
lea    0x10(%rsi),%rax
mov    %rax,-0x38(%rsp)
mov    $0x1,%r13d
movsd  0xe69(%rip),%xmm0
movapd 0xe51(%rip),%xmm1
jmp    11d3 <laplacian+0xd3>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0x1,%r13
mov    %r13,%r10
mov    %r10,%r13
cmp    %rdx,%r10
je     1333 <laplacian+0x233>
cmp    $0x2,%ecx
jle    11c0 <laplacian+0xc0>
mov    %r13,%r9
mov    -0x8(%rsp),%rax
imul   %rax,%r9
lea    0x1(%r13),%r10
mov    %r10,%r12
imul   %rax,%r12
add    $0xffffffffffffffff,%r13
imul   %rax,%r13
mov    $0x1,%r8d
cmpq   $0x2,-0x48(%rsp)
jb     12c0 <laplacian+0x1c0>
mov    -0x18(%rsp),%rax
lea    (%rax,%r9,8),%r14
mov    -0x20(%rsp),%rax
lea    (%rax,%r9,8),%rax
mov    -0x40(%rsp),%rsi
lea    (%rsi,%r13,8),%r15
mov    -0x28(%rsp),%rdi
lea    (%rdi,%r13,8),%rbx
lea    (%rsi,%r12,8),%rsi
lea    (%rdi,%r12,8),%rdi
cmp    %rbx,%r14
setb   %bpl
cmp    %rax,%r15
setb   %bl
and    %bpl,%bl
cmp    %rdi,%r14
setb   %dil
cmp    %rax,%rsi
setb   %al
and    %dil,%al
or     %bl,%al
or     -0x59(%rsp),%al
jne    12c0 <laplacian+0x1c0>
mov    -0x38(%rsp),%rax
lea    (%rax,%r9,8),%rbx
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
movupd -0x10(%rbx,%rax,8),%xmm2
movupd (%rbx,%rax,8),%xmm3
addpd  %xmm2,%xmm3
movupd (%rsi,%rax,8),%xmm2
addpd  %xmm3,%xmm2
movupd (%r15,%rax,8),%xmm3
addpd  %xmm2,%xmm3
mulpd  %xmm1,%xmm3
movupd %xmm3,(%r14,%rax,8)
add    $0x2,%rax
cmp    %rax,%r11
jne    1270 <laplacian+0x170>
mov    -0x30(%rsp),%r8
cmp    %r11,-0x48(%rsp)
je     11c7 <laplacian+0xc7>
cs nopw 0x0(%rax,%rax,1)
nop
mov    %rdx,%r14
mov    %rcx,%rdx
add    %r8,%r13
mov    -0x58(%rsp),%rax
lea    (%rax,%r13,8),%rsi
add    %r8,%r12
lea    (%rax,%r12,8),%rbx
add    %r8,%r9
mov    -0x40(%rsp),%rax
lea    (%rax,%r9,8),%rax
mov    -0x50(%rsp),%rcx
lea    (%rcx,%r9,8),%rbp
mov    -0x10(%rsp),%rcx
sub    %r8,%rcx
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
movsd  (%rax,%rdi,8),%xmm2
addsd  -0x10(%rax,%rdi,8),%xmm2
addsd  (%rbx,%rdi,8),%xmm2
addsd  (%rsi,%rdi,8),%xmm2
mulsd  %xmm0,%xmm2
movsd  %xmm2,0x0(%rbp,%rdi,8)
add    $0x1,%rdi
cmp    %rdi,%rcx
jne    1300 <laplacian+0x200>
mov    %rdx,%rcx
mov    %r14,%rdx
jmp    11c7 <laplacian+0xc7>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @laplacian(double* %0, double* %1, i32 %2, i32 %3) {
%5 = alloca double*
%6 = alloca double*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
store double* %0, double** %5
store double* %1, double** %6
store i32 %2, i32* %7
store i32 %3, i32* %8
%17 = load i32, i32* %7
store i32 %17, i32* %9
store i32 1, i32* %10
br label %18
18: ; preds = %95, %4
%19 = load i32, i32* %10
%20 = load i32, i32* %7
%21 = sub nsw i32 %20, 1
%22 = icmp slt i32 %19, %21
br i1 %22, label %23, label %98
23: ; preds = %18
store i32 1, i32* %11
br label %24
24: ; preds = %91, %23
%25 = load i32, i32* %11
%26 = load i32, i32* %8
%27 = sub nsw i32 %26, 1
%28 = icmp slt i32 %25, %27
br i1 %28, label %29, label %94
29: ; preds = %24
%30 = load double*, double** %5
%31 = load i32, i32* %10
%32 = add nsw i32 %31, 0
%33 = load i32, i32* %7
%34 = mul nsw i32 %32, %33
%35 = load i32, i32* %11
%36 = add nsw i32 %34, %35
%37 = add nsw i32 %36, 1
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds double, double* %30, i64 %38
%40 = load double, double* %39
store double %40, double* %12
%41 = load double*, double** %5
%42 = load i32, i32* %10
%43 = add nsw i32 %42, 0
%44 = load i32, i32* %7
%45 = mul nsw i32 %43, %44
%46 = load i32, i32* %11
%47 = add nsw i32 %45, %46
%48 = sub nsw i32 %47, 1
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds double, double* %41, i64 %49
%51 = load double, double* %50
store double %51, double* %13
%52 = load double*, double** %5
%53 = load i32, i32* %10
%54 = add nsw i32 %53, 1
%55 = load i32, i32* %7
%56 = mul nsw i32 %54, %55
%57 = load i32, i32* %11
%58 = add nsw i32 %56, %57
%59 = add nsw i32 %58, 0
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds double, double* %52, i64 %60
%62 = load double, double* %61
store double %62, double* %14
%63 = load double*, double** %5
%64 = load i32, i32* %10
%65 = sub nsw i32 %64, 1
%66 = load i32, i32* %7
%67 = mul nsw i32 %65, %66
%68 = load i32, i32* %11
%69 = add nsw i32 %67, %68
%70 = add nsw i32 %69, 0
%71 = sext i32 %70 to i64
%72 = getelementptr inbounds double, double* %63, i64 %71
%73 = load double, double* %72
store double %73, double* %15
%74 = load double, double* %12
%75 = load double, double* %13
%76 = fadd double %74, %75
%77 = load double, double* %14
%78 = fadd double %76, %77
%79 = load double, double* %15
%80 = fadd double %78, %79
%81 = fmul double 2.500000e-01, %80
store double %81, double* %16
%82 = load double, double* %16
%83 = load double*, double** %6
%84 = load i32, i32* %10
%85 = load i32, i32* %7
%86 = mul nsw i32 %84, %85
%87 = load i32, i32* %11
%88 = add nsw i32 %86, %87
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds double, double* %83, i64 %89
store double %82, double* %90
br label %91
91: ; preds = %29
%92 = load i32, i32* %11
%93 = add nsw i32 %92, 1
store i32 %93, i32* %11
br label %24
94: ; preds = %24
br label %95
95: ; preds = %94
%96 = load i32, i32* %10
%97 = add nsw i32 %96, 1
store i32 %97, i32* %10
br label %18
98: ; preds = %18
ret void
}

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