double chbevl(double x, void *array, int n) {
  double b0, b1, b2, *p;
  int i;
  p = (double *)array;
  b0 = *p++;
  b1 = 0.0;
  i = n - 1;
  do {
    b2 = b1;
    b1 = b0;
    b0 = x * b1 - b2 + *p++;
  } while (--i);
  return (0.5 * (b0 - b2));
}


x86 assembly (clang, -O0):
<chbevl>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x38(%rbp)
movsd  (%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x3c(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  -0x28(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x38(%rbp)
addsd  (%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x3c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x3c(%rbp)
cmp    $0x0,%eax
jne    1141 <chbevl+0x41>
movsd  -0x20(%rbp),%xmm1
subsd  -0x30(%rbp),%xmm1
movsd  0xe41(%rip),%xmm0
mulsd  %xmm1,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<chbevl>:
movsd  (%rdi),%xmm1
add    $0x8,%rdi
lea    -0x1(%rsi),%eax
lea    -0x2(%rsi),%ecx
test   $0x3,%al
je     1161 <chbevl+0x61>
add    $0xff,%sil
movzbl %sil,%edx
and    $0x3,%edx
xorpd  %xmm4,%xmm4
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movapd %xmm1,%xmm2
movapd %xmm4,%xmm3
movapd %xmm0,%xmm1
mulsd  %xmm2,%xmm1
subsd  %xmm4,%xmm1
addsd  (%rdi),%xmm1
add    $0x8,%rdi
add    $0x1,%rsi
movapd %xmm2,%xmm4
cmp    %esi,%edx
jne    1130 <chbevl+0x30>
sub    %esi,%eax
cmp    $0x3,%ecx
jae    116a <chbevl+0x6a>
jmp    11bf <chbevl+0xbf>
xorpd  %xmm2,%xmm2
cmp    $0x3,%ecx
jb     11bf <chbevl+0xbf>
mov    %eax,%eax
xor    %ecx,%ecx
xchg   %ax,%ax
movapd %xmm0,%xmm4
mulsd  %xmm1,%xmm4
subsd  %xmm2,%xmm4
addsd  (%rdi,%rcx,8),%xmm4
movapd %xmm0,%xmm3
mulsd  %xmm4,%xmm3
subsd  %xmm1,%xmm3
addsd  0x8(%rdi,%rcx,8),%xmm3
movapd %xmm0,%xmm2
mulsd  %xmm3,%xmm2
subsd  %xmm4,%xmm2
addsd  0x10(%rdi,%rcx,8),%xmm2
movapd %xmm0,%xmm1
mulsd  %xmm2,%xmm1
subsd  %xmm3,%xmm1
addsd  0x18(%rdi,%rcx,8),%xmm1
add    $0x4,%rcx
cmp    %ecx,%eax
jne    1170 <chbevl+0x70>
subsd  %xmm3,%xmm1
mulsd  0xe35(%rip),%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @chbevl(double %0, i8* %1, i32 %2) {
%4 = alloca double
%5 = alloca i8*
%6 = alloca i32
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double*
%11 = alloca i32
store double %0, double* %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%12 = load i8*, i8** %5
%13 = bitcast i8* %12 to double*
store double* %13, double** %10
%14 = load double*, double** %10
%15 = getelementptr inbounds double, double* %14, i32 1
store double* %15, double** %10
%16 = load double, double* %14
store double %16, double* %7
store double 0.000000e+00, double* %8
%17 = load i32, i32* %6
%18 = sub nsw i32 %17, 1
store i32 %18, i32* %11
br label %19
19: ; preds = %31, %3
%20 = load double, double* %8
store double %20, double* %9
%21 = load double, double* %7
store double %21, double* %8
%22 = load double, double* %4
%23 = load double, double* %8
%24 = load double, double* %9
%25 = fneg double %24
%26 = call double @llvm.fmuladd.f64(double %22, double %23, double %25)
%27 = load double*, double** %10
%28 = getelementptr inbounds double, double* %27, i32 1
store double* %28, double** %10
%29 = load double, double* %27
%30 = fadd double %26, %29
store double %30, double* %7
br label %31
31: ; preds = %19
%32 = load i32, i32* %11
%33 = add nsw i32 %32, -1
store i32 %33, i32* %11
%34 = icmp ne i32 %33, 0
br i1 %34, label %19, label %35
35: ; preds = %31
%36 = load double, double* %7
%37 = load double, double* %9
%38 = fsub double %36, %37
%39 = fmul double 5.000000e-01, %38
ret double %39
}

LLVM IR (-O2):
define double @chbevl(double %0, i8* nocapture %1, i32 %2) {
%4 = bitcast i8* %1 to double*
%5 = getelementptr inbounds i8, i8* %1, i64 8
%6 = bitcast i8* %5 to double*
%7 = load double, double* %4
%8 = add i32 %2, -1
%9 = add i32 %2, -2
%10 = and i32 %8, 3
%11 = icmp eq i32 %10, 0
br i1 %11, label %26, label %12
12: ; preds = %3, %12
%13 = phi double [ %14, %12 ], [ 0.000000e+00, %3 ]
%14 = phi double [ %22, %12 ], [ %7, %3 ]
%15 = phi double* [ %20, %12 ], [ %6, %3 ]
%16 = phi i32 [ %23, %12 ], [ %8, %3 ]
%17 = phi i32 [ %24, %12 ], [ 0, %3 ]
%18 = fneg double %13
%19 = tail call double @llvm.fmuladd.f64(double %0, double %14, double %18)
%20 = getelementptr inbounds double, double* %15, i64 1
%21 = load double, double* %15
%22 = fadd double %19, %21
%23 = add nsw i32 %16, -1
%24 = add i32 %17, 1
%25 = icmp eq i32 %24, %10
br i1 %25, label %26, label %12
26: ; preds = %12, %3
%27 = phi double [ undef, %3 ], [ %13, %12 ]
%28 = phi double [ undef, %3 ], [ %22, %12 ]
%29 = phi double [ 0.000000e+00, %3 ], [ %14, %12 ]
%30 = phi double [ %7, %3 ], [ %22, %12 ]
%31 = phi double* [ %6, %3 ], [ %20, %12 ]
%32 = phi i32 [ %8, %3 ], [ %23, %12 ]
%33 = icmp ult i32 %9, 3
br i1 %33, label %61, label %34
34: ; preds = %26, %34
%35 = phi double [ %53, %34 ], [ %29, %26 ]
%36 = phi double [ %58, %34 ], [ %30, %26 ]
%37 = phi double* [ %56, %34 ], [ %31, %26 ]
%38 = phi i32 [ %59, %34 ], [ %32, %26 ]
%39 = fneg double %35
%40 = tail call double @llvm.fmuladd.f64(double %0, double %36, double %39)
%41 = getelementptr inbounds double, double* %37, i64 1
%42 = load double, double* %37
%43 = fadd double %40, %42
%44 = fneg double %36
%45 = tail call double @llvm.fmuladd.f64(double %0, double %43, double %44)
%46 = getelementptr inbounds double, double* %37, i64 2
%47 = load double, double* %41
%48 = fadd double %45, %47
%49 = fneg double %43
%50 = tail call double @llvm.fmuladd.f64(double %0, double %48, double %49)
%51 = getelementptr inbounds double, double* %37, i64 3
%52 = load double, double* %46
%53 = fadd double %50, %52
%54 = fneg double %48
%55 = tail call double @llvm.fmuladd.f64(double %0, double %53, double %54)
%56 = getelementptr inbounds double, double* %37, i64 4
%57 = load double, double* %51
%58 = fadd double %55, %57
%59 = add nsw i32 %38, -4
%60 = icmp eq i32 %59, 0
br i1 %60, label %61, label %34
61: ; preds = %34, %26
%62 = phi double [ %27, %26 ], [ %48, %34 ]
%63 = phi double [ %28, %26 ], [ %58, %34 ]
%64 = fsub double %63, %62
%65 = fmul double %64, 5.000000e-01
ret double %65
}