void agbnp3_cspline_interpolate(float x, float dx, int n, float *y, float *y2,
                                float *f, float *fp) {
  int k;
  float xh, b, a, a2, b2, kf, dp1, dp2, dxinv = 1. / dx;
  dp1 = dx / 6.0;
  dp2 = dx * dp1;
  xh = x * dxinv;
  k = xh;
  kf = k;
  if (k > n - 2) {
    *f = 0.0;
    *fp = 0.0;
    return;
  }
  a = (kf + 1.0) - xh;
  a2 = a * a;
  b = xh - kf;
  b2 = b * b;
  *f = a * y[k] + b * y[k + 1] +
       ((a2 * a - a) * y2[k] + (b2 * b - b) * y2[k + 1]) * dp2;
  *fp = (y[k + 1] - y[k]) * dxinv -
        ((3. * a2 - 1.) * y2[k] + (3. * b2 - 1.) * y2[k + 1]) * dp1;
}


x86 assembly (clang, -O0):
<agbnp3_cspline_interpolate>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xed6(%rip),%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x58(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xeb0(%rip),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x8(%rbp),%xmm0
mulss  -0x50(%rbp),%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x4(%rbp),%xmm0
mulss  -0x58(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
cvttss2si -0x38(%rbp),%eax
mov    %eax,-0x34(%rbp)
cvtsi2ssl -0x34(%rbp),%xmm0
movss  %xmm0,-0x4c(%rbp)
mov    -0x34(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x2,%ecx
cmp    %ecx,%eax
jle    11b9 <agbnp3_cspline_interpolate+0xb9>
mov    -0x28(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax)
mov    -0x30(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax)
jmp    1397 <agbnp3_cspline_interpolate+0x297>
movss  -0x4c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe3e(%rip),%xmm1
addsd  %xmm1,%xmm0
movss  -0x38(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x40(%rbp)
movss  -0x40(%rbp),%xmm0
mulss  -0x40(%rbp),%xmm0
movss  %xmm0,-0x44(%rbp)
movss  -0x38(%rbp),%xmm0
subss  -0x4c(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x3c(%rbp),%xmm0
mulss  -0x3c(%rbp),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x40(%rbp),%xmm1
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movss  -0x3c(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulss  (%rax,%rcx,4),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x44(%rbp),%xmm0
movss  -0x40(%rbp),%xmm3
movss  -0x40(%rbp),%xmm2
movd   %xmm2,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm2
mulss  %xmm3,%xmm0
addss  %xmm2,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
movss  -0x48(%rbp),%xmm2
movss  -0x3c(%rbp),%xmm5
movss  -0x3c(%rbp),%xmm4
movd   %xmm4,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm4
mulss  %xmm5,%xmm2
addss  %xmm4,%xmm2
mov    -0x20(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulss  (%rax,%rcx,4),%xmm2
mulss  %xmm3,%xmm0
addss  %xmm2,%xmm0
movss  -0x54(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x18(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
subss  (%rax,%rcx,4),%xmm0
mulss  -0x58(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x44(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd11(%rip),%xmm2
mulsd  %xmm2,%xmm0
movsd  0xd0d(%rip),%xmm2
addsd  %xmm2,%xmm0
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
cvtss2sd %xmm2,%xmm3
movss  -0x48(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
movsd  0xcdf(%rip),%xmm4
mulsd  %xmm4,%xmm2
movsd  0xcdb(%rip),%xmm4
addsd  %xmm4,%xmm2
mov    -0x20(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm4
cvtss2sd %xmm4,%xmm4
mulsd  %xmm4,%xmm2
mulsd  %xmm3,%xmm0
addsd  %xmm2,%xmm0
movss  -0x50(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x30(%rbp),%rax
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<agbnp3_cspline_interpolate>:
movss  0xef8(%rip),%xmm2
divss  %xmm1,%xmm2
mulss  %xmm2,%xmm0
cvttss2si %xmm0,%eax
add    $0xfffffffe,%edi
cmp    %eax,%edi
jge    112a <agbnp3_cspline_interpolate+0x2a>
movl   $0x0,(%rcx)
xorps  %xmm0,%xmm0
movss  %xmm0,(%r8)
ret
cvtsi2ss %eax,%xmm3
cvtsi2sd %eax,%xmm4
addsd  0xece(%rip),%xmm4
cvtss2sd %xmm0,%xmm5
subsd  %xmm5,%xmm4
cvtsd2ss %xmm4,%xmm6
movaps %xmm6,%xmm7
mulss  %xmm6,%xmm7
subss  %xmm3,%xmm0
movaps %xmm0,%xmm4
mulss  %xmm0,%xmm4
cltq
movss  0x4(%rsi,%rax,4),%xmm8
mulss  %xmm0,%xmm8
movss  (%rsi,%rax,4),%xmm5
mulss  %xmm6,%xmm5
xorps  %xmm3,%xmm3
cvtss2sd %xmm7,%xmm3
mulss  %xmm6,%xmm7
subss  %xmm6,%xmm7
xorps  %xmm6,%xmm6
cvtss2sd %xmm4,%xmm6
mulss  %xmm0,%xmm4
subss  %xmm0,%xmm4
movaps %xmm1,%xmm0
divss  0xe6c(%rip),%xmm0
mulss  %xmm0,%xmm1
mulss  0x4(%rdx,%rax,4),%xmm4
mulss  (%rdx,%rax,4),%xmm7
addss  %xmm8,%xmm5
addss  %xmm4,%xmm7
mulss  %xmm1,%xmm7
addss  %xmm5,%xmm7
movss  %xmm7,(%rcx)
movss  0x4(%rsi,%rax,4),%xmm1
subss  (%rsi,%rax,4),%xmm1
mulss  %xmm1,%xmm2
xorps  %xmm1,%xmm1
cvtss2sd %xmm2,%xmm1
movsd  0xe36(%rip),%xmm2
mulsd  %xmm2,%xmm3
movsd  0xe32(%rip),%xmm4
addsd  %xmm4,%xmm3
movss  (%rdx,%rax,4),%xmm5
movss  0x4(%rdx,%rax,4),%xmm7
cvtss2sd %xmm5,%xmm5
mulsd  %xmm3,%xmm5
mulsd  %xmm2,%xmm6
addsd  %xmm4,%xmm6
xorps  %xmm2,%xmm2
cvtss2sd %xmm7,%xmm2
mulsd  %xmm6,%xmm2
addsd  %xmm5,%xmm2
cvtss2sd %xmm0,%xmm0
mulsd  %xmm2,%xmm0
subsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movss  %xmm0,(%r8)
ret

LLVM IR (-O0):
define void @agbnp3_cspline_interpolate(float %0, float %1, i32 %2, float* %3, float* %4, float* %5, float* %6) {
%8 = alloca float
%9 = alloca float
%10 = alloca i32
%11 = alloca float*
%12 = alloca float*
%13 = alloca float*
%14 = alloca float*
%15 = alloca i32
%16 = alloca float
%17 = alloca float
%18 = alloca float
%19 = alloca float
%20 = alloca float
%21 = alloca float
%22 = alloca float
%23 = alloca float
%24 = alloca float
store float %0, float* %8
store float %1, float* %9
store i32 %2, i32* %10
store float* %3, float** %11
store float* %4, float** %12
store float* %5, float** %13
store float* %6, float** %14
%25 = load float, float* %9
%26 = fpext float %25 to double
%27 = fdiv double 1.000000e+00, %26
%28 = fptrunc double %27 to float
store float %28, float* %24
%29 = load float, float* %9
%30 = fpext float %29 to double
%31 = fdiv double %30, 6.000000e+00
%32 = fptrunc double %31 to float
store float %32, float* %22
%33 = load float, float* %9
%34 = load float, float* %22
%35 = fmul float %33, %34
store float %35, float* %23
%36 = load float, float* %8
%37 = load float, float* %24
%38 = fmul float %36, %37
store float %38, float* %16
%39 = load float, float* %16
%40 = fptosi float %39 to i32
store i32 %40, i32* %15
%41 = load i32, i32* %15
%42 = sitofp i32 %41 to float
store float %42, float* %21
%43 = load i32, i32* %15
%44 = load i32, i32* %10
%45 = sub nsw i32 %44, 2
%46 = icmp sgt i32 %43, %45
br i1 %46, label %47, label %50
47: ; preds = %7
%48 = load float*, float** %13
store float 0.000000e+00, float* %48
%49 = load float*, float** %14
store float 0.000000e+00, float* %49
br label %150
50: ; preds = %7
%51 = load float, float* %21
%52 = fpext float %51 to double
%53 = fadd double %52, 1.000000e+00
%54 = load float, float* %16
%55 = fpext float %54 to double
%56 = fsub double %53, %55
%57 = fptrunc double %56 to float
store float %57, float* %18
%58 = load float, float* %18
%59 = load float, float* %18
%60 = fmul float %58, %59
store float %60, float* %19
%61 = load float, float* %16
%62 = load float, float* %21
%63 = fsub float %61, %62
store float %63, float* %17
%64 = load float, float* %17
%65 = load float, float* %17
%66 = fmul float %64, %65
store float %66, float* %20
%67 = load float, float* %18
%68 = load float*, float** %11
%69 = load i32, i32* %15
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds float, float* %68, i64 %70
%72 = load float, float* %71
%73 = load float, float* %17
%74 = load float*, float** %11
%75 = load i32, i32* %15
%76 = add nsw i32 %75, 1
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds float, float* %74, i64 %77
%79 = load float, float* %78
%80 = fmul float %73, %79
%81 = call float @llvm.fmuladd.f32(float %67, float %72, float %80)
%82 = load float, float* %19
%83 = load float, float* %18
%84 = load float, float* %18
%85 = fneg float %84
%86 = call float @llvm.fmuladd.f32(float %82, float %83, float %85)
%87 = load float*, float** %12
%88 = load i32, i32* %15
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds float, float* %87, i64 %89
%91 = load float, float* %90
%92 = load float, float* %20
%93 = load float, float* %17
%94 = load float, float* %17
%95 = fneg float %94
%96 = call float @llvm.fmuladd.f32(float %92, float %93, float %95)
%97 = load float*, float** %12
%98 = load i32, i32* %15
%99 = add nsw i32 %98, 1
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds float, float* %97, i64 %100
%102 = load float, float* %101
%103 = fmul float %96, %102
%104 = call float @llvm.fmuladd.f32(float %86, float %91, float %103)
%105 = load float, float* %23
%106 = call float @llvm.fmuladd.f32(float %104, float %105, float %81)
%107 = load float*, float** %13
store float %106, float* %107
%108 = load float*, float** %11
%109 = load i32, i32* %15
%110 = add nsw i32 %109, 1
%111 = sext i32 %110 to i64
%112 = getelementptr inbounds float, float* %108, i64 %111
%113 = load float, float* %112
%114 = load float*, float** %11
%115 = load i32, i32* %15
%116 = sext i32 %115 to i64
%117 = getelementptr inbounds float, float* %114, i64 %116
%118 = load float, float* %117
%119 = fsub float %113, %118
%120 = load float, float* %24
%121 = fmul float %119, %120
%122 = fpext float %121 to double
%123 = load float, float* %19
%124 = fpext float %123 to double
%125 = call double @llvm.fmuladd.f64(double 3.000000e+00, double %124, double -1.000000e+00)
%126 = load float*, float** %12
%127 = load i32, i32* %15
%128 = sext i32 %127 to i64
%129 = getelementptr inbounds float, float* %126, i64 %128
%130 = load float, float* %129
%131 = fpext float %130 to double
%132 = load float, float* %20
%133 = fpext float %132 to double
%134 = call double @llvm.fmuladd.f64(double 3.000000e+00, double %133, double -1.000000e+00)
%135 = load float*, float** %12
%136 = load i32, i32* %15
%137 = add nsw i32 %136, 1
%138 = sext i32 %137 to i64
%139 = getelementptr inbounds float, float* %135, i64 %138
%140 = load float, float* %139
%141 = fpext float %140 to double
%142 = fmul double %134, %141
%143 = call double @llvm.fmuladd.f64(double %125, double %131, double %142)
%144 = load float, float* %22
%145 = fpext float %144 to double
%146 = fneg double %143
%147 = call double @llvm.fmuladd.f64(double %146, double %145, double %122)
%148 = fptrunc double %147 to float
%149 = load float*, float** %14
store float %148, float* %149
br label %150
150: ; preds = %50, %47
ret void
}

LLVM IR (-O2):
define void @agbnp3_cspline_interpolate(float %0, float %1, i32 %2, float* nocapture %3, float* nocapture %4, float* nocapture writeonly %5, float* nocapture writeonly %6) {
%8 = fdiv float 1.000000e+00, %1
%9 = fdiv float %1, 6.000000e+00
%10 = fmul float %8, %0
%11 = fptosi float %10 to i32
%12 = add nsw i32 %2, -2
%13 = icmp slt i32 %12, %11
br i1 %13, label %14, label %15
14: ; preds = %7
store float 0.000000e+00, float* %5
br label %65
15: ; preds = %7
%16 = sitofp i32 %11 to float
%17 = fmul float %9, %1
%18 = sitofp i32 %11 to double
%19 = fadd double %18, 1.000000e+00
%20 = fpext float %10 to double
%21 = fsub double %19, %20
%22 = fptrunc double %21 to float
%23 = fmul float %22, %22
%24 = fsub float %10, %16
%25 = fmul float %24, %24
%26 = sext i32 %11 to i64
%27 = getelementptr inbounds float, float* %3, i64 %26
%28 = load float, float* %27
%29 = add nsw i32 %11, 1
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds float, float* %3, i64 %30
%32 = load float, float* %31
%33 = fmul float %24, %32
%34 = tail call float @llvm.fmuladd.f32(float %22, float %28, float %33)
%35 = fneg float %22
%36 = tail call float @llvm.fmuladd.f32(float %23, float %22, float %35)
%37 = getelementptr inbounds float, float* %4, i64 %26
%38 = load float, float* %37
%39 = fneg float %24
%40 = tail call float @llvm.fmuladd.f32(float %25, float %24, float %39)
%41 = getelementptr inbounds float, float* %4, i64 %30
%42 = load float, float* %41
%43 = fmul float %40, %42
%44 = tail call float @llvm.fmuladd.f32(float %36, float %38, float %43)
%45 = tail call float @llvm.fmuladd.f32(float %44, float %17, float %34)
store float %45, float* %5
%46 = load float, float* %31
%47 = load float, float* %27
%48 = fsub float %46, %47
%49 = fmul float %8, %48
%50 = fpext float %49 to double
%51 = fpext float %23 to double
%52 = tail call double @llvm.fmuladd.f64(double %51, double 3.000000e+00, double -1.000000e+00)
%53 = load float, float* %37
%54 = fpext float %53 to double
%55 = fpext float %25 to double
%56 = tail call double @llvm.fmuladd.f64(double %55, double 3.000000e+00, double -1.000000e+00)
%57 = load float, float* %41
%58 = fpext float %57 to double
%59 = fmul double %56, %58
%60 = tail call double @llvm.fmuladd.f64(double %52, double %54, double %59)
%61 = fpext float %9 to double
%62 = fneg double %60
%63 = tail call double @llvm.fmuladd.f64(double %62, double %61, double %50)
%64 = fptrunc double %63 to float
br label %65
65: ; preds = %15, %14
%66 = phi float [ %64, %15 ], [ 0.000000e+00, %14 ]
store float %66, float* %6
ret void
}