double poledf(double x, double *a, int m, double *d) {
  for (m--; m > 0; m--) {
    x -= a[m + 1] * d[m];
    d[m] = d[m - 1];
  }
  x -= a[1] * d[0];
  d[0] = x;
  return (x);
}


x86 assembly (clang, -O0):
<poledf>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    119c <poledf+0x9c>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x8(%rbp),%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    111d <poledf+0x1d>
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm2
movsd  -0x8(%rbp),%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<poledf>:
cmp    $0x2,%esi
jl     1155 <poledf+0x55>
mov    %esi,%eax
mov    $0xfffffffe,%ecx
add    %rax,%rcx
add    $0xffffffffffffffff,%rax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movsd  0x8(%rdi,%rax,8),%xmm1
mov    %eax,%r8d
mulsd  (%rdx,%r8,8),%xmm1
subsd  %xmm1,%xmm0
mov    %ecx,%esi
movsd  (%rdx,%rsi,8),%xmm1
movsd  %xmm1,(%rdx,%r8,8)
add    $0xffffffffffffffff,%rcx
lea    -0x1(%rax),%rsi
add    $0x1,%rax
cmp    $0x2,%rax
mov    %rsi,%rax
ja     1120 <poledf+0x20>
movsd  0x8(%rdi),%xmm1
mulsd  (%rdx),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,(%rdx)
ret

LLVM IR (-O0):
define double @poledf(double %0, double* %1, i32 %2, double* %3) {
%5 = alloca double
%6 = alloca double*
%7 = alloca i32
%8 = alloca double*
store double %0, double* %5
store double* %1, double** %6
store i32 %2, i32* %7
store double* %3, double** %8
%9 = load i32, i32* %7
%10 = add nsw i32 %9, -1
store i32 %10, i32* %7
br label %11
11: ; preds = %39, %4
%12 = load i32, i32* %7
%13 = icmp sgt i32 %12, 0
br i1 %13, label %14, label %42
14: ; preds = %11
%15 = load double*, double** %6
%16 = load i32, i32* %7
%17 = add nsw i32 %16, 1
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds double, double* %15, i64 %18
%20 = load double, double* %19
%21 = load double*, double** %8
%22 = load i32, i32* %7
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds double, double* %21, i64 %23
%25 = load double, double* %24
%26 = load double, double* %5
%27 = fneg double %20
%28 = call double @llvm.fmuladd.f64(double %27, double %25, double %26)
store double %28, double* %5
%29 = load double*, double** %8
%30 = load i32, i32* %7
%31 = sub 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* %7
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds double, double* %35, i64 %37
store double %34, double* %38
br label %39
39: ; preds = %14
%40 = load i32, i32* %7
%41 = add nsw i32 %40, -1
store i32 %41, i32* %7
br label %11
42: ; preds = %11
%43 = load double*, double** %6
%44 = getelementptr inbounds double, double* %43, i64 1
%45 = load double, double* %44
%46 = load double*, double** %8
%47 = getelementptr inbounds double, double* %46, i64 0
%48 = load double, double* %47
%49 = load double, double* %5
%50 = fneg double %45
%51 = call double @llvm.fmuladd.f64(double %50, double %48, double %49)
store double %51, double* %5
%52 = load double, double* %5
%53 = load double*, double** %8
%54 = getelementptr inbounds double, double* %53, i64 0
store double %52, double* %54
%55 = load double, double* %5
ret double %55
}

LLVM IR (-O2):
define double @poledf(double %0, double* nocapture %1, i32 %2, double* nocapture %3) {
%5 = icmp sgt i32 %2, 1
br i1 %5, label %6, label %24
6: ; preds = %4
%7 = zext i32 %2 to i64
br label %8
8: ; preds = %6, %8
%9 = phi i64 [ %7, %6 ], [ %11, %8 ]
%10 = phi double [ %0, %6 ], [ %18, %8 ]
%11 = add nsw i64 %9, -1
%12 = getelementptr inbounds double, double* %1, i64 %9
%13 = load double, double* %12
%14 = and i64 %11, 4294967295
%15 = getelementptr inbounds double, double* %3, i64 %14
%16 = load double, double* %15
%17 = fneg double %13
%18 = tail call double @llvm.fmuladd.f64(double %17, double %16, double %10)
%19 = add nuw i64 %9, 4294967294
%20 = and i64 %19, 4294967295
%21 = getelementptr inbounds double, double* %3, i64 %20
%22 = load double, double* %21
store double %22, double* %15
%23 = icmp ugt i64 %9, 2
br i1 %23, label %8, label %24
24: ; preds = %8, %4
%25 = phi double [ %0, %4 ], [ %18, %8 ]
%26 = getelementptr inbounds double, double* %1, i64 1
%27 = load double, double* %26
%28 = load double, double* %3
%29 = fneg double %27
%30 = tail call double @llvm.fmuladd.f64(double %29, double %28, double %25)
store double %30, double* %3
ret double %30
}