#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 */
double f_up(double);
double interpolateDD(double X, double Values[][4], double step, int N) {
  int i;
  double toRet = 0.0;
  if (X >= Values[0][0] && X < Values[1][0])
    toRet = Values[0][1] + (X - Values[0][0]) * Values[0][2] +
            (X - Values[0][0]) * (X - Values[0][0]) * 0.5 * Values[0][3];
  if (X >= Values[N - 2][0] && X <= Values[N - 1][0])
    toRet = Values[N - 2][1] + (X - Values[N - 2][0]) * Values[N - 2][2] +
            (X - Values[N - 2][0]) * (X - Values[N - 2][0]) * 0.5 *
                Values[N - 2][3];
  if (X >= Values[1][0] && X < Values[N - 2][0])
    for (i = 1; i < N - 1; i++) {
      if (Values[i][0] <= X && Values[i + 1][0] > X && i != 0)
        toRet = 0.5 *
                (Values[i - 2][1] * f_up(0.5 * (X - Values[i - 2][0]) / step) +
                 Values[i - 1][1] * f_up(0.5 * (X - Values[i - 1][0]) / step) +
                 Values[i][1] * f_up(0.5 * (X - Values[i][0]) / step) +
                 Values[i + 1][1] * f_up(0.5 * (X - Values[i + 1][0]) / step) +
                 Values[i + 2][1] * f_up(0.5 * (X - Values[i + 2][0]) / step));
    }
  return toRet;
}


