float i0f(float x) {
  float sum = 1.0, val = 1.0, c = 0.0;
  for (int n = 1; n < 20; n++) {
    float tmp = x / (2 * n);
    val *= tmp * tmp;
    float y = val - c;
    float t = sum + y;
    c = (t - sum) - y;
    sum = t;
  }
  return sum;
}


x86 assembly (clang, -O0):
<i0f>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x4(%rbp)
movss  0xeef(%rip),%xmm0
movss  %xmm0,-0x8(%rbp)
movss  0xee2(%rip),%xmm0
movss  %xmm0,-0xc(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x10(%rbp)
movl   $0x1,-0x14(%rbp)
cmpl   $0x14,-0x14(%rbp)
jge    11b2 <i0f+0xb2>
movss  -0x4(%rbp),%xmm0
mov    -0x14(%rbp),%eax
shl    $0x1,%eax
cvtsi2ss %eax,%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
mulss  -0x18(%rbp),%xmm0
mulss  -0xc(%rbp),%xmm0
movss  %xmm0,-0xc(%rbp)
movss  -0xc(%rbp),%xmm0
subss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0x8(%rbp),%xmm0
addss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm0
subss  -0x8(%rbp),%xmm0
subss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x10(%rbp)
movss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x8(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1132 <i0f+0x32>
movss  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<i0f>:
xorps  %xmm4,%xmm4
movss  0xef5(%rip),%xmm2
mov    $0x4,%eax
movaps %xmm2,%xmm1
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
lea    -0x2(%rax),%ecx
xorps  %xmm5,%xmm5
cvtsi2ss %ecx,%xmm5
movaps %xmm0,%xmm3
divss  %xmm5,%xmm3
mulss  %xmm3,%xmm3
mulss  %xmm1,%xmm3
movaps %xmm3,%xmm5
subss  %xmm4,%xmm5
movaps %xmm2,%xmm1
addss  %xmm5,%xmm1
cmp    $0x28,%eax
je     118e <i0f+0x8e>
movaps %xmm1,%xmm4
subss  %xmm2,%xmm4
subss  %xmm5,%xmm4
xorps  %xmm2,%xmm2
cvtsi2ss %eax,%xmm2
movaps %xmm0,%xmm5
divss  %xmm2,%xmm5
mulss  %xmm5,%xmm5
mulss  %xmm5,%xmm3
movaps %xmm3,%xmm5
subss  %xmm4,%xmm5
movaps %xmm1,%xmm2
addss  %xmm5,%xmm2
movaps %xmm2,%xmm4
subss  %xmm1,%xmm4
subss  %xmm5,%xmm4
add    $0x4,%eax
movaps %xmm3,%xmm1
jmp    1120 <i0f+0x20>
movaps %xmm1,%xmm0
ret

LLVM IR (-O0):
define float @i0f(float %0) {
%2 = alloca float
%3 = alloca float
%4 = alloca float
%5 = alloca float
%6 = alloca i32
%7 = alloca float
%8 = alloca float
%9 = alloca float
store float %0, float* %2
store float 1.000000e+00, float* %3
store float 1.000000e+00, float* %4
store float 0.000000e+00, float* %5
store i32 1, i32* %6
br label %10
10: ; preds = %36, %1
%11 = load i32, i32* %6
%12 = icmp slt i32 %11, 20
br i1 %12, label %13, label %39
13: ; preds = %10
%14 = load float, float* %2
%15 = load i32, i32* %6
%16 = mul nsw i32 2, %15
%17 = sitofp i32 %16 to float
%18 = fdiv float %14, %17
store float %18, float* %7
%19 = load float, float* %7
%20 = load float, float* %7
%21 = fmul float %19, %20
%22 = load float, float* %4
%23 = fmul float %22, %21
store float %23, float* %4
%24 = load float, float* %4
%25 = load float, float* %5
%26 = fsub float %24, %25
store float %26, float* %8
%27 = load float, float* %3
%28 = load float, float* %8
%29 = fadd float %27, %28
store float %29, float* %9
%30 = load float, float* %9
%31 = load float, float* %3
%32 = fsub float %30, %31
%33 = load float, float* %8
%34 = fsub float %32, %33
store float %34, float* %5
%35 = load float, float* %9
store float %35, float* %3
br label %36
36: ; preds = %13
%37 = load i32, i32* %6
%38 = add nsw i32 %37, 1
store i32 %38, i32* %6
br label %10
39: ; preds = %10
%40 = load float, float* %3
ret float %40
}

LLVM IR (-O2):
define float @i0f(float %0) {
br label %3
2: ; preds = %3
ret float %14
3: ; preds = %17, %1
%4 = phi float [ 1.000000e+00, %1 ], [ %26, %17 ]
%5 = phi float [ 1.000000e+00, %1 ], [ %24, %17 ]
%6 = phi float [ 0.000000e+00, %1 ], [ %28, %17 ]
%7 = phi i32 [ 1, %1 ], [ %29, %17 ]
%8 = shl nuw nsw i32 %7, 1
%9 = sitofp i32 %8 to float
%10 = fdiv float %0, %9
%11 = fmul float %10, %10
%12 = fmul float %5, %11
%13 = fsub float %12, %6
%14 = fadd float %4, %13
%15 = add nuw nsw i32 %7, 1
%16 = icmp eq i32 %15, 20
br i1 %16, label %2, label %17
17: ; preds = %3
%18 = fsub float %14, %4
%19 = fsub float %18, %13
%20 = shl nuw nsw i32 %15, 1
%21 = sitofp i32 %20 to float
%22 = fdiv float %0, %21
%23 = fmul float %22, %22
%24 = fmul float %12, %23
%25 = fsub float %24, %19
%26 = fadd float %14, %25
%27 = fsub float %26, %14
%28 = fsub float %27, %25
%29 = add nuw nsw i32 %7, 2
br label %3
}