#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 /*<<< orphan*/ limited_deriv1(float *, float const *, int);
int /*<<< orphan*/ limited_derivk(float *, float const *, int, int);
void central2d_predict(float *restrict v, float *restrict scratch,
                       const float *restrict u, const float *restrict f,
                       const float *restrict g, float dtcdx2, float dtcdy2,
                       int nx, int ny, int nfield) {
  float *restrict fx = scratch;
  float *restrict gy = scratch + nx;
  for (int k = 0; k < nfield; ++k) {
    for (int iy = 1; iy < ny - 1; ++iy) {
      int offset = (k * ny + iy) * nx + 1;
      limited_deriv1(fx + 1, f + offset, nx - 2);
      limited_derivk(gy + 1, g + offset, nx - 2, nx);
      for (int ix = 1; ix < nx - 1; ++ix) {
        int offset = (k * ny + iy) * nx + ix;
        v[offset] = u[offset] - dtcdx2 * fx[ix] - dtcdy2 * gy[ix];
      }
    }
  }
}


x86 assembly (clang, -O0):
<central2d_predict>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    0x18(%rbp),%eax
mov    0x10(%rbp),%eax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
movss  %xmm0,-0x2c(%rbp)
movss  %xmm1,-0x30(%rbp)
mov    %r9d,-0x34(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x48(%rbp)
movl   $0x0,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
cmp    0x18(%rbp),%eax
jge    12b9 <central2d_predict+0x199>
movl   $0x1,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    12a6 <central2d_predict+0x186>
mov    -0x4c(%rbp),%eax
imul   0x10(%rbp),%eax
add    -0x50(%rbp),%eax
imul   -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
mov    -0x40(%rbp),%rdi
add    $0x4,%rdi
mov    -0x20(%rbp),%rsi
movslq -0x54(%rbp),%rax
shl    $0x2,%rax
add    %rax,%rsi
mov    -0x34(%rbp),%edx
sub    $0x2,%edx
call   1030 <limited_deriv1@plt>
mov    -0x48(%rbp),%rdi
add    $0x4,%rdi
mov    -0x28(%rbp),%rsi
movslq -0x54(%rbp),%rax
shl    $0x2,%rax
add    %rax,%rsi
mov    -0x34(%rbp),%edx
sub    $0x2,%edx
mov    -0x34(%rbp),%ecx
call   1040 <limited_derivk@plt>
movl   $0x1,-0x58(%rbp)
mov    -0x58(%rbp),%eax
mov    -0x34(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1293 <central2d_predict+0x173>
mov    -0x4c(%rbp),%eax
imul   0x10(%rbp),%eax
add    -0x50(%rbp),%eax
imul   -0x34(%rbp),%eax
add    -0x58(%rbp),%eax
mov    %eax,-0x5c(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  -0x2c(%rbp),%xmm1
mov    -0x40(%rbp),%rax
movslq -0x58(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x30(%rbp),%xmm0
mov    -0x48(%rbp),%rax
movslq -0x58(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x58(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x58(%rbp)
jmp    11f8 <central2d_predict+0xd8>
jmp    1298 <central2d_predict+0x178>
mov    -0x50(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x50(%rbp)
jmp    1185 <central2d_predict+0x65>
jmp    12ab <central2d_predict+0x18b>
mov    -0x4c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4c(%rbp)
jmp    1172 <central2d_predict+0x52>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<central2d_predict>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x108,%rsp
mov    %r8,0xa8(%rsp)
mov    %rcx,0xa0(%rsp)
mov    0x148(%rsp),%r8d
test   %r8d,%r8d
jle    1441 <central2d_predict+0x321>
mov    0x140(%rsp),%eax
movslq %r9d,%rbp
lea    (%rsi,%rbp,4),%r15
lea    -0x1(%rax),%ebx
mov    %rbx,0x90(%rsp)
lea    0x4(%rsi),%rbx
mov    %rbx,0x88(%rsp)
lea    -0x1(%rbp),%ecx
movdqa 0xe7e(%rip),%xmm2
pxor   %xmm2,%xmm0
pxor   %xmm2,%xmm1
movslq %eax,%r9
mov    %r8d,%ebx
mov    %rbx,0x58(%rsp)
lea    -0x1(%rcx),%rbx
mov    %rbx,0x38(%rsp)
mov    %rbx,%r8
and    $0xfffffffffffffff8,%r8
pshufd $0x0,%xmm0,%xmm6
pshufd $0x0,%xmm1,%xmm7
lea    (%rdi,%rbp,4),%rax
add    $0x14,%rax
mov    %rax,0x30(%rsp)
mov    %r9,0x48(%rsp)
imul   %rbp,%r9
shl    $0x2,%r9
mov    %r9,0x50(%rsp)
lea    (%rdx,%rbp,4),%rax
add    $0x14,%rax
mov    %rax,0x28(%rsp)
lea    (%rdx,%rbp,4),%rax
mov    %rax,0x20(%rsp)
lea    (%rdi,%rbp,4),%rax
mov    %rax,0x18(%rsp)
lea    -0x2(%rbp),%eax
mov    %eax,0xc(%rsp)
lea    0x4(%r15),%rax
mov    %rax,0x70(%rsp)
lea    0x1(%r8),%rax
mov    %rax,0x60(%rsp)
mov    %rbp,0x40(%rsp)
lea    0x0(,%rbp,4),%rax
mov    %rax,0x68(%rsp)
xor    %eax,%eax
mov    %rax,0x10(%rsp)
movdqa %xmm1,0xf0(%rsp)
movdqa %xmm0,0xe0(%rsp)
mov    %rsi,0x98(%rsp)
mov    %rcx,0x80(%rsp)
mov    %r8,0x78(%rsp)
movdqa %xmm6,0xd0(%rsp)
movdqa %xmm7,0xc0(%rsp)
jmp    1295 <central2d_predict+0x175>
nopw   0x0(%rax,%rax,1)
mov    0x10(%rsp),%rdx
add    $0x1,%rdx
mov    0x50(%rsp),%rax
add    %rax,0x30(%rsp)
add    %rax,0x28(%rsp)
add    %rax,0x20(%rsp)
add    %rax,0x18(%rsp)
mov    %rdx,%rax
mov    %rdx,0x10(%rsp)
cmp    0x58(%rsp),%rdx
je     1441 <central2d_predict+0x321>
mov    0x140(%rsp),%eax
cmp    $0x3,%eax
jl     1260 <central2d_predict+0x140>
mov    0x10(%rsp),%rax
imul   0x48(%rsp),%rax
mov    %rax,0xb0(%rsp)
mov    $0x1,%edx
mov    0x18(%rsp),%rbp
mov    0x20(%rsp),%r14
mov    0x28(%rsp),%r12
mov    0x30(%rsp),%r13
jmp    12fb <central2d_predict+0x1db>
nop
mov    0xb8(%rsp),%rdx
add    $0x1,%rdx
mov    0x68(%rsp),%rax
add    %rax,%r13
add    %rax,%r12
add    %rax,%r14
add    %rax,%rbp
cmp    0x90(%rsp),%rdx
je     1260 <central2d_predict+0x140>
mov    0xb0(%rsp),%rax
mov    %rdx,0xb8(%rsp)
lea    (%rdx,%rax,1),%rbx
imul   0x40(%rsp),%rbx
mov    0xa0(%rsp),%rax
lea    (%rax,%rbx,4),%rsi
add    $0x4,%rsi
mov    0x88(%rsp),%rdi
mov    0xc(%rsp),%edx
call   1030 <limited_deriv1@plt>
mov    0xa8(%rsp),%rax
lea    (%rax,%rbx,4),%rsi
add    $0x4,%rsi
mov    0x70(%rsp),%rdi
mov    0xc(%rsp),%edx
mov    0x40(%rsp),%rbx
mov    %ebx,%ecx
call   1040 <limited_derivk@plt>
movaps 0xc0(%rsp),%xmm7
movaps 0xd0(%rsp),%xmm6
mov    0x78(%rsp),%r8
mov    0x80(%rsp),%rcx
mov    0x98(%rsp),%rsi
movaps 0xe0(%rsp),%xmm0
movaps 0xf0(%rsp),%xmm1
cmp    $0x3,%ebx
jl     12d0 <central2d_predict+0x1b0>
mov    $0x1,%eax
cmpq   $0x8,0x38(%rsp)
jb     1410 <central2d_predict+0x2f0>
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
movups -0x10(%r12,%rax,4),%xmm5
movups (%r12,%rax,4),%xmm4
movups 0x4(%rsi,%rax,4),%xmm2
movups 0x14(%rsi,%rax,4),%xmm3
mulps  %xmm6,%xmm2
addps  %xmm5,%xmm2
mulps  %xmm6,%xmm3
addps  %xmm4,%xmm3
movups 0x4(%r15,%rax,4),%xmm5
movups 0x14(%r15,%rax,4),%xmm4
mulps  %xmm7,%xmm5
addps  %xmm2,%xmm5
mulps  %xmm7,%xmm4
addps  %xmm3,%xmm4
movups %xmm5,-0x10(%r13,%rax,4)
movups %xmm4,0x0(%r13,%rax,4)
add    $0x8,%rax
cmp    %rax,%r8
jne    13b0 <central2d_predict+0x290>
mov    0x60(%rsp),%rax
cmp    %r8,0x38(%rsp)
je     12d0 <central2d_predict+0x1b0>
xchg   %ax,%ax
movss  (%rsi,%rax,4),%xmm3
mulss  %xmm0,%xmm3
addss  (%r14,%rax,4),%xmm3
movss  (%r15,%rax,4),%xmm2
mulss  %xmm1,%xmm2
addss  %xmm3,%xmm2
movss  %xmm2,0x0(%rbp,%rax,4)
add    $0x1,%rax
cmp    %rax,%rcx
jne    1410 <central2d_predict+0x2f0>
jmp    12d0 <central2d_predict+0x1b0>
add    $0x108,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @central2d_predict(float* noalias %0, float* noalias %1, float* noalias %2, float* noalias %3, float* noalias %4, float %5, float %6, i32 %7, i32 %8, i32 %9) {
%11 = alloca float*
%12 = alloca float*
%13 = alloca float*
%14 = alloca float*
%15 = alloca float*
%16 = alloca float
%17 = alloca float
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca float*
%22 = alloca float*
%23 = alloca i32
%24 = alloca i32
%25 = alloca i32
%26 = alloca i32
%27 = alloca i32
store float* %0, float** %11
store float* %1, float** %12
store float* %2, float** %13
store float* %3, float** %14
store float* %4, float** %15
store float %5, float* %16
store float %6, float* %17
store i32 %7, i32* %18
store i32 %8, i32* %19
store i32 %9, i32* %20
%28 = load float*, float** %12
store float* %28, float** %21
%29 = load float*, float** %12
%30 = load i32, i32* %18
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds float, float* %29, i64 %31
store float* %32, float** %22
store i32 0, i32* %23
br label %33
33: ; preds = %119, %10
%34 = load i32, i32* %23
%35 = load i32, i32* %20
%36 = icmp slt i32 %34, %35
br i1 %36, label %37, label %122
37: ; preds = %33
store i32 1, i32* %24
br label %38
38: ; preds = %115, %37
%39 = load i32, i32* %24
%40 = load i32, i32* %19
%41 = sub nsw i32 %40, 1
%42 = icmp slt i32 %39, %41
br i1 %42, label %43, label %118
43: ; preds = %38
%44 = load i32, i32* %23
%45 = load i32, i32* %19
%46 = mul nsw i32 %44, %45
%47 = load i32, i32* %24
%48 = add nsw i32 %46, %47
%49 = load i32, i32* %18
%50 = mul nsw i32 %48, %49
%51 = add nsw i32 %50, 1
store i32 %51, i32* %25
%52 = load float*, float** %21
%53 = getelementptr inbounds float, float* %52, i64 1
%54 = load float*, float** %14
%55 = load i32, i32* %25
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds float, float* %54, i64 %56
%58 = load i32, i32* %18
%59 = sub nsw i32 %58, 2
%60 = call i32 @limited_deriv1(float* %53, float* %57, i32 %59)
%61 = load float*, float** %22
%62 = getelementptr inbounds float, float* %61, i64 1
%63 = load float*, float** %15
%64 = load i32, i32* %25
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds float, float* %63, i64 %65
%67 = load i32, i32* %18
%68 = sub nsw i32 %67, 2
%69 = load i32, i32* %18
%70 = call i32 @limited_derivk(float* %62, float* %66, i32 %68, i32 %69)
store i32 1, i32* %26
br label %71
71: ; preds = %111, %43
%72 = load i32, i32* %26
%73 = load i32, i32* %18
%74 = sub nsw i32 %73, 1
%75 = icmp slt i32 %72, %74
br i1 %75, label %76, label %114
76: ; preds = %71
%77 = load i32, i32* %23
%78 = load i32, i32* %19
%79 = mul nsw i32 %77, %78
%80 = load i32, i32* %24
%81 = add nsw i32 %79, %80
%82 = load i32, i32* %18
%83 = mul nsw i32 %81, %82
%84 = load i32, i32* %26
%85 = add nsw i32 %83, %84
store i32 %85, i32* %27
%86 = load float*, float** %13
%87 = load i32, i32* %27
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds float, float* %86, i64 %88
%90 = load float, float* %89
%91 = load float, float* %16
%92 = load float*, float** %21
%93 = load i32, i32* %26
%94 = sext i32 %93 to i64
%95 = getelementptr inbounds float, float* %92, i64 %94
%96 = load float, float* %95
%97 = fneg float %91
%98 = call float @llvm.fmuladd.f32(float %97, float %96, float %90)
%99 = load float, float* %17
%100 = load float*, float** %22
%101 = load i32, i32* %26
%102 = sext i32 %101 to i64
%103 = getelementptr inbounds float, float* %100, i64 %102
%104 = load float, float* %103
%105 = fneg float %99
%106 = call float @llvm.fmuladd.f32(float %105, float %104, float %98)
%107 = load float*, float** %11
%108 = load i32, i32* %27
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds float, float* %107, i64 %109
store float %106, float* %110
br label %111
111: ; preds = %76
%112 = load i32, i32* %26
%113 = add nsw i32 %112, 1
store i32 %113, i32* %26
br label %71
114: ; preds = %71
br label %115
115: ; preds = %114
%116 = load i32, i32* %24
%117 = add nsw i32 %116, 1
store i32 %117, i32* %24
br label %38
118: ; preds = %38
br label %119
119: ; preds = %118
%120 = load i32, i32* %23
%121 = add nsw i32 %120, 1
store i32 %121, i32* %23
br label %33
122: ; preds = %33
ret void
}

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