float cubic_interpolation(float v[4], float x) {
  return v[1] + 0.5 * x *
                    (v[2] - v[0] +
                     x * (2.0 * v[0] - 5.0 * v[1] + 4.0 * v[2] - v[3] +
                          x * (3.0 * (v[1] - v[2]) + v[3] - v[0])));
  float y = 3.0 * (v[1] - v[2]) + v[3] - v[0];
  y = x * y + 2.0 * v[0] - 5.0 * v[1] + 4.0 * v[2] - v[3];
  y = x * y + v[2] - v[0];
  y = 0.5 * x * y + v[1];
  return y;
}


x86 assembly (clang, -O0):
<cubic_interpolation>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movss  %xmm0,-0xc(%rbp)
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm2
movsd  0xeed(%rip),%xmm0
mulsd  %xmm2,%xmm0
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm2
mov    -0x8(%rbp),%rax
subss  (%rax),%xmm2
cvtss2sd %xmm2,%xmm3
movss  -0xc(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm4
cvtss2sd %xmm4,%xmm4
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm5
cvtss2sd %xmm5,%xmm6
movsd  0xea2(%rip),%xmm5
mulsd  %xmm6,%xmm5
movq   %xmm5,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm5
addsd  %xmm4,%xmm4
addsd  %xmm5,%xmm4
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm5
cvtss2sd %xmm5,%xmm5
movsd  0xe62(%rip),%xmm6
mulsd  %xmm6,%xmm5
addsd  %xmm4,%xmm5
mov    -0x8(%rbp),%rax
movss  0xc(%rax),%xmm4
cvtss2sd %xmm4,%xmm4
subsd  %xmm4,%xmm5
movss  -0xc(%rbp),%xmm4
cvtss2sd %xmm4,%xmm4
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm6
mov    -0x8(%rbp),%rax
subss  0x8(%rax),%xmm6
cvtss2sd %xmm6,%xmm6
mov    -0x8(%rbp),%rax
movss  0xc(%rax),%xmm7
cvtss2sd %xmm7,%xmm7
movsd  0xe0c(%rip),%xmm8
mulsd  %xmm8,%xmm6
addsd  %xmm7,%xmm6
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm7
cvtss2sd %xmm7,%xmm7
subsd  %xmm7,%xmm6
mulsd  %xmm6,%xmm4
addsd  %xmm5,%xmm4
mulsd  %xmm4,%xmm2
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<cubic_interpolation>:
movss  (%rdi),%xmm3
movss  0x4(%rdi),%xmm4
cvtss2sd %xmm4,%xmm8
cvtss2sd %xmm0,%xmm2
movsd  0xee6(%rip),%xmm0
mulsd  %xmm2,%xmm0
movss  0x8(%rdi),%xmm5
cvtss2sd %xmm5,%xmm6
subss  %xmm5,%xmm4
subss  %xmm3,%xmm5
cvtss2sd %xmm5,%xmm5
cvtss2sd %xmm3,%xmm3
movsd  0xec9(%rip),%xmm7
mulsd  %xmm8,%xmm7
movss  0xc(%rdi),%xmm1
cvtss2sd %xmm1,%xmm1
cvtss2sd %xmm4,%xmm4
mulsd  0xebf(%rip),%xmm4
addsd  %xmm1,%xmm4
subsd  %xmm3,%xmm4
addsd  %xmm3,%xmm3
addsd  %xmm7,%xmm3
mulsd  0xe9f(%rip),%xmm6
addsd  %xmm3,%xmm6
subsd  %xmm1,%xmm6
mulsd  %xmm2,%xmm4
addsd  %xmm6,%xmm4
mulsd  %xmm2,%xmm4
addsd  %xmm5,%xmm4
mulsd  %xmm0,%xmm4
addsd  %xmm8,%xmm4
xorps  %xmm0,%xmm0
cvtsd2ss %xmm4,%xmm0
ret

LLVM IR (-O0):
define float @cubic_interpolation(float* %0, float %1) {
%3 = alloca float*
%4 = alloca float
%5 = alloca float
store float* %0, float** %3
store float %1, float* %4
%6 = load float*, float** %3
%7 = getelementptr inbounds float, float* %6, i64 1
%8 = load float, float* %7
%9 = fpext float %8 to double
%10 = load float, float* %4
%11 = fpext float %10 to double
%12 = fmul double 5.000000e-01, %11
%13 = load float*, float** %3
%14 = getelementptr inbounds float, float* %13, i64 2
%15 = load float, float* %14
%16 = load float*, float** %3
%17 = getelementptr inbounds float, float* %16, i64 0
%18 = load float, float* %17
%19 = fsub float %15, %18
%20 = fpext float %19 to double
%21 = load float, float* %4
%22 = fpext float %21 to double
%23 = load float*, float** %3
%24 = getelementptr inbounds float, float* %23, i64 0
%25 = load float, float* %24
%26 = fpext float %25 to double
%27 = load float*, float** %3
%28 = getelementptr inbounds float, float* %27, i64 1
%29 = load float, float* %28
%30 = fpext float %29 to double
%31 = fmul double 5.000000e+00, %30
%32 = fneg double %31
%33 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %26, double %32)
%34 = load float*, float** %3
%35 = getelementptr inbounds float, float* %34, i64 2
%36 = load float, float* %35
%37 = fpext float %36 to double
%38 = call double @llvm.fmuladd.f64(double 4.000000e+00, double %37, double %33)
%39 = load float*, float** %3
%40 = getelementptr inbounds float, float* %39, i64 3
%41 = load float, float* %40
%42 = fpext float %41 to double
%43 = fsub double %38, %42
%44 = load float, float* %4
%45 = fpext float %44 to double
%46 = load float*, float** %3
%47 = getelementptr inbounds float, float* %46, i64 1
%48 = load float, float* %47
%49 = load float*, float** %3
%50 = getelementptr inbounds float, float* %49, i64 2
%51 = load float, float* %50
%52 = fsub float %48, %51
%53 = fpext float %52 to double
%54 = load float*, float** %3
%55 = getelementptr inbounds float, float* %54, i64 3
%56 = load float, float* %55
%57 = fpext float %56 to double
%58 = call double @llvm.fmuladd.f64(double 3.000000e+00, double %53, double %57)
%59 = load float*, float** %3
%60 = getelementptr inbounds float, float* %59, i64 0
%61 = load float, float* %60
%62 = fpext float %61 to double
%63 = fsub double %58, %62
%64 = call double @llvm.fmuladd.f64(double %45, double %63, double %43)
%65 = call double @llvm.fmuladd.f64(double %22, double %64, double %20)
%66 = call double @llvm.fmuladd.f64(double %12, double %65, double %9)
%67 = fptrunc double %66 to float
ret float %67
}

