void phidf(const double x, const int m, double a, double *d) {
  int i;
  d[0] = a * d[0] + (1.0 - a * a) * x;
  for (i = 1; i < m; i++)
    d[i] += a * (d[i + 1] - d[i - 1]);
  for (i = m; i >= 1; i--)
    d[i] = d[i - 1];
  return;
}


x86 assembly (clang, -O0):
<phidf>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm2
movsd  -0x18(%rbp),%xmm1
movsd  -0x18(%rbp),%xmm3
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm3,%xmm1
movsd  0xeb1(%rip),%xmm3
addsd  %xmm3,%xmm1
mulsd  -0x8(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x1,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    11cc <phidf+0xcc>
movsd  -0x18(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x20(%rbp),%rax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm2
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    116f <phidf+0x6f>
mov    -0xc(%rbp),%eax
mov    %eax,-0x24(%rbp)
cmpl   $0x1,-0x24(%rbp)
jl     1209 <phidf+0x109>
mov    -0x20(%rbp),%rax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    11d2 <phidf+0xd2>
pop    %rbp
ret

x86 assembly (clang, -O2):
<phidf>:
push   %r14
push   %rbx
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
movsd  0xeed(%rip),%xmm3
subsd  %xmm2,%xmm3
mulsd  %xmm0,%xmm3
movsd  (%rsi),%xmm0
mulsd  %xmm1,%xmm0
addsd  %xmm3,%xmm0
movsd  %xmm0,(%rsi)
mov    %edi,%ecx
cmp    $0x2,%edi
jl     11cd <phidf+0xcd>
movsd  0x8(%rsi),%xmm3
lea    -0x1(%rcx),%r8
mov    $0x1,%ebx
cmp    $0x2,%edi
jne    114f <phidf+0x4f>
movapd %xmm3,%xmm2
jmp    11b0 <phidf+0xb0>
mov    %r8,%r9
and    $0xfffffffffffffffe,%r9
neg    %r9
mov    $0x1,%edx
xchg   %ax,%ax
movsd  0x8(%rsi,%rdx,8),%xmm4
movsd  0x10(%rsi,%rdx,8),%xmm2
movapd %xmm4,%xmm5
subsd  %xmm0,%xmm5
mulsd  %xmm1,%xmm5
addsd  %xmm3,%xmm5
movsd  %xmm5,(%rsi,%rdx,8)
lea    0x2(%rdx),%rbx
movapd %xmm2,%xmm0
subsd  %xmm5,%xmm0
mulsd  %xmm1,%xmm0
addsd  %xmm4,%xmm0
movsd  %xmm0,0x8(%rsi,%rdx,8)
lea    (%r9,%rdx,1),%rax
add    $0x2,%rax
movapd %xmm2,%xmm3
mov    %rbx,%rdx
cmp    $0x1,%rax
jne    1160 <phidf+0x60>
test   $0x1,%r8b
je     11cd <phidf+0xcd>
movsd  0x8(%rsi,%rbx,8),%xmm3
subsd  %xmm0,%xmm3
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
movsd  %xmm1,(%rsi,%rbx,8)
test   %edi,%edi
jle    11f8 <phidf+0xf8>
cmp    $0x4,%edi
jae    11fc <phidf+0xfc>
add    $0x1,%rcx
nopw   0x0(%rax,%rax,1)
lea    -0x2(%rcx),%eax
movsd  (%rsi,%rax,8),%xmm0
movsd  %xmm0,-0x8(%rsi,%rcx,8)
add    $0xffffffffffffffff,%rcx
cmp    $0x1,%rcx
ja     11e0 <phidf+0xe0>
pop    %rbx
pop    %r14
ret
lea    -0x1(%rcx),%r8
add    $0xffffffff,%edi
mov    $0x8,%edx
mov    %r8,%rax
mul    %rdx
seto   %r9b
cmp    %r8d,%edi
jb     11d6 <phidf+0xd6>
mov    %r8,%rbx
shr    $0x20,%rbx
jne    11d6 <phidf+0xd6>
lea    (%rsi,%rcx,8),%rdx
mov    %rdx,%rbx
sub    %rax,%rbx
cmp    %rdx,%rbx
ja     11d6 <phidf+0xd6>
test   %r9b,%r9b
jne    11d6 <phidf+0xd6>
lea    (%rsi,%rdi,8),%rbx
mov    %rbx,%rdx
sub    %rax,%rdx
cmp    %rbx,%rdx
ja     11d6 <phidf+0xd6>
test   %r9b,%r9b
jne    11d6 <phidf+0xd6>
lea    0x8(%rsi),%rax
lea    (%rsi,%rdi,8),%rdx
add    $0x8,%rdx
cmp    %rdx,%rax
jae    1275 <phidf+0x175>
lea    (%rsi,%rcx,8),%rax
add    $0x8,%rax
add    $0x1,%rdi
sub    %rcx,%rdi
lea    (%rsi,%rdi,8),%rdx
cmp    %rax,%rdx
jb     11d6 <phidf+0xd6>
mov    $0xffffffff,%r9d
mov    %ecx,%r10d
and    $0xfffffffc,%r10d
lea    -0x4(%r10),%rax
mov    %rax,%r11
shr    $0x2,%r11
add    $0x1,%r11
test   %rax,%rax
je     133a <phidf+0x23a>
mov    %r11,%rdi
and    $0xfffffffffffffffe,%rdi
lea    (%rsi,%r8,8),%rax
lea    (%rcx,%r9,1),%r8
add    $0xfffffffffffffffc,%r8
lea    (%rcx,%r9,1),%r14
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
lea    (%r14,%rdx,1),%ebx
movups -0x18(%rsi,%rbx,8),%xmm0
movups -0x8(%rsi,%rbx,8),%xmm1
movups %xmm1,(%rax,%rdx,8)
movups %xmm0,-0x10(%rax,%rdx,8)
lea    (%r8,%rdx,1),%ebx
movupd -0x18(%rsi,%rbx,8),%xmm0
movupd -0x8(%rsi,%rbx,8),%xmm1
movupd %xmm1,-0x20(%rax,%rdx,8)
movupd %xmm0,-0x30(%rax,%rdx,8)
add    $0xfffffffffffffff8,%rdx
add    $0xfffffffffffffffe,%rdi
jne    12c0 <phidf+0x1c0>
neg    %rdx
test   $0x1,%r11b
je     1329 <phidf+0x229>
mov    %rcx,%rax
sub    %rdx,%rax
add    %eax,%r9d
movupd -0x18(%rsi,%r9,8),%xmm0
movupd -0x8(%rsi,%r9,8),%xmm1
movupd %xmm1,-0x8(%rsi,%rax,8)
movupd %xmm0,-0x18(%rsi,%rax,8)
cmp    %rcx,%r10
je     11f8 <phidf+0xf8>
and    $0x3,%ecx
jmp    11d6 <phidf+0xd6>
xor    %edx,%edx
test   $0x1,%r11b
jne    1306 <phidf+0x206>
jmp    1329 <phidf+0x229>

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

LLVM IR (-O2):
define void @phidf(double %0, i32 %1, double %2, double* nocapture %3) {
%5 = load double, double* %3
%6 = fneg double %2
%7 = tail call double @llvm.fmuladd.f64(double %6, double %2, double 1.000000e+00)
%8 = fmul double %7, %0
%9 = tail call double @llvm.fmuladd.f64(double %2, double %5, double %8)
store double %9, double* %3
%10 = icmp sgt i32 %1, 1
br i1 %10, label %11, label %32
11: ; preds = %4
%12 = zext i32 %1 to i64
%13 = getelementptr inbounds double, double* %3, i64 1
%14 = load double, double* %13
%15 = add nsw i64 %12, -1
%16 = and i64 %15, 1
%17 = icmp eq i32 %1, 2
br i1 %17, label %20, label %18
18: ; preds = %11
%19 = and i64 %15, -2
br label %155
20: ; preds = %155, %11
%21 = phi double [ %14, %11 ], [ %168, %155 ]
%22 = phi double [ %9, %11 ], [ %171, %155 ]
%23 = phi i64 [ 1, %11 ], [ %166, %155 ]
%24 = icmp eq i64 %16, 0
br i1 %24, label %32, label %25
25: ; preds = %20
%26 = add nuw nsw i64 %23, 1
%27 = getelementptr inbounds double, double* %3, i64 %26
%28 = load double, double* %27
%29 = fsub double %28, %22
%30 = getelementptr inbounds double, double* %3, i64 %23
%31 = tail call double @llvm.fmuladd.f64(double %2, double %29, double %21)
store double %31, double* %30
br label %32
32: ; preds = %25, %20, %4
%33 = icmp sgt i32 %1, 0
br i1 %33, label %34, label %182
34: ; preds = %32
%35 = zext i32 %1 to i64
%36 = icmp ult i32 %1, 4
br i1 %36, label %153, label %37
37: ; preds = %34
%38 = add nsw i64 %35, -1
%39 = add i32 %1, -1
%40 = trunc i64 %38 to i32
%41 = icmp ult i32 %39, %40
%42 = icmp ugt i64 %38, 4294967295
%43 = or i1 %41, %42
%44 = getelementptr double, double* %3, i64 %35
%45 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %38, i64 8)
%46 = extractvalue { i64, i1 } %45, 0
%47 = extractvalue { i64, i1 } %45, 1
%48 = bitcast double* %44 to i8*
%49 = sub i64 0, %46
%50 = getelementptr i8, i8* %48, i64 %49
%51 = icmp ugt i8* %50, %48
%52 = or i1 %51, %47
%53 = zext i32 %39 to i64
%54 = getelementptr double, double* %3, i64 %53
%55 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %38, i64 8)
%56 = extractvalue { i64, i1 } %55, 0
%57 = extractvalue { i64, i1 } %55, 1
%58 = bitcast double* %54 to i8*
%59 = sub i64 0, %56
%60 = getelementptr i8, i8* %58, i64 %59
%61 = icmp ugt i8* %60, %58
%62 = or i1 %61, %57
%63 = or i1 %43, %52
%64 = or i1 %63, %62
br i1 %64, label %153, label %65
65: ; preds = %37
%66 = getelementptr double, double* %3, i64 1
%67 = add nuw nsw i64 %35, 1
%68 = getelementptr double, double* %3, i64 %67
%69 = add i32 %1, -1
%70 = zext i32 %69 to i64
%71 = add nuw nsw i64 %70, 1
%72 = sub nsw i64 %71, %35
%73 = getelementptr double, double* %3, i64 %72
%74 = add nuw nsw i64 %70, 1
%75 = getelementptr double, double* %3, i64 %74
%76 = icmp ult double* %66, %75
%77 = icmp ult double* %73, %68
%78 = and i1 %76, %77
br i1 %78, label %153, label %79
79: ; preds = %65
%80 = and i64 %35, 4294967292
%81 = and i64 %35, 3
%82 = add nsw i64 %80, -4
%83 = lshr exact i64 %82, 2
%84 = add nuw nsw i64 %83, 1
%85 = and i64 %84, 1
%86 = icmp eq i64 %82, 0
br i1 %86, label %130, label %87
87: ; preds = %79
%88 = and i64 %84, 9223372036854775806
br label %89
89: ; preds = %89, %87
%90 = phi i64 [ 0, %87 ], [ %127, %89 ]
%91 = phi i64 [ 0, %87 ], [ %128, %89 ]
%92 = sub i64 %35, %90
%93 = add i64 %92, 4294967295
%94 = and i64 %93, 4294967295
%95 = getelementptr inbounds double, double* %3, i64 %94
%96 = getelementptr inbounds double, double* %95, i64 -1
%97 = bitcast double* %96 to <2 x double>*
%98 = load <2 x double>, <2 x double>* %97
%99 = getelementptr inbounds double, double* %95, i64 -2
%100 = getelementptr inbounds double, double* %99, i64 -1
%101 = bitcast double* %100 to <2 x double>*
%102 = load <2 x double>, <2 x double>* %101
%103 = getelementptr inbounds double, double* %3, i64 %92
%104 = getelementptr inbounds double, double* %103, i64 -1
%105 = bitcast double* %104 to <2 x double>*
store <2 x double> %98, <2 x double>* %105
%106 = getelementptr inbounds double, double* %103, i64 -2
%107 = getelementptr inbounds double, double* %106, i64 -1
%108 = bitcast double* %107 to <2 x double>*
store <2 x double> %102, <2 x double>* %108
%109 = or i64 %90, 4
%110 = sub i64 %35, %109
%111 = add i64 %110, 4294967295
%112 = and i64 %111, 4294967295
%113 = getelementptr inbounds double, double* %3, i64 %112
%114 = getelementptr inbounds double, double* %113, i64 -1
%115 = bitcast double* %114 to <2 x double>*
%116 = load <2 x double>, <2 x double>* %115
%117 = getelementptr inbounds double, double* %113, i64 -2
%118 = getelementptr inbounds double, double* %117, i64 -1
%119 = bitcast double* %118 to <2 x double>*
%120 = load <2 x double>, <2 x double>* %119
%121 = getelementptr inbounds double, double* %3, i64 %110
%122 = getelementptr inbounds double, double* %121, i64 -1
%123 = bitcast double* %122 to <2 x double>*
store <2 x double> %116, <2 x double>* %123
%124 = getelementptr inbounds double, double* %121, i64 -2
%125 = getelementptr inbounds double, double* %124, i64 -1
%126 = bitcast double* %125 to <2 x double>*
store <2 x double> %120, <2 x double>* %126
%127 = add nuw i64 %90, 8
%128 = add i64 %91, 2
%129 = icmp eq i64 %128, %88
br i1 %129, label %130, label %89
130: ; preds = %89, %79
%131 = phi i64 [ 0, %79 ], [ %127, %89 ]
%132 = icmp eq i64 %85, 0
br i1 %132, label %151, label %133
133: ; preds = %130
%134 = sub i64 %35, %131
%135 = add i64 %134, 4294967295
%136 = and i64 %135, 4294967295
%137 = getelementptr inbounds double, double* %3, i64 %136
%138 = getelementptr inbounds double, double* %137, i64 -1
%139 = bitcast double* %138 to <2 x double>*
%140 = load <2 x double>, <2 x double>* %139
%141 = getelementptr inbounds double, double* %137, i64 -2
%142 = getelementptr inbounds double, double* %141, i64 -1
%143 = bitcast double* %142 to <2 x double>*
%144 = load <2 x double>, <2 x double>* %143
%145 = getelementptr inbounds double, double* %3, i64 %134
%146 = getelementptr inbounds double, double* %145, i64 -1
%147 = bitcast double* %146 to <2 x double>*
store <2 x double> %140, <2 x double>* %147
%148 = getelementptr inbounds double, double* %145, i64 -2
%149 = getelementptr inbounds double, double* %148, i64 -1
%150 = bitcast double* %149 to <2 x double>*
store <2 x double> %144, <2 x double>* %150
br label %151
151: ; preds = %130, %133
%152 = icmp eq i64 %80, %35
br i1 %152, label %182, label %153
153: ; preds = %65, %37, %34, %151
%154 = phi i64 [ %35, %65 ], [ %35, %37 ], [ %35, %34 ], [ %81, %151 ]
br label %174
155: ; preds = %155, %18
%156 = phi double [ %14, %18 ], [ %168, %155 ]
%157 = phi double [ %9, %18 ], [ %171, %155 ]
%158 = phi i64 [ 1, %18 ], [ %166, %155 ]
%159 = phi i64 [ 0, %18 ], [ %172, %155 ]
%160 = add nuw nsw i64 %158, 1
%161 = getelementptr inbounds double, double* %3, i64 %160
%162 = load double, double* %161
%163 = fsub double %162, %157
%164 = getelementptr inbounds double, double* %3, i64 %158
%165 = tail call double @llvm.fmuladd.f64(double %2, double %163, double %156)
store double %165, double* %164
%166 = add nuw nsw i64 %158, 2
%167 = getelementptr inbounds double, double* %3, i64 %166
%168 = load double, double* %167
%169 = fsub double %168, %165
%170 = getelementptr inbounds double, double* %3, i64 %160
%171 = tail call double @llvm.fmuladd.f64(double %2, double %169, double %162)
store double %171, double* %170
%172 = add i64 %159, 2
%173 = icmp eq i64 %172, %19
br i1 %173, label %20, label %155
174: ; preds = %153, %174
%175 = phi i64 [ %176, %174 ], [ %154, %153 ]
%176 = add nsw i64 %175, -1
%177 = and i64 %176, 4294967295
%178 = getelementptr inbounds double, double* %3, i64 %177
%179 = load double, double* %178
%180 = getelementptr inbounds double, double* %3, i64 %175
store double %179, double* %180
%181 = icmp ugt i64 %175, 1
br i1 %181, label %174, label %182
182: ; preds = %174, %151, %32
ret void
}