x86 assembly (clang, -O0):
<interpolateDD>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %esi,-0x1c(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
ucomisd (%rax),%xmm0
jb     11c3 <interpolateDD+0xb3>
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
movsd  0x20(%rax),%xmm0
ucomisd %xmm1,%xmm0
jbe    11c3 <interpolateDD+0xb3>
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm1
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm0
movsd  -0x8(%rbp),%xmm2
mov    -0x10(%rbp),%rax
subsd  (%rax),%xmm2
mulsd  %xmm2,%xmm0
movsd  0xe57(%rip),%xmm2
mulsd  %xmm2,%xmm0
mov    -0x10(%rbp),%rax
movsd  0x18(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
ucomisd (%rax),%xmm0
jb     12d4 <interpolateDD+0x1c4>
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm0
ucomisd %xmm1,%xmm0
jb     12d4 <interpolateDD+0x1c4>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm0
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x10(%rax),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm0
movsd  -0x8(%rbp),%xmm2
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm2
mulsd  %xmm2,%xmm0
movsd  0xd56(%rip),%xmm2
mulsd  %xmm2,%xmm0
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x18(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
ucomisd 0x20(%rax),%xmm0
jb     159b <interpolateDD+0x48b>
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm0
ucomisd %xmm1,%xmm0
jbe    159b <interpolateDD+0x48b>
movl   $0x1,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1596 <interpolateDD+0x486>
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm1
movsd  -0x8(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jb     1583 <interpolateDD+0x473>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  (%rax),%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    1583 <interpolateDD+0x473>
cmpl   $0x0,-0x20(%rbp)
je     1583 <interpolateDD+0x473>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm1
movsd  0xc47(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <f_up@plt>
movsd  %xmm0,-0x68(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm1
movsd  0xbf1(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <f_up@plt>
movsd  -0x70(%rbp),%xmm1
movsd  -0x68(%rbp),%xmm2
movaps %xmm0,%xmm3
movsd  -0x60(%rbp),%xmm0
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm1
movsd  0xb87(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <f_up@plt>
movsd  -0x58(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x50(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm1
movsd  0xb1c(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <f_up@plt>
movsd  -0x48(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x40(%rbp),%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x8(%rbp),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
shl    $0x5,%rcx
add    %rcx,%rax
subsd  (%rax),%xmm1
movsd  0xab1(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  -0x18(%rbp),%xmm0
call   1030 <f_up@plt>
movsd  -0x38(%rbp),%xmm1
movaps %xmm0,%xmm2
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  0xa86(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    1588 <interpolateDD+0x478>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1316 <interpolateDD+0x206>
jmp    159b <interpolateDD+0x48b>
movsd  -0x28(%rbp),%xmm0
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<interpolateDD>:
push   %r15
push   %r14
push   %rbx
sub    $0x30,%rsp
mov    %esi,%r14d
movsd  %xmm1,0x20(%rsp)
mov    %rdi,%r15
movapd %xmm0,%xmm3
movsd  (%rdi),%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm1,%xmm3
jb     1171 <interpolateDD+0x61>
movsd  0x20(%r15),%xmm2
ucomisd %xmm3,%xmm2
jbe    1171 <interpolateDD+0x61>
movapd %xmm3,%xmm0
subsd  %xmm1,%xmm0
movsd  0x10(%r15),%xmm1
mulsd  %xmm0,%xmm1
addsd  0x8(%r15),%xmm1
mulsd  %xmm0,%xmm0
mulsd  0xe99(%rip),%xmm0
mulsd  0x18(%r15),%xmm0
addsd  %xmm1,%xmm0
movslq %r14d,%rcx
lea    -0x2(%rcx),%rax
shl    $0x5,%rax
movsd  (%r15,%rax,1),%xmm1
ucomisd %xmm1,%xmm3
jb     11ca <interpolateDD+0xba>
shl    $0x5,%rcx
movsd  -0x20(%rcx,%r15,1),%xmm2
ucomisd %xmm3,%xmm2
jb     11ca <interpolateDD+0xba>
movapd %xmm3,%xmm0
subsd  %xmm1,%xmm0
movsd  0x10(%r15,%rax,1),%xmm2
mulsd  %xmm0,%xmm2
addsd  0x8(%r15,%rax,1),%xmm2
mulsd  %xmm0,%xmm0
mulsd  0xe41(%rip),%xmm0
mulsd  0x18(%r15,%rax,1),%xmm0
addsd  %xmm2,%xmm0
movsd  0x20(%r15),%xmm2
ucomisd %xmm2,%xmm3
jb     137d <interpolateDD+0x26d>
ucomisd %xmm3,%xmm1
jbe    137d <interpolateDD+0x26d>
cmp    $0x3,%r14d
jl     137d <interpolateDD+0x26d>
add    $0xffffffff,%r14d
shl    $0x5,%r14
mov    $0x40,%ebx
movsd  %xmm3,0x18(%rsp)
ucomisd %xmm2,%xmm3
jb     1362 <interpolateDD+0x252>
nopl   0x0(%rax,%rax,1)
movsd  (%r15,%rbx,1),%xmm1
ucomisd %xmm3,%xmm1
jbe    1362 <interpolateDD+0x252>
movsd  -0x58(%r15,%rbx,1),%xmm0
movsd  %xmm0,0x8(%rsp)
movapd %xmm3,%xmm0
subsd  -0x60(%r15,%rbx,1),%xmm0
movsd  0xdc0(%rip),%xmm1
mulsd  %xmm1,%xmm0
divsd  0x20(%rsp),%xmm0
call   1030 <f_up@plt>
movsd  %xmm0,0x10(%rsp)
movsd  -0x38(%r15,%rbx,1),%xmm0
movsd  %xmm0,0x28(%rsp)
movsd  0x18(%rsp),%xmm0
subsd  -0x40(%r15,%rbx,1),%xmm0
mulsd  0xd89(%rip),%xmm0
divsd  0x20(%rsp),%xmm0
call   1030 <f_up@plt>
mulsd  0x28(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
mulsd  0x8(%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rsp)
movsd  -0x18(%r15,%rbx,1),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x18(%rsp),%xmm0
subsd  -0x20(%r15,%rbx,1),%xmm0
mulsd  0xd40(%rip),%xmm0
divsd  0x20(%rsp),%xmm0
call   1030 <f_up@plt>
mulsd  0x8(%rsp),%xmm0
addsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  0x8(%r15,%rbx,1),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x18(%rsp),%xmm0
subsd  (%r15,%rbx,1),%xmm0
mulsd  0xd02(%rip),%xmm0
divsd  0x20(%rsp),%xmm0
call   1030 <f_up@plt>
mulsd  0x8(%rsp),%xmm0
addsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  0x28(%r15,%rbx,1),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x18(%rsp),%xmm0
subsd  0x20(%r15,%rbx,1),%xmm0
mulsd  0xcc3(%rip),%xmm0
divsd  0x20(%rsp),%xmm0
call   1030 <f_up@plt>
movsd  0x18(%rsp),%xmm3
mulsd  0x8(%rsp),%xmm0
addsd  0x10(%rsp),%xmm0
mulsd  0xc9e(%rip),%xmm0
cmp    %rbx,%r14
je     137d <interpolateDD+0x26d>
movsd  (%r15,%rbx,1),%xmm2
add    $0x20,%rbx
ucomisd %xmm2,%xmm3
jae    1210 <interpolateDD+0x100>
jmp    1362 <interpolateDD+0x252>
add    $0x30,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define double @interpolateDD(double %0, [4 x double]* %1, double %2, i32 %3) {
%5 = alloca double
%6 = alloca [4 x double]*
%7 = alloca double
%8 = alloca i32
%9 = alloca i32
%10 = alloca double
store double %0, double* %5
store [4 x double]* %1, [4 x double]** %6
store double %2, double* %7
store i32 %3, i32* %8
store double 0.000000e+00, double* %10
%11 = load double, double* %5
%12 = load [4 x double]*, [4 x double]** %6
%13 = getelementptr inbounds [4 x double], [4 x double]* %12, i64 0
%14 = getelementptr inbounds [4 x double], [4 x double]* %13, i64 0, i64 0
%15 = load double, double* %14
%16 = fcmp oge double %11, %15
br i1 %16, label %17, label %59
17: ; preds = %4
%18 = load double, double* %5
%19 = load [4 x double]*, [4 x double]** %6
%20 = getelementptr inbounds [4 x double], [4 x double]* %19, i64 1
%21 = getelementptr inbounds [4 x double], [4 x double]* %20, i64 0, i64 0
%22 = load double, double* %21
%23 = fcmp olt double %18, %22
br i1 %23, label %24, label %59
24: ; preds = %17
%25 = load [4 x double]*, [4 x double]** %6
%26 = getelementptr inbounds [4 x double], [4 x double]* %25, i64 0
%27 = getelementptr inbounds [4 x double], [4 x double]* %26, i64 0, i64 1
%28 = load double, double* %27
%29 = load double, double* %5
%30 = load [4 x double]*, [4 x double]** %6
%31 = getelementptr inbounds [4 x double], [4 x double]* %30, i64 0
%32 = getelementptr inbounds [4 x double], [4 x double]* %31, i64 0, i64 0
%33 = load double, double* %32
%34 = fsub double %29, %33
%35 = load [4 x double]*, [4 x double]** %6
%36 = getelementptr inbounds [4 x double], [4 x double]* %35, i64 0
%37 = getelementptr inbounds [4 x double], [4 x double]* %36, i64 0, i64 2
%38 = load double, double* %37
%39 = call double @llvm.fmuladd.f64(double %34, double %38, double %28)
%40 = load double, double* %5
%41 = load [4 x double]*, [4 x double]** %6
%42 = getelementptr inbounds [4 x double], [4 x double]* %41, i64 0
%43 = getelementptr inbounds [4 x double], [4 x double]* %42, i64 0, i64 0
%44 = load double, double* %43
%45 = fsub double %40, %44
%46 = load double, double* %5
%47 = load [4 x double]*, [4 x double]** %6
%48 = getelementptr inbounds [4 x double], [4 x double]* %47, i64 0
%49 = getelementptr inbounds [4 x double], [4 x double]* %48, i64 0, i64 0
%50 = load double, double* %49
%51 = fsub double %46, %50
%52 = fmul double %45, %51
%53 = fmul double %52, 5.000000e-01
%54 = load [4 x double]*, [4 x double]** %6
%55 = getelementptr inbounds [4 x double], [4 x double]* %54, i64 0
%56 = getelementptr inbounds [4 x double], [4 x double]* %55, i64 0, i64 3
%57 = load double, double* %56
%58 = call double @llvm.fmuladd.f64(double %53, double %57, double %39)
store double %58, double* %10
br label %59
59: ; preds = %24, %17, %4
%60 = load double, double* %5
%61 = load [4 x double]*, [4 x double]** %6
%62 = load i32, i32* %8
%63 = sub nsw i32 %62, 2
%64 = sext i32 %63 to i64
%65 = getelementptr inbounds [4 x double], [4 x double]* %61, i64 %64
%66 = getelementptr inbounds [4 x double], [4 x double]* %65, i64 0, i64 0
%67 = load double, double* %66
%68 = fcmp oge double %60, %67
br i1 %68, label %69, label %132
69: ; preds = %59
%70 = load double, double* %5
%71 = load [4 x double]*, [4 x double]** %6
%72 = load i32, i32* %8
%73 = sub nsw i32 %72, 1
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds [4 x double], [4 x double]* %71, i64 %74
%76 = getelementptr inbounds [4 x double], [4 x double]* %75, i64 0, i64 0
%77 = load double, double* %76
%78 = fcmp ole double %70, %77
br i1 %78, label %79, label %132
79: ; preds = %69
%80 = load [4 x double]*, [4 x double]** %6
%81 = load i32, i32* %8
%82 = sub nsw i32 %81, 2
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds [4 x double], [4 x double]* %80, i64 %83
%85 = getelementptr inbounds [4 x double], [4 x double]* %84, i64 0, i64 1
%86 = load double, double* %85
%87 = load double, double* %5
%88 = load [4 x double]*, [4 x double]** %6
%89 = load i32, i32* %8
%90 = sub nsw i32 %89, 2
%91 = sext i32 %90 to i64
%92 = getelementptr inbounds [4 x double], [4 x double]* %88, i64 %91
%93 = getelementptr inbounds [4 x double], [4 x double]* %92, i64 0, i64 0
%94 = load double, double* %93
%95 = fsub double %87, %94
%96 = load [4 x double]*, [4 x double]** %6
%97 = load i32, i32* %8
%98 = sub nsw i32 %97, 2
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds [4 x double], [4 x double]* %96, i64 %99
%101 = getelementptr inbounds [4 x double], [4 x double]* %100, i64 0, i64 2
%102 = load double, double* %101
%103 = call double @llvm.fmuladd.f64(double %95, double %102, double %86)
%104 = load double, double* %5
%105 = load [4 x double]*, [4 x double]** %6
%106 = load i32, i32* %8
%107 = sub nsw i32 %106, 2
%108 = sext i32 %107 to i64
%109 = getelementptr inbounds [4 x double], [4 x double]* %105, i64 %108
%110 = getelementptr inbounds [4 x double], [4 x double]* %109, i64 0, i64 0
%111 = load double, double* %110
%112 = fsub double %104, %111
%113 = load double, double* %5
%114 = load [4 x double]*, [4 x double]** %6
%115 = load i32, i32* %8
%116 = sub nsw i32 %115, 2
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds [4 x double], [4 x double]* %114, i64 %117
%119 = getelementptr inbounds [4 x double], [4 x double]* %118, i64 0, i64 0
%120 = load double, double* %119
%121 = fsub double %113, %120
%122 = fmul double %112, %121
%123 = fmul double %122, 5.000000e-01
%124 = load [4 x double]*, [4 x double]** %6
%125 = load i32, i32* %8
%126 = sub nsw i32 %125, 2
%127 = sext i32 %126 to i64
%128 = getelementptr inbounds [4 x double], [4 x double]* %124, i64 %127
%129 = getelementptr inbounds [4 x double], [4 x double]* %128, i64 0, i64 3
%130 = load double, double* %129
%131 = call double @llvm.fmuladd.f64(double %123, double %130, double %103)
store double %131, double* %10
br label %132
132: ; preds = %79, %69, %59
%133 = load double, double* %5
%134 = load [4 x double]*, [4 x double]** %6
%135 = getelementptr inbounds [4 x double], [4 x double]* %134, i64 1
%136 = getelementptr inbounds [4 x double], [4 x double]* %135, i64 0, i64 0
%137 = load double, double* %136
%138 = fcmp oge double %133, %137
br i1 %138, label %139, label %287
139: ; preds = %132
%140 = load double, double* %5
%141 = load [4 x double]*, [4 x double]** %6
%142 = load i32, i32* %8
%143 = sub nsw i32 %142, 2
%144 = sext i32 %143 to i64
%145 = getelementptr inbounds [4 x double], [4 x double]* %141, i64 %144
%146 = getelementptr inbounds [4 x double], [4 x double]* %145, i64 0, i64 0
%147 = load double, double* %146
%148 = fcmp olt double %140, %147
br i1 %148, label %149, label %287
149: ; preds = %139
store i32 1, i32* %9
br label %150
150: ; preds = %283, %149
%151 = load i32, i32* %9
%152 = load i32, i32* %8
%153 = sub nsw i32 %152, 1
%154 = icmp slt i32 %151, %153
br i1 %154, label %155, label %286
155: ; preds = %150
%156 = load [4 x double]*, [4 x double]** %6
%157 = load i32, i32* %9
%158 = sext i32 %157 to i64
%159 = getelementptr inbounds [4 x double], [4 x double]* %156, i64 %158
%160 = getelementptr inbounds [4 x double], [4 x double]* %159, i64 0, i64 0
%161 = load double, double* %160
%162 = load double, double* %5
%163 = fcmp ole double %161, %162
br i1 %163, label %164, label %282
164: ; preds = %155
%165 = load [4 x double]*, [4 x double]** %6
%166 = load i32, i32* %9
%167 = add nsw i32 %166, 1
%168 = sext i32 %167 to i64
%169 = getelementptr inbounds [4 x double], [4 x double]* %165, i64 %168
%170 = getelementptr inbounds [4 x double], [4 x double]* %169, i64 0, i64 0
%171 = load double, double* %170
%172 = load double, double* %5
%173 = fcmp ogt double %171, %172
br i1 %173, label %174, label %282
174: ; preds = %164
%175 = load i32, i32* %9
%176 = icmp ne i32 %175, 0
br i1 %176, label %177, label %282
177: ; preds = %174
%178 = load [4 x double]*, [4 x double]** %6
%179 = load i32, i32* %9
%180 = sub nsw i32 %179, 2
%181 = sext i32 %180 to i64
%182 = getelementptr inbounds [4 x double], [4 x double]* %178, i64 %181
%183 = getelementptr inbounds [4 x double], [4 x double]* %182, i64 0, i64 1
%184 = load double, double* %183
%185 = load double, double* %5
%186 = load [4 x double]*, [4 x double]** %6
%187 = load i32, i32* %9
%188 = sub nsw i32 %187, 2
%189 = sext i32 %188 to i64
%190 = getelementptr inbounds [4 x double], [4 x double]* %186, i64 %189
%191 = getelementptr inbounds [4 x double], [4 x double]* %190, i64 0, i64 0
%192 = load double, double* %191
%193 = fsub double %185, %192
%194 = fmul double 5.000000e-01, %193
%195 = load double, double* %7
%196 = fdiv double %194, %195
%197 = call double @f_up(double %196)
%198 = load [4 x double]*, [4 x double]** %6
%199 = load i32, i32* %9
%200 = sub nsw i32 %199, 1
%201 = sext i32 %200 to i64
%202 = getelementptr inbounds [4 x double], [4 x double]* %198, i64 %201
%203 = getelementptr inbounds [4 x double], [4 x double]* %202, i64 0, i64 1
%204 = load double, double* %203
%205 = load double, double* %5
%206 = load [4 x double]*, [4 x double]** %6
%207 = load i32, i32* %9
%208 = sub nsw i32 %207, 1
%209 = sext i32 %208 to i64
%210 = getelementptr inbounds [4 x double], [4 x double]* %206, i64 %209
%211 = getelementptr inbounds [4 x double], [4 x double]* %210, i64 0, i64 0
%212 = load double, double* %211
%213 = fsub double %205, %212
%214 = fmul double 5.000000e-01, %213
%215 = load double, double* %7
%216 = fdiv double %214, %215
%217 = call double @f_up(double %216)
%218 = fmul double %204, %217
%219 = call double @llvm.fmuladd.f64(double %184, double %197, double %218)
%220 = load [4 x double]*, [4 x double]** %6
%221 = load i32, i32* %9
%222 = sext i32 %221 to i64
%223 = getelementptr inbounds [4 x double], [4 x double]* %220, i64 %222
%224 = getelementptr inbounds [4 x double], [4 x double]* %223, i64 0, i64 1
%225 = load double, double* %224
%226 = load double, double* %5
%227 = load [4 x double]*, [4 x double]** %6
%228 = load i32, i32* %9
%229 = sext i32 %228 to i64
%230 = getelementptr inbounds [4 x double], [4 x double]* %227, i64 %229
%231 = getelementptr inbounds [4 x double], [4 x double]* %230, i64 0, i64 0
%232 = load double, double* %231
%233 = fsub double %226, %232
%234 = fmul double 5.000000e-01, %233
%235 = load double, double* %7
%236 = fdiv double %234, %235
%237 = call double @f_up(double %236)
%238 = call double @llvm.fmuladd.f64(double %225, double %237, double %219)
%239 = load [4 x double]*, [4 x double]** %6
%240 = load i32, i32* %9
%241 = add nsw i32 %240, 1
%242 = sext i32 %241 to i64
%243 = getelementptr inbounds [4 x double], [4 x double]* %239, i64 %242
%244 = getelementptr inbounds [4 x double], [4 x double]* %243, i64 0, i64 1
%245 = load double, double* %244
%246 = load double, double* %5
%247 = load [4 x double]*, [4 x double]** %6
%248 = load i32, i32* %9
%249 = add nsw i32 %248, 1
%250 = sext i32 %249 to i64
%251 = getelementptr inbounds [4 x double], [4 x double]* %247, i64 %250
%252 = getelementptr inbounds [4 x double], [4 x double]* %251, i64 0, i64 0
%253 = load double, double* %252
%254 = fsub double %246, %253
%255 = fmul double 5.000000e-01, %254
%256 = load double, double* %7
%257 = fdiv double %255, %256
%258 = call double @f_up(double %257)
%259 = call double @llvm.fmuladd.f64(double %245, double %258, double %238)
%260 = load [4 x double]*, [4 x double]** %6
%261 = load i32, i32* %9
%262 = add nsw i32 %261, 2
%263 = sext i32 %262 to i64
%264 = getelementptr inbounds [4 x double], [4 x double]* %260, i64 %263
%265 = getelementptr inbounds [4 x double], [4 x double]* %264, i64 0, i64 1
%266 = load double, double* %265
%267 = load double, double* %5
%268 = load [4 x double]*, [4 x double]** %6
%269 = load i32, i32* %9
%270 = add nsw i32 %269, 2
%271 = sext i32 %270 to i64
%272 = getelementptr inbounds [4 x double], [4 x double]* %268, i64 %271
%273 = getelementptr inbounds [4 x double], [4 x double]* %272, i64 0, i64 0
%274 = load double, double* %273
%275 = fsub double %267, %274
%276 = fmul double 5.000000e-01, %275
%277 = load double, double* %7
%278 = fdiv double %276, %277
%279 = call double @f_up(double %278)
%280 = call double @llvm.fmuladd.f64(double %266, double %279, double %259)
%281 = fmul double 5.000000e-01, %280
store double %281, double* %10
br label %282
282: ; preds = %177, %174, %164, %155
br label %283
283: ; preds = %282
%284 = load i32, i32* %9
%285 = add nsw i32 %284, 1
store i32 %285, i32* %9
br label %150
286: ; preds = %150
br label %287
287: ; preds = %286, %139, %132
%288 = load double, double* %10
ret double %288
}

LLVM IR (-O2):
define double @interpolateDD(double %0, [4 x double]* %1, double %2, i32 %3) {
%5 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 0, i64 0
%6 = load double, double* %5
%7 = fcmp ugt double %6, %0
br i1 %7, label %24, label %8
8: ; preds = %4
%9 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 1, i64 0
%10 = load double, double* %9
%11 = fcmp ogt double %10, %0
br i1 %11, label %12, label %24
12: ; preds = %8
%13 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 0, i64 1
%14 = load double, double* %13
%15 = fsub double %0, %6
%16 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 0, i64 2
%17 = load double, double* %16
%18 = tail call double @llvm.fmuladd.f64(double %15, double %17, double %14)
%19 = fmul double %15, %15
%20 = fmul double %19, 5.000000e-01
%21 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 0, i64 3
%22 = load double, double* %21
%23 = tail call double @llvm.fmuladd.f64(double %20, double %22, double %18)
br label %24
24: ; preds = %12, %8, %4
%25 = phi double [ %23, %12 ], [ 0.000000e+00, %8 ], [ 0.000000e+00, %4 ]
%26 = add nsw i32 %3, -2
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %27, i64 0
%29 = load double, double* %28
%30 = fcmp ugt double %29, %0
br i1 %30, label %49, label %31
31: ; preds = %24
%32 = add nsw i32 %3, -1
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %33, i64 0
%35 = load double, double* %34
%36 = fcmp ult double %35, %0
br i1 %36, label %49, label %37
37: ; preds = %31
%38 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %27, i64 1
%39 = load double, double* %38
%40 = fsub double %0, %29
%41 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %27, i64 2
%42 = load double, double* %41
%43 = tail call double @llvm.fmuladd.f64(double %40, double %42, double %39)
%44 = fmul double %40, %40
%45 = fmul double %44, 5.000000e-01
%46 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %27, i64 3
%47 = load double, double* %46
%48 = tail call double @llvm.fmuladd.f64(double %45, double %47, double %43)
br label %49
49: ; preds = %37, %31, %24
%50 = phi double [ %48, %37 ], [ %25, %31 ], [ %25, %24 ]
%51 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 1, i64 0
%52 = load double, double* %51
%53 = fcmp ole double %52, %0
%54 = fcmp ogt double %29, %0
%55 = select i1 %53, i1 %54, i1 false
%56 = icmp sgt i32 %3, 2
%57 = and i1 %55, %56
br i1 %57, label %58, label %127
58: ; preds = %49
%59 = add nsw i32 %3, -1
%60 = zext i32 %59 to i64
br label %61
61: ; preds = %124, %58
%62 = phi double [ %52, %58 ], [ %126, %124 ]
%63 = phi i64 [ 1, %58 ], [ %67, %124 ]
%64 = phi double [ %50, %58 ], [ %122, %124 ]
%65 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %63, i64 0
%66 = fcmp ugt double %62, %0
%67 = add nuw nsw i64 %63, 1
br i1 %66, label %121, label %68
68: ; preds = %61
%69 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %67, i64 0
%70 = load double, double* %69
%71 = fcmp ogt double %70, %0
br i1 %71, label %72, label %121
72: ; preds = %68
%73 = add nsw i64 %63, -2
%74 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %73, i64 1
%75 = load double, double* %74
%76 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %73, i64 0
%77 = load double, double* %76
%78 = fsub double %0, %77
%79 = fmul double %78, 5.000000e-01
%80 = fdiv double %79, %2
%81 = tail call double @f_up(double %80)
%82 = add nsw i64 %63, -1
%83 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %82, i64 1
%84 = load double, double* %83
%85 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %82, i64 0
%86 = load double, double* %85
%87 = fsub double %0, %86
%88 = fmul double %87, 5.000000e-01
%89 = fdiv double %88, %2
%90 = tail call double @f_up(double %89)
%91 = fmul double %84, %90
%92 = tail call double @llvm.fmuladd.f64(double %75, double %81, double %91)
%93 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %63, i64 1
%94 = load double, double* %93
%95 = load double, double* %65
%96 = fsub double %0, %95
%97 = fmul double %96, 5.000000e-01
%98 = fdiv double %97, %2
%99 = tail call double @f_up(double %98)
%100 = tail call double @llvm.fmuladd.f64(double %94, double %99, double %92)
%101 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %67, i64 1
%102 = load double, double* %101
%103 = load double, double* %69
%104 = fsub double %0, %103
%105 = fmul double %104, 5.000000e-01
%106 = fdiv double %105, %2
%107 = tail call double @f_up(double %106)
%108 = tail call double @llvm.fmuladd.f64(double %102, double %107, double %100)
%109 = add nuw i64 %63, 2
%110 = and i64 %109, 4294967295
%111 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %110, i64 1
%112 = load double, double* %111
%113 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %110, i64 0
%114 = load double, double* %113
%115 = fsub double %0, %114
%116 = fmul double %115, 5.000000e-01
%117 = fdiv double %116, %2
%118 = tail call double @f_up(double %117)
%119 = tail call double @llvm.fmuladd.f64(double %112, double %118, double %108)
%120 = fmul double %119, 5.000000e-01
br label %121
121: ; preds = %61, %68, %72
%122 = phi double [ %64, %68 ], [ %120, %72 ], [ %64, %61 ]
%123 = icmp eq i64 %67, %60
br i1 %123, label %127, label %124
124: ; preds = %121
%125 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 %67, i64 0
%126 = load double, double* %125
br label %61
127: ; preds = %121, %49
%128 = phi double [ %50, %49 ], [ %122, %121 ]
ret double %128
}