void interp(u0, un, n, u, r1) float u0, un;
int n;
float u[], r1;
{
  double r_1, r_2, r2, rn_1, r2n_2, r2n, r2n_2i, rn_i, ri, r2i, a0, an;
  int i;
  rn_1 = r1;
  for (i = 1; i < n - 1; ++i)
    rn_1 *= r1;
  r2n_2 = rn_1 * rn_1;
  r_1 = 1. / r1;
  r_2 = r_1 * r_1;
  r2 = r1 * r1;
  r2n = r2n_2 * r2;
  a0 = u0 / (1. - r2n);
  an = un / (1. - r2n);
  u[0] = u0;
  r2n_2i = r2n_2;
  r2i = r2;
  ri = r1;
  rn_i = rn_1;
  for (i = 1; i < n; i++) {
    u[i] = a0 * ri * (1 - r2n_2i) + an * rn_i * (1 - r2i);
    r2n_2i *= r_2;
    r2i *= r2;
    ri *= r1;
    rn_i *= r_1;
  }
  u[n] = un;
}


x86 assembly (clang, -O0):
<interp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
movsd  %xmm2,-0x90(%rbp)
ff
movaps %xmm0,%xmm2
movsd  -0x90(%rbp),%xmm0
ff
cvtsd2ss %xmm2,%xmm2
cvtsd2ss %xmm1,%xmm1
cvtsd2ss %xmm0,%xmm0
movss  %xmm2,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
movss  %xmm0,-0x1c(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movl   $0x1,-0x84(%rbp)
mov    -0x84(%rbp),%eax
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1190 <interp+0x90>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x84(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x84(%rbp)
jmp    1155 <interp+0x55>
movsd  -0x40(%rbp),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xe50(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movss  -0x1c(%rbp),%xmm0
mulss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x48(%rbp),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movss  -0x4(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe05(%rip),%xmm1
subsd  -0x50(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xde6(%rip),%xmm1
subsd  -0x50(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x80(%rbp)
movss  -0x4(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movl   $0x1,-0x84(%rbp)
mov    -0x84(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    131c <interp+0x21c>
movsd  -0x78(%rbp),%xmm0
mulsd  -0x68(%rbp),%xmm0
movsd  0xd74(%rip),%xmm2
subsd  -0x58(%rbp),%xmm2
movsd  -0x80(%rbp),%xmm1
mulsd  -0x60(%rbp),%xmm1
movsd  0xd5d(%rip),%xmm3
subsd  -0x70(%rbp),%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x84(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movsd  -0x30(%rbp),%xmm0
mulsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x38(%rbp),%xmm0
mulsd  -0x70(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
mulsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x28(%rbp),%xmm0
mulsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x84(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x84(%rbp)
jmp    126b <interp+0x16b>
movss  -0x8(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movslq -0xc(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<interp>:
cvtsd2ss %xmm0,%xmm8
cvtsd2ss %xmm2,%xmm4
cvtss2sd %xmm4,%xmm7
movaps %xmm7,%xmm2
cmp    $0x3,%edi
jl     1169 <interp+0x69>
lea    -0x2(%rdi),%ecx
lea    -0x3(%rdi),%edx
mov    %ecx,%eax
and    $0x7,%eax
movaps %xmm7,%xmm2
cmp    $0x7,%edx
jb     1155 <interp+0x55>
and    $0xfffffff8,%ecx
movaps %xmm7,%xmm2
xchg   %ax,%ax
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
mulsd  %xmm7,%xmm2
add    $0xfffffff8,%ecx
jne    1130 <interp+0x30>
test   %eax,%eax
je     1169 <interp+0x69>
nopl   0x0(%rax)
mulsd  %xmm7,%xmm2
add    $0xffffffff,%eax
jne    1160 <interp+0x60>
cvtsd2ss %xmm1,%xmm9
movss  %xmm8,(%rsi)
cmp    $0x2,%edi
jl     1238 <interp+0x138>
movaps %xmm2,%xmm5
mulsd  %xmm2,%xmm5
movsd  0xe74(%rip),%xmm10
movapd %xmm10,%xmm12
divsd  %xmm7,%xmm12
movapd %xmm12,%xmm11
mulsd  %xmm12,%xmm11
mulss  %xmm4,%xmm4
cvtss2sd %xmm4,%xmm13
movapd %xmm5,%xmm0
mulsd  %xmm13,%xmm0
cvtss2sd %xmm8,%xmm8
movapd %xmm10,%xmm4
subsd  %xmm0,%xmm4
divsd  %xmm4,%xmm8
cvtss2sd %xmm9,%xmm14
divsd  %xmm4,%xmm14
mov    %edi,%eax
mov    $0x1,%ecx
movapd %xmm13,%xmm4
movapd %xmm7,%xmm0
nop
movapd %xmm8,%xmm1
mulsd  %xmm0,%xmm1
movapd %xmm10,%xmm3
subsd  %xmm5,%xmm3
mulsd  %xmm1,%xmm3
movapd %xmm14,%xmm1
mulsd  %xmm2,%xmm1
movapd %xmm10,%xmm6
subsd  %xmm4,%xmm6
mulsd  %xmm1,%xmm6
addsd  %xmm3,%xmm6
xorps  %xmm1,%xmm1
cvtsd2ss %xmm6,%xmm1
movss  %xmm1,(%rsi,%rcx,4)
mulsd  %xmm11,%xmm5
mulsd  %xmm13,%xmm4
mulsd  %xmm7,%xmm0
mulsd  %xmm12,%xmm2
add    $0x1,%rcx
cmp    %rcx,%rax
jne    11e0 <interp+0xe0>
movslq %edi,%rax
movss  %xmm9,(%rsi,%rax,4)
ret

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

LLVM IR (-O2):
define void @interp(double %0, double %1, i32 %2, float* nocapture writeonly %3, double %4) {
%6 = fptrunc double %0 to float
%7 = fptrunc double %1 to float
%8 = fptrunc double %4 to float
%9 = fpext float %8 to double
%10 = icmp sgt i32 %2, 2
br i1 %10, label %11, label %41
11: ; preds = %5
%12 = add i32 %2, -2
%13 = add i32 %2, -3
%14 = and i32 %12, 7
%15 = icmp ult i32 %13, 7
br i1 %15, label %31, label %16
16: ; preds = %11
%17 = and i32 %12, -8
br label %18
18: ; preds = %18, %16
%19 = phi double [ %9, %16 ], [ %28, %18 ]
%20 = phi i32 [ 0, %16 ], [ %29, %18 ]
%21 = fmul double %19, %9
%22 = fmul double %21, %9
%23 = fmul double %22, %9
%24 = fmul double %23, %9
%25 = fmul double %24, %9
%26 = fmul double %25, %9
%27 = fmul double %26, %9
%28 = fmul double %27, %9
%29 = add i32 %20, 8
%30 = icmp eq i32 %29, %17
br i1 %30, label %31, label %18
31: ; preds = %18, %11
%32 = phi double [ undef, %11 ], [ %28, %18 ]
%33 = phi double [ %9, %11 ], [ %28, %18 ]
%34 = icmp eq i32 %14, 0
br i1 %34, label %41, label %35
35: ; preds = %31, %35
%36 = phi double [ %38, %35 ], [ %33, %31 ]
%37 = phi i32 [ %39, %35 ], [ 0, %31 ]
%38 = fmul double %36, %9
%39 = add i32 %37, 1
%40 = icmp eq i32 %39, %14
br i1 %40, label %41, label %35
41: ; preds = %31, %35, %5
%42 = phi double [ %9, %5 ], [ %32, %31 ], [ %38, %35 ]
%43 = fmul double %42, %42
%44 = fdiv double 1.000000e+00, %9
%45 = fmul double %44, %44
%46 = fmul float %8, %8
%47 = fpext float %46 to double
%48 = fmul double %43, %47
%49 = fpext float %6 to double
%50 = fsub double 1.000000e+00, %48
%51 = fdiv double %49, %50
%52 = fpext float %7 to double
%53 = fdiv double %52, %50
store float %6, float* %3
%54 = icmp sgt i32 %2, 1
br i1 %54, label %55, label %77
55: ; preds = %41
%56 = zext i32 %2 to i64
br label %57
57: ; preds = %55, %57
%58 = phi i64 [ 1, %55 ], [ %75, %57 ]
%59 = phi double [ %43, %55 ], [ %71, %57 ]
%60 = phi double [ %47, %55 ], [ %72, %57 ]
%61 = phi double [ %9, %55 ], [ %73, %57 ]
%62 = phi double [ %42, %55 ], [ %74, %57 ]
%63 = fmul double %51, %61
%64 = fsub double 1.000000e+00, %59
%65 = fmul double %53, %62
%66 = fsub double 1.000000e+00, %60
%67 = fmul double %65, %66
%68 = tail call double @llvm.fmuladd.f64(double %63, double %64, double %67)
%69 = fptrunc double %68 to float
%70 = getelementptr inbounds float, float* %3, i64 %58
store float %69, float* %70
%71 = fmul double %45, %59
%72 = fmul double %60, %47
%73 = fmul double %61, %9
%74 = fmul double %44, %62
%75 = add nuw nsw i64 %58, 1
%76 = icmp eq i64 %75, %56
br i1 %76, label %77, label %57
77: ; preds = %57, %41
%78 = sext i32 %2 to i64
%79 = getelementptr inbounds float, float* %3, i64 %78
store float %7, float* %79
ret void
}