LLVM IR (-O2):
define float @cubic_interpolation(float* nocapture %0, float %1) {
%3 = getelementptr inbounds float, float* %0, i64 1
%4 = load float, float* %3
%5 = fpext float %4 to double
%6 = fpext float %1 to double
%7 = fmul double %6, 5.000000e-01
%8 = getelementptr inbounds float, float* %0, i64 2
%9 = load float, float* %8
%10 = load float, float* %0
%11 = fsub float %9, %10
%12 = fpext float %11 to double
%13 = fpext float %10 to double
%14 = fmul double %5, -5.000000e+00
%15 = tail call double @llvm.fmuladd.f64(double %13, double 2.000000e+00, double %14)
%16 = fpext float %9 to double
%17 = tail call double @llvm.fmuladd.f64(double %16, double 4.000000e+00, double %15)
%18 = getelementptr inbounds float, float* %0, i64 3
%19 = load float, float* %18
%20 = fpext float %19 to double
%21 = fsub double %17, %20
%22 = fsub float %4, %9
%23 = fpext float %22 to double
%24 = tail call double @llvm.fmuladd.f64(double %23, double 3.000000e+00, double %20)
%25 = fsub double %24, %13
%26 = tail call double @llvm.fmuladd.f64(double %6, double %25, double %21)
%27 = tail call double @llvm.fmuladd.f64(double %6, double %26, double %12)
%28 = tail call double @llvm.fmuladd.f64(double %7, double %27, double %5)
%29 = fptrunc double %28 to float
ret float %29
}