#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int omp_get_num_threads();
int /*<<< orphan*/ printf(char *, int);
void diffusion_openmp(float *f1, float *f2, int nx, int ny, int nz, float ce,
                      float cw, float cn, float cs, float ct, float cb,
                      float cc, float dt, float **f_ret, float *time_ret,
                      int *count_ret) {
#pragma omp parallel
  {
    float time = 0.0;
    int count = 0;
    float *f1_t = f1;
    float *f2_t = f2;
#pragma omp master
    printf("%d threads running\n", omp_get_num_threads());
    do {
      int z;
#pragma omp for
      for (z = 0; z < nz; z++) {
        int y;
        for (y = 0; y < ny; y++) {
          int x;
          for (x = 0; x < nx; x++) {
            int c, w, e, n, s, b, t;
            c = x + y * nx + z * nx * ny;
            w = (x == 0) ? c : c - 1;
            e = (x == nx - 1) ? c : c + 1;
            n = (y == 0) ? c : c - nx;
            s = (y == ny - 1) ? c : c + nx;
            b = (z == 0) ? c : c - nx * ny;
            t = (z == nz - 1) ? c : c + nx * ny;
            f2_t[c] = cc * f1_t[c] + cw * f1_t[w] + ce * f1_t[e] +
                      cs * f1_t[s] + cn * f1_t[n] + cb * f1_t[b] + ct * f1_t[t];
          }
        }
      }
      float *t = f1_t;
      f1_t = f2_t;
      f2_t = t;
      time += dt;
      count++;
    } while (time + 0.5 * dt < 0.1);
#pragma omp master
    {
      *f_ret = f1_t;
      *time_ret = time;
      *count_ret = count;
    }
  }
  return;
}


