float cubicInterpolate(const float p[4], const float x) {
  return p[1] + 0.5 * x *
                    (p[2] - p[0] +
                     x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] +
                          x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
}


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

LLVM IR (-O2):
define float @cubicInterpolate(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
}