double hermite(long n, double x) {
  double h1 = 1.;
  double h2 = 2. * x;
  double xx = 2. * x;
  long i;
  for (i = 1; i < n; i++) {
    xx = 2. * x * h2 - 2. * (i)*h1;
    h1 = h2;
    h2 = xx;
  }
  return xx;
}


x86 assembly (clang, -O0):
<hermite>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  0xef3(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xede(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xecc(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movq   $0x1,-0x30(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x8(%rbp),%rax
jge    11c6 <hermite+0xc6>
movsd  0xea4(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
cvtsi2sdq -0x30(%rbp),%xmm3
movsd  0xe8c(%rip),%xmm1
mulsd  %xmm3,%xmm1
mulsd  -0x18(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1146 <hermite+0x46>
movsd  -0x28(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<hermite>:
addsd  %xmm0,%xmm0
cmp    $0x2,%rdi
jl     1133 <hermite+0x33>
lea    -0x1(%rdi),%rdx
add    $0xfffffffffffffffe,%rdi
mov    %edx,%eax
and    $0x3,%eax
cmp    $0x3,%rdi
jae    1134 <hermite+0x34>
movsd  0xedb(%rip),%xmm2
mov    $0x1,%ecx
movapd %xmm0,%xmm1
jmp    11e9 <hermite+0xe9>
ret
and    $0xfffffffffffffffc,%rdx
movsd  0xec0(%rip),%xmm2
mov    $0x1,%ecx
movsd  0xebb(%rip),%xmm3
movapd %xmm0,%xmm1
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
xorps  %xmm4,%xmm4
cvtsi2sd %rcx,%xmm4
mulsd  %xmm3,%xmm4
mulsd  %xmm2,%xmm4
movapd %xmm0,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm4,%xmm2
lea    0x1(%rcx),%rsi
xorps  %xmm4,%xmm4
cvtsi2sd %rsi,%xmm4
mulsd  %xmm3,%xmm4
mulsd  %xmm1,%xmm4
movapd %xmm0,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm4,%xmm1
lea    0x2(%rcx),%rsi
xorps  %xmm4,%xmm4
cvtsi2sd %rsi,%xmm4
mulsd  %xmm3,%xmm4
mulsd  %xmm2,%xmm4
movapd %xmm0,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm4,%xmm2
lea    0x3(%rcx),%rsi
xorps  %xmm4,%xmm4
cvtsi2sd %rsi,%xmm4
mulsd  %xmm3,%xmm4
mulsd  %xmm1,%xmm4
movapd %xmm0,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm4,%xmm1
add    $0x4,%rcx
cmp    %rdx,%rsi
jne    1160 <hermite+0x60>
test   %rax,%rax
je     122a <hermite+0x12a>
movsd  0xe12(%rip),%xmm3
cs nopw 0x0(%rax,%rax,1)
xorps  %xmm4,%xmm4
cvtsi2sd %rcx,%xmm4
mulsd  %xmm3,%xmm4
mulsd  %xmm2,%xmm4
movapd %xmm1,%xmm2
movapd %xmm0,%xmm1
mulsd  %xmm2,%xmm1
addsd  %xmm4,%xmm1
add    $0x1,%rcx
add    $0xffffffffffffffff,%rax
jne    1200 <hermite+0x100>
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @hermite(i64 %0, double %1) {
%3 = alloca i64
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca i64
store i64 %0, i64* %3
store double %1, double* %4
store double 1.000000e+00, double* %5
%9 = load double, double* %4
%10 = fmul double 2.000000e+00, %9
store double %10, double* %6
%11 = load double, double* %4
%12 = fmul double 2.000000e+00, %11
store double %12, double* %7
store i64 1, i64* %8
br label %13
13: ; preds = %30, %2
%14 = load i64, i64* %8
%15 = load i64, i64* %3
%16 = icmp slt i64 %14, %15
br i1 %16, label %17, label %33
17: ; preds = %13
%18 = load double, double* %4
%19 = fmul double 2.000000e+00, %18
%20 = load double, double* %6
%21 = load i64, i64* %8
%22 = sitofp i64 %21 to double
%23 = fmul double 2.000000e+00, %22
%24 = load double, double* %5
%25 = fmul double %23, %24
%26 = fneg double %25
%27 = call double @llvm.fmuladd.f64(double %19, double %20, double %26)
store double %27, double* %7
%28 = load double, double* %6
store double %28, double* %5
%29 = load double, double* %7
store double %29, double* %6
br label %30
30: ; preds = %17
%31 = load i64, i64* %8
%32 = add nsw i64 %31, 1
store i64 %32, i64* %8
br label %13
33: ; preds = %13
%34 = load double, double* %7
ret double %34
}

LLVM IR (-O2):
define double @hermite(i64 %0, double %1) {
%3 = fmul double %1, 2.000000e+00
%4 = icmp sgt i64 %0, 1
br i1 %4, label %5, label %57
5: ; preds = %2
%6 = add i64 %0, -1
%7 = add i64 %0, -2
%8 = and i64 %6, 3
%9 = icmp ult i64 %7, 3
br i1 %9, label %39, label %10
10: ; preds = %5
%11 = and i64 %6, -4
br label %12
12: ; preds = %12, %10
%13 = phi i64 [ 1, %10 ], [ %36, %12 ]
%14 = phi double [ %3, %10 ], [ %35, %12 ]
%15 = phi double [ 1.000000e+00, %10 ], [ %30, %12 ]
%16 = phi i64 [ 0, %10 ], [ %37, %12 ]
%17 = sitofp i64 %13 to double
%18 = fmul double %17, -2.000000e+00
%19 = fmul double %15, %18
%20 = tail call double @llvm.fmuladd.f64(double %3, double %14, double %19)
%21 = add nuw nsw i64 %13, 1
%22 = sitofp i64 %21 to double
%23 = fmul double %22, -2.000000e+00
%24 = fmul double %14, %23
%25 = tail call double @llvm.fmuladd.f64(double %3, double %20, double %24)
%26 = add nuw nsw i64 %13, 2
%27 = sitofp i64 %26 to double
%28 = fmul double %27, -2.000000e+00
%29 = fmul double %20, %28
%30 = tail call double @llvm.fmuladd.f64(double %3, double %25, double %29)
%31 = add nuw nsw i64 %13, 3
%32 = sitofp i64 %31 to double
%33 = fmul double %32, -2.000000e+00
%34 = fmul double %25, %33
%35 = tail call double @llvm.fmuladd.f64(double %3, double %30, double %34)
%36 = add nuw nsw i64 %13, 4
%37 = add i64 %16, 4
%38 = icmp eq i64 %37, %11
br i1 %38, label %39, label %12
39: ; preds = %12, %5
%40 = phi double [ undef, %5 ], [ %35, %12 ]
%41 = phi i64 [ 1, %5 ], [ %36, %12 ]
%42 = phi double [ %3, %5 ], [ %35, %12 ]
%43 = phi double [ 1.000000e+00, %5 ], [ %30, %12 ]
%44 = icmp eq i64 %8, 0
br i1 %44, label %57, label %45
45: ; preds = %39, %45
%46 = phi i64 [ %54, %45 ], [ %41, %39 ]
%47 = phi double [ %53, %45 ], [ %42, %39 ]
%48 = phi double [ %47, %45 ], [ %43, %39 ]
%49 = phi i64 [ %55, %45 ], [ 0, %39 ]
%50 = sitofp i64 %46 to double
%51 = fmul double %50, -2.000000e+00
%52 = fmul double %48, %51
%53 = tail call double @llvm.fmuladd.f64(double %3, double %47, double %52)
%54 = add nuw nsw i64 %46, 1
%55 = add i64 %49, 1
%56 = icmp eq i64 %55, %8
br i1 %56, label %57, label %45
57: ; preds = %39, %45, %2
%58 = phi double [ %3, %2 ], [ %40, %39 ], [ %53, %45 ]
ret double %58
}