x86 assembly (clang, -O0):
<diffusion_openmp>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
mov    0x18(%rbp),%rax
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
movss  %xmm0,-0x20(%rbp)
movss  %xmm1,-0x24(%rbp)
movss  %xmm2,-0x28(%rbp)
movss  %xmm3,-0x2c(%rbp)
movss  %xmm4,-0x30(%rbp)
movss  %xmm5,-0x34(%rbp)
movss  %xmm6,-0x38(%rbp)
movss  %xmm7,-0x3c(%rbp)
mov    %r9,-0x48(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4c(%rbp)
movl   $0x0,-0x50(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    $0x0,%al
call   1040 <omp_get_num_threads@plt>
mov    %eax,%esi
lea    0xe70(%rip),%rdi
call   1030 <printf@plt>
movl   $0x0,-0x64(%rbp)
mov    -0x64(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1424 <diffusion_openmp+0x304>
movl   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    1411 <diffusion_openmp+0x2f1>
movl   $0x0,-0x6c(%rbp)
mov    -0x6c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    13fe <diffusion_openmp+0x2de>
mov    -0x6c(%rbp),%eax
mov    -0x68(%rbp),%ecx
imul   -0x14(%rbp),%ecx
add    %ecx,%eax
mov    -0x64(%rbp),%ecx
imul   -0x14(%rbp),%ecx
imul   -0x18(%rbp),%ecx
add    %ecx,%eax
mov    %eax,-0x70(%rbp)
cmpl   $0x0,-0x6c(%rbp)
jne    1212 <diffusion_openmp+0xf2>
mov    -0x70(%rbp),%eax
mov    %eax,-0x94(%rbp)
jmp    121e <diffusion_openmp+0xfe>
mov    -0x70(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x94(%rbp)
mov    -0x94(%rbp),%eax
mov    %eax,-0x74(%rbp)
mov    -0x6c(%rbp),%eax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    1246 <diffusion_openmp+0x126>
mov    -0x70(%rbp),%eax
mov    %eax,-0x98(%rbp)
jmp    1252 <diffusion_openmp+0x132>
mov    -0x70(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x98(%rbp)
mov    -0x98(%rbp),%eax
mov    %eax,-0x78(%rbp)
cmpl   $0x0,-0x68(%rbp)
jne    1273 <diffusion_openmp+0x153>
mov    -0x70(%rbp),%eax
mov    %eax,-0x9c(%rbp)
jmp    127f <diffusion_openmp+0x15f>
mov    -0x70(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    %eax,-0x9c(%rbp)
mov    -0x9c(%rbp),%eax
mov    %eax,-0x7c(%rbp)
mov    -0x68(%rbp),%eax
mov    -0x18(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    12a7 <diffusion_openmp+0x187>
mov    -0x70(%rbp),%eax
mov    %eax,-0xa0(%rbp)
jmp    12b3 <diffusion_openmp+0x193>
mov    -0x70(%rbp),%eax
add    -0x14(%rbp),%eax
mov    %eax,-0xa0(%rbp)
mov    -0xa0(%rbp),%eax
mov    %eax,-0x80(%rbp)
cmpl   $0x0,-0x64(%rbp)
jne    12d4 <diffusion_openmp+0x1b4>
mov    -0x70(%rbp),%eax
mov    %eax,-0xa4(%rbp)
jmp    12e6 <diffusion_openmp+0x1c6>
mov    -0x70(%rbp),%eax
mov    -0x14(%rbp),%ecx
imul   -0x18(%rbp),%ecx
sub    %ecx,%eax
mov    %eax,-0xa4(%rbp)
mov    -0xa4(%rbp),%eax
mov    %eax,-0x84(%rbp)
mov    -0x64(%rbp),%eax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jne    1311 <diffusion_openmp+0x1f1>
mov    -0x70(%rbp),%eax
mov    %eax,-0xa8(%rbp)
jmp    1323 <diffusion_openmp+0x203>
mov    -0x70(%rbp),%eax
mov    -0x14(%rbp),%ecx
imul   -0x18(%rbp),%ecx
add    %ecx,%eax
mov    %eax,-0xa8(%rbp)
mov    -0xa8(%rbp),%eax
mov    %eax,-0x88(%rbp)
movss  -0x38(%rbp),%xmm1
mov    -0x58(%rbp),%rax
movslq -0x70(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movss  -0x24(%rbp),%xmm0
mov    -0x58(%rbp),%rax
movslq -0x74(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x20(%rbp),%xmm0
mov    -0x58(%rbp),%rax
movslq -0x78(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x2c(%rbp),%xmm1
mov    -0x58(%rbp),%rax
movslq -0x80(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x28(%rbp),%xmm0
mov    -0x58(%rbp),%rax
movslq -0x7c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  -0x34(%rbp),%xmm1
mov    -0x58(%rbp),%rax
movslq -0x84(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x30(%rbp),%xmm0
mov    -0x58(%rbp),%rax
movslq -0x88(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x60(%rbp),%rax
movslq -0x70(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x6c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x6c(%rbp)
jmp    11d2 <diffusion_openmp+0xb2>
jmp    1403 <diffusion_openmp+0x2e3>
mov    -0x68(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x68(%rbp)
jmp    11bf <diffusion_openmp+0x9f>
jmp    1416 <diffusion_openmp+0x2f6>
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    11ac <diffusion_openmp+0x8c>
mov    -0x58(%rbp),%rax
mov    %rax,-0x90(%rbp)
mov    -0x60(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x90(%rbp),%rax
mov    %rax,-0x60(%rbp)
movss  -0x3c(%rbp),%xmm0
addss  -0x4c(%rbp),%xmm0
movss  %xmm0,-0x4c(%rbp)
mov    -0x50(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
movss  -0x4c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movss  -0x3c(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
movsd  0xb94(%rip),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  0xb7c(%rip),%xmm0
ucomisd %xmm1,%xmm0
ja     11a5 <diffusion_openmp+0x85>
mov    -0x58(%rbp),%rcx
mov    -0x48(%rbp),%rax
mov    %rcx,(%rax)
movss  -0x4c(%rbp),%xmm0
mov    0x10(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x50(%rbp),%ecx
mov    0x18(%rbp),%rax
mov    %ecx,(%rax)
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<diffusion_openmp>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x58,%rsp
mov    %r9,0x50(%rsp)
movss  %xmm7,0x4(%rsp)
movss  %xmm6,0x20(%rsp)
movss  %xmm5,0x1c(%rsp)
movss  %xmm4,0x18(%rsp)
movss  %xmm3,0x14(%rsp)
movss  %xmm2,0x10(%rsp)
movss  %xmm1,0x34(%rsp)
movss  %xmm0,0x30(%rsp)
mov    %r8d,%r14d
mov    %ecx,%ebp
mov    %edx,%r13d
mov    %rsi,%r15
mov    %rdi,%rbx
xor    %eax,%eax
call   1040 <omp_get_num_threads@plt>
lea    0xe91(%rip),%rdi
mov    %eax,%esi
call   1030 <printf@plt>
movss  0x10(%rsp),%xmm15
movss  0x14(%rsp),%xmm14
movss  0x18(%rsp),%xmm13
movss  0x1c(%rsp),%xmm1
movss  0x20(%rsp),%xmm12
movss  0x4(%rsp),%xmm0
cvtss2sd %xmm0,%xmm9
lea    -0x1(%r13),%eax
lea    -0x1(%rbp),%ecx
mov    %ecx,0x2c(%rsp)
mov    %rbp,%rcx
mov    %rbp,0x48(%rsp)
imul   %r13d,%ebp
mov    %rbp,0x40(%rsp)
mov    %r14,%rcx
mov    %r14,0x38(%rsp)
lea    -0x1(%r14),%ecx
mov    %ecx,0x28(%rsp)
mov    %r13d,%edi
xorps  %xmm11,%xmm11
mulsd  0xe11(%rip),%xmm9
xor    %ecx,%ecx
movss  0x34(%rsp),%xmm8
movss  0x30(%rsp),%xmm10
jmp    1243 <diffusion_openmp+0x123>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
addss  0x4(%rsp),%xmm11
mov    0x24(%rsp),%ecx
add    $0x1,%ecx
xorps  %xmm0,%xmm0
cvtss2sd %xmm11,%xmm0
addsd  %xmm9,%xmm0
movsd  0xdd5(%rip),%xmm2
ucomisd %xmm0,%xmm2
mov    %rbx,%r15
mov    %rbp,%rbx
jbe    13c1 <diffusion_openmp+0x2a1>
mov    %ecx,0x24(%rsp)
mov    %r15,%rbp
cmpl   $0x0,0x38(%rsp)
jle    1210 <diffusion_openmp+0xf0>
xor    %ecx,%ecx
mov    %rcx,0x8(%rsp)
movl   $0x0,(%rsp)
jmp    128e <diffusion_openmp+0x16e>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    (%rsp),%edx
add    $0x1,%edx
mov    0x8(%rsp),%rcx
add    0x40(%rsp),%rcx
mov    %rcx,0x8(%rsp)
mov    %edx,(%rsp)
cmp    0x38(%rsp),%edx
je     1210 <diffusion_openmp+0xf0>
cmpl   $0x0,0x48(%rsp)
jle    1270 <diffusion_openmp+0x150>
mov    (%rsp),%ecx
test   %ecx,%ecx
mov    0x40(%rsp),%r10
mov    %r10d,%edx
cmove  %ecx,%edx
xor    %r12d,%r12d
cmp    0x28(%rsp),%ecx
cmove  %r12d,%r10d
mov    0x8(%rsp),%r9
add    %r9d,%r10d
mov    %r9d,%r11d
sub    %edx,%r11d
jmp    12d4 <diffusion_openmp+0x1b4>
add    $0x1,%r12d
add    %rdi,%r10
add    %rdi,%r11
add    %rdi,%r9
cmp    0x48(%rsp),%r12d
je     1270 <diffusion_openmp+0x150>
test   %r13d,%r13d
jle    12c0 <diffusion_openmp+0x1a0>
test   %r12d,%r12d
mov    %r13d,%edx
cmove  %r12d,%edx
movslq %r9d,%r8
cmp    0x2c(%rsp),%r12d
mov    %r13d,%ecx
mov    $0x0,%esi
cmove  %esi,%ecx
movslq %ecx,%r14
add    %r8,%r14
sub    %edx,%r8d
xor    %r15d,%r15d
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
lea    (%r9,%r15,1),%rdx
cmp    $0x1,%r15
mov    %edx,%ecx
adc    $0xffffffff,%ecx
movslq %ecx,%rcx
movss  (%rbx,%rcx,4),%xmm3
xor    %ecx,%ecx
cmp    %r15,%rax
setne  %cl
add    %edx,%ecx
movslq %ecx,%rcx
movss  (%rbx,%rcx,4),%xmm4
lea    (%r14,%r15,1),%ecx
movslq %ecx,%rcx
movss  (%rbx,%rcx,4),%xmm5
lea    (%r8,%r15,1),%ecx
movslq %ecx,%rcx
movss  (%rbx,%rcx,4),%xmm6
lea    (%r11,%r15,1),%ecx
movslq %ecx,%rcx
movss  (%rbx,%rcx,4),%xmm7
lea    (%r10,%r15,1),%ecx
movslq %ecx,%rcx
movss  (%rbx,%rcx,4),%xmm2
movslq %edx,%rcx
mulss  %xmm8,%xmm3
movss  (%rbx,%rcx,4),%xmm0
mulss  %xmm12,%xmm0
addss  %xmm3,%xmm0
mulss  %xmm10,%xmm4
addss  %xmm0,%xmm4
mulss  %xmm14,%xmm5
addss  %xmm4,%xmm5
mulss  %xmm15,%xmm6
addss  %xmm5,%xmm6
mulss  %xmm1,%xmm7
addss  %xmm6,%xmm7
mulss  %xmm13,%xmm2
addss  %xmm7,%xmm2
movss  %xmm2,0x0(%rbp,%rcx,4)
add    $0x1,%r15
cmp    %r15,%rdi
jne    1310 <diffusion_openmp+0x1f0>
jmp    12c0 <diffusion_openmp+0x1a0>
mov    0x50(%rsp),%rax
mov    %rbp,(%rax)
mov    0x90(%rsp),%rax
movss  %xmm11,(%rax)
mov    0x98(%rsp),%rax
mov    %ecx,(%rax)
add    $0x58,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [20 x i8] c"%d threads running\0A\00"
define void @diffusion_openmp(float* %0, float* %1, i32 %2, i32 %3, i32 %4, float %5, float %6, float %7, float %8, float %9, float %10, float %11, float %12, float** %13, float* %14, i32* %15) {
%17 = alloca float*
%18 = alloca float*
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca float
%23 = alloca float
%24 = alloca float
%25 = alloca float
%26 = alloca float
%27 = alloca float
%28 = alloca float
%29 = alloca float
%30 = alloca float**
%31 = alloca float*
%32 = alloca i32*
%33 = alloca float
%34 = alloca i32
%35 = alloca float*
%36 = alloca float*
%37 = alloca i32
%38 = alloca i32
%39 = alloca i32
%40 = alloca i32
%41 = alloca i32
%42 = alloca i32
%43 = alloca i32
%44 = alloca i32
%45 = alloca i32
%46 = alloca i32
%47 = alloca float*
store float* %0, float** %17
store float* %1, float** %18
store i32 %2, i32* %19
store i32 %3, i32* %20
store i32 %4, i32* %21
store float %5, float* %22
store float %6, float* %23
store float %7, float* %24
store float %8, float* %25
store float %9, float* %26
store float %10, float* %27
store float %11, float* %28
store float %12, float* %29
store float** %13, float*** %30
store float* %14, float** %31
store i32* %15, i32** %32
store float 0.000000e+00, float* %33
store i32 0, i32* %34
%48 = load float*, float** %17
store float* %48, float** %35
%49 = load float*, float** %18
store float* %49, float** %36
%50 = call i32 (...) @omp_get_num_threads()
%51 = call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0), i32 %50)
br label %52
52: ; preds = %220, %16
store i32 0, i32* %37
br label %53
53: ; preds = %208, %52
%54 = load i32, i32* %37
%55 = load i32, i32* %21
%56 = icmp slt i32 %54, %55
br i1 %56, label %57, label %211
57: ; preds = %53
store i32 0, i32* %38
br label %58
58: ; preds = %204, %57
%59 = load i32, i32* %38
%60 = load i32, i32* %20
%61 = icmp slt i32 %59, %60
br i1 %61, label %62, label %207
62: ; preds = %58
store i32 0, i32* %39
br label %63
63: ; preds = %200, %62
%64 = load i32, i32* %39
%65 = load i32, i32* %19
%66 = icmp slt i32 %64, %65
br i1 %66, label %67, label %203
67: ; preds = %63
%68 = load i32, i32* %39
%69 = load i32, i32* %38
%70 = load i32, i32* %19
%71 = mul nsw i32 %69, %70
%72 = add nsw i32 %68, %71
%73 = load i32, i32* %37
%74 = load i32, i32* %19
%75 = mul nsw i32 %73, %74
%76 = load i32, i32* %20
%77 = mul nsw i32 %75, %76
%78 = add nsw i32 %72, %77
store i32 %78, i32* %40
%79 = load i32, i32* %39
%80 = icmp eq i32 %79, 0
br i1 %80, label %81, label %83
81: ; preds = %67
%82 = load i32, i32* %40
br label %86
83: ; preds = %67
%84 = load i32, i32* %40
%85 = sub nsw i32 %84, 1
br label %86
86: ; preds = %83, %81
%87 = phi i32 [ %82, %81 ], [ %85, %83 ]
store i32 %87, i32* %41
%88 = load i32, i32* %39
%89 = load i32, i32* %19
%90 = sub nsw i32 %89, 1
%91 = icmp eq i32 %88, %90
br i1 %91, label %92, label %94
92: ; preds = %86
%93 = load i32, i32* %40
br label %97
94: ; preds = %86
%95 = load i32, i32* %40
%96 = add nsw i32 %95, 1
br label %97
97: ; preds = %94, %92
%98 = phi i32 [ %93, %92 ], [ %96, %94 ]
store i32 %98, i32* %42
%99 = load i32, i32* %38
%100 = icmp eq i32 %99, 0
br i1 %100, label %101, label %103
101: ; preds = %97
%102 = load i32, i32* %40
br label %107
103: ; preds = %97
%104 = load i32, i32* %40
%105 = load i32, i32* %19
%106 = sub nsw i32 %104, %105
br label %107
107: ; preds = %103, %101
%108 = phi i32 [ %102, %101 ], [ %106, %103 ]
store i32 %108, i32* %43
%109 = load i32, i32* %38
%110 = load i32, i32* %20
%111 = sub nsw i32 %110, 1
%112 = icmp eq i32 %109, %111
br i1 %112, label %113, label %115
113: ; preds = %107
%114 = load i32, i32* %40
br label %119
115: ; preds = %107
%116 = load i32, i32* %40
%117 = load i32, i32* %19
%118 = add nsw i32 %116, %117
br label %119
119: ; preds = %115, %113
%120 = phi i32 [ %114, %113 ], [ %118, %115 ]
store i32 %120, i32* %44
%121 = load i32, i32* %37
%122 = icmp eq i32 %121, 0
br i1 %122, label %123, label %125
123: ; preds = %119
%124 = load i32, i32* %40
br label %131
125: ; preds = %119
%126 = load i32, i32* %40
%127 = load i32, i32* %19
%128 = load i32, i32* %20
%129 = mul nsw i32 %127, %128
%130 = sub nsw i32 %126, %129
br label %131
131: ; preds = %125, %123
%132 = phi i32 [ %124, %123 ], [ %130, %125 ]
store i32 %132, i32* %45
%133 = load i32, i32* %37
%134 = load i32, i32* %21
%135 = sub nsw i32 %134, 1
%136 = icmp eq i32 %133, %135
br i1 %136, label %137, label %139
137: ; preds = %131
%138 = load i32, i32* %40
br label %145
139: ; preds = %131
%140 = load i32, i32* %40
%141 = load i32, i32* %19
%142 = load i32, i32* %20
%143 = mul nsw i32 %141, %142
%144 = add nsw i32 %140, %143
br label %145
145: ; preds = %139, %137
%146 = phi i32 [ %138, %137 ], [ %144, %139 ]
store i32 %146, i32* %46
%147 = load float, float* %28
%148 = load float*, float** %35
%149 = load i32, i32* %40
%150 = sext i32 %149 to i64
%151 = getelementptr inbounds float, float* %148, i64 %150
%152 = load float, float* %151
%153 = load float, float* %23
%154 = load float*, float** %35
%155 = load i32, i32* %41
%156 = sext i32 %155 to i64
%157 = getelementptr inbounds float, float* %154, i64 %156
%158 = load float, float* %157
%159 = fmul float %153, %158
%160 = call float @llvm.fmuladd.f32(float %147, float %152, float %159)
%161 = load float, float* %22
%162 = load float*, float** %35
%163 = load i32, i32* %42
%164 = sext i32 %163 to i64
%165 = getelementptr inbounds float, float* %162, i64 %164
%166 = load float, float* %165
%167 = call float @llvm.fmuladd.f32(float %161, float %166, float %160)
%168 = load float, float* %25
%169 = load float*, float** %35
%170 = load i32, i32* %44
%171 = sext i32 %170 to i64
%172 = getelementptr inbounds float, float* %169, i64 %171
%173 = load float, float* %172
%174 = call float @llvm.fmuladd.f32(float %168, float %173, float %167)
%175 = load float, float* %24
%176 = load float*, float** %35
%177 = load i32, i32* %43
%178 = sext i32 %177 to i64
%179 = getelementptr inbounds float, float* %176, i64 %178
%180 = load float, float* %179
%181 = call float @llvm.fmuladd.f32(float %175, float %180, float %174)
%182 = load float, float* %27
%183 = load float*, float** %35
%184 = load i32, i32* %45
%185 = sext i32 %184 to i64
%186 = getelementptr inbounds float, float* %183, i64 %185
%187 = load float, float* %186
%188 = call float @llvm.fmuladd.f32(float %182, float %187, float %181)
%189 = load float, float* %26
%190 = load float*, float** %35
%191 = load i32, i32* %46
%192 = sext i32 %191 to i64
%193 = getelementptr inbounds float, float* %190, i64 %192
%194 = load float, float* %193
%195 = call float @llvm.fmuladd.f32(float %189, float %194, float %188)
%196 = load float*, float** %36
%197 = load i32, i32* %40
%198 = sext i32 %197 to i64
%199 = getelementptr inbounds float, float* %196, i64 %198
store float %195, float* %199
br label %200
200: ; preds = %145
%201 = load i32, i32* %39
%202 = add nsw i32 %201, 1
store i32 %202, i32* %39
br label %63
203: ; preds = %63
br label %204
204: ; preds = %203
%205 = load i32, i32* %38
%206 = add nsw i32 %205, 1
store i32 %206, i32* %38
br label %58
207: ; preds = %58
br label %208
208: ; preds = %207
%209 = load i32, i32* %37
%210 = add nsw i32 %209, 1
store i32 %210, i32* %37
br label %53
211: ; preds = %53
%212 = load float*, float** %35
store float* %212, float** %47
%213 = load float*, float** %36
store float* %213, float** %35
%214 = load float*, float** %47
store float* %214, float** %36
%215 = load float, float* %29
%216 = load float, float* %33
%217 = fadd float %216, %215
store float %217, float* %33
%218 = load i32, i32* %34
%219 = add nsw i32 %218, 1
store i32 %219, i32* %34
br label %220
220: ; preds = %211
%221 = load float, float* %33
%222 = fpext float %221 to double
%223 = load float, float* %29
%224 = fpext float %223 to double
%225 = call double @llvm.fmuladd.f64(double 5.000000e-01, double %224, double %222)
%226 = fcmp olt double %225, 1.000000e-01
br i1 %226, label %52, label %227
227: ; preds = %220
%228 = load float*, float** %35
%229 = load float**, float*** %30
store float* %228, float** %229
%230 = load float, float* %33
%231 = load float*, float** %31
store float %230, float* %231
%232 = load i32, i32* %34
%233 = load i32*, i32** %32
store i32 %232, i32* %233
ret void
}

LLVM IR (-O2):
@.str = [20 x i8] c"%d threads running\0A\00"
define void @diffusion_openmp(float* %0, float* %1, i32 %2, i32 %3, i32 %4, float %5, float %6, float %7, float %8, float %9, float %10, float %11, float %12, float** nocapture writeonly %13, float* nocapture writeonly %14, i32* nocapture writeonly %15) {
%17 = tail call i32 (...) @omp_get_num_threads()
%18 = tail call i32 @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str, i64 0, i64 0), i32 %17)
%19 = icmp sgt i32 %4, 0
%20 = fpext float %12 to double
%21 = icmp sgt i32 %3, 0
%22 = icmp sgt i32 %2, 0
%23 = add nsw i32 %2, -1
%24 = add nsw i32 %3, -1
%25 = mul nsw i32 %3, %2
%26 = add nsw i32 %4, -1
%27 = zext i32 %23 to i64
%28 = zext i32 %2 to i64
br label %29
29: ; preds = %102, %16
%30 = phi float* [ %1, %16 ], [ %31, %102 ]
%31 = phi float* [ %0, %16 ], [ %30, %102 ]
%32 = phi i32 [ 0, %16 ], [ %104, %102 ]
%33 = phi float [ 0.000000e+00, %16 ], [ %103, %102 ]
br i1 %19, label %34, label %102
34: ; preds = %29, %99
%35 = phi i32 [ %100, %99 ], [ 0, %29 ]
br i1 %21, label %36, label %99
36: ; preds = %34
%37 = mul i32 %35, %3
%38 = icmp eq i32 %35, 0
%39 = select i1 %38, i32 0, i32 %25
%40 = icmp eq i32 %35, %26
%41 = select i1 %40, i32 0, i32 %25
br label %42
42: ; preds = %36, %96
%43 = phi i32 [ 0, %36 ], [ %97, %96 ]
br i1 %22, label %44, label %96
44: ; preds = %42
%45 = add i32 %43, %37
%46 = mul i32 %45, %2
%47 = icmp eq i32 %43, 0
%48 = select i1 %47, i32 0, i32 %2
%49 = icmp eq i32 %43, %24
%50 = select i1 %49, i32 0, i32 %2
br label %51
51: ; preds = %44, %51
%52 = phi i64 [ 0, %44 ], [ %94, %51 ]
%53 = trunc i64 %52 to i32
%54 = add i32 %46, %53
%55 = icmp ne i64 %52, 0
%56 = sext i1 %55 to i32
%57 = add nsw i32 %54, %56
%58 = icmp ne i64 %52, %27
%59 = zext i1 %58 to i32
%60 = add nsw i32 %54, %59
%61 = sub nsw i32 %54, %48
%62 = add nsw i32 %54, %50
%63 = sub nsw i32 %54, %39
%64 = add nsw i32 %54, %41
%65 = sext i32 %54 to i64
%66 = getelementptr inbounds float, float* %31, i64 %65
%67 = load float, float* %66
%68 = sext i32 %57 to i64
%69 = getelementptr inbounds float, float* %31, i64 %68
%70 = load float, float* %69
%71 = fmul float %70, %6
%72 = tail call float @llvm.fmuladd.f32(float %11, float %67, float %71)
%73 = sext i32 %60 to i64
%74 = getelementptr inbounds float, float* %31, i64 %73
%75 = load float, float* %74
%76 = tail call float @llvm.fmuladd.f32(float %5, float %75, float %72)
%77 = sext i32 %62 to i64
%78 = getelementptr inbounds float, float* %31, i64 %77
%79 = load float, float* %78
%80 = tail call float @llvm.fmuladd.f32(float %8, float %79, float %76)
%81 = sext i32 %61 to i64
%82 = getelementptr inbounds float, float* %31, i64 %81
%83 = load float, float* %82
%84 = tail call float @llvm.fmuladd.f32(float %7, float %83, float %80)
%85 = sext i32 %63 to i64
%86 = getelementptr inbounds float, float* %31, i64 %85
%87 = load float, float* %86
%88 = tail call float @llvm.fmuladd.f32(float %10, float %87, float %84)
%89 = sext i32 %64 to i64
%90 = getelementptr inbounds float, float* %31, i64 %89
%91 = load float, float* %90
%92 = tail call float @llvm.fmuladd.f32(float %9, float %91, float %88)
%93 = getelementptr inbounds float, float* %30, i64 %65
store float %92, float* %93
%94 = add nuw nsw i64 %52, 1
%95 = icmp eq i64 %94, %28
br i1 %95, label %96, label %51
96: ; preds = %51, %42
%97 = add nuw nsw i32 %43, 1
%98 = icmp eq i32 %97, %3
br i1 %98, label %99, label %42
99: ; preds = %96, %34
%100 = add nuw nsw i32 %35, 1
%101 = icmp eq i32 %100, %4
br i1 %101, label %102, label %34
102: ; preds = %99, %29
%103 = fadd float %33, %12
%104 = add nuw nsw i32 %32, 1
%105 = fpext float %103 to double
%106 = tail call double @llvm.fmuladd.f64(double %20, double 5.000000e-01, double %105)
%107 = fcmp olt double %106, 1.000000e-01
br i1 %107, label %29, label %108
108: ; preds = %102
store float* %30, float** %13
store float %103, float* %14
store i32 %104, i32* %15
ret void
}