float fredin(float x, int n, float a, float b, float t[], float f[], float w[],
             float (*g)(float), float (*ak)(float, float)) {
  int i;
  float sum = 0.0;
  for (i = 1; i <= n; i++)
    sum += (*ak)(x, t[i]) * w[i] * f[i];
  return (*g)(x) + sum;
}


x86 assembly (clang, -O0):
<fredin>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movss  %xmm0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  %xmm2,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x40(%rbp)
movl   $0x1,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x8(%rbp),%eax
jg     119b <fredin+0x9b>
mov    -0x38(%rbp),%rax
movss  -0x4(%rbp),%xmm0
mov    -0x18(%rbp),%rcx
movslq -0x3c(%rbp),%rdx
movss  (%rcx,%rdx,4),%xmm1
call   *%rax
mov    -0x28(%rbp),%rax
movslq -0x3c(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x3c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm2
movss  -0x40(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    113d <fredin+0x3d>
mov    -0x30(%rbp),%rax
movss  -0x4(%rbp),%xmm0
call   *%rax
addss  -0x40(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fredin>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %r8,0x10(%rsp)
test   %edi,%edi
jle    117d <fredin+0x7d>
mov    %r9,%r15
mov    %rcx,%r12
mov    %rdx,%r13
mov    %rsi,%rbx
mov    %edi,%ebp
add    $0x1,%ebp
xorps  %xmm1,%xmm1
movss  %xmm1,0x8(%rsp)
mov    $0x1,%r14d
movss  %xmm0,0xc(%rsp)
nopl   (%rax)
movss  (%rbx,%r14,4),%xmm1
movss  0xc(%rsp),%xmm0
call   *%r15
mulss  (%r12,%r14,4),%xmm0
mulss  0x0(%r13,%r14,4),%xmm0
movss  0x8(%rsp),%xmm1
addss  %xmm0,%xmm1
movss  %xmm1,0x8(%rsp)
movss  0xc(%rsp),%xmm0
add    $0x1,%r14
cmp    %r14,%rbp
jne    1140 <fredin+0x40>
jmp    1186 <fredin+0x86>
xorps  %xmm1,%xmm1
movss  %xmm1,0x8(%rsp)
call   *0x10(%rsp)
addss  0x8(%rsp),%xmm0
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define float @fredin(float %0, i32 %1, float %2, float %3, float* %4, float* %5, float* %6, float (float)* %7, float (float, float)* %8) {
%10 = alloca float
%11 = alloca i32
%12 = alloca float
%13 = alloca float
%14 = alloca float*
%15 = alloca float*
%16 = alloca float*
%17 = alloca float (float)*
%18 = alloca float (float, float)*
%19 = alloca i32
%20 = alloca float
store float %0, float* %10
store i32 %1, i32* %11
store float %2, float* %12
store float %3, float* %13
store float* %4, float** %14
store float* %5, float** %15
store float* %6, float** %16
store float (float)* %7, float (float)** %17
store float (float, float)* %8, float (float, float)** %18
store float 0.000000e+00, float* %20
store i32 1, i32* %19
br label %21
21: ; preds = %47, %9
%22 = load i32, i32* %19
%23 = load i32, i32* %11
%24 = icmp sle i32 %22, %23
br i1 %24, label %25, label %50
25: ; preds = %21
%26 = load float (float, float)*, float (float, float)** %18
%27 = load float, float* %10
%28 = load float*, float** %14
%29 = load i32, i32* %19
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds float, float* %28, i64 %30
%32 = load float, float* %31
%33 = call float %26(float %27, float %32)
%34 = load float*, float** %16
%35 = load i32, i32* %19
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds float, float* %34, i64 %36
%38 = load float, float* %37
%39 = fmul float %33, %38
%40 = load float*, float** %15
%41 = load i32, i32* %19
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds float, float* %40, i64 %42
%44 = load float, float* %43
%45 = load float, float* %20
%46 = call float @llvm.fmuladd.f32(float %39, float %44, float %45)
store float %46, float* %20
br label %47
47: ; preds = %25
%48 = load i32, i32* %19
%49 = add nsw i32 %48, 1
store i32 %49, i32* %19
br label %21
50: ; preds = %21
%51 = load float (float)*, float (float)** %17
%52 = load float, float* %10
%53 = call float %51(float %52)
%54 = load float, float* %20
%55 = fadd float %53, %54
ret float %55
}

LLVM IR (-O2):
define float @fredin(float %0, i32 %1, float %2, float %3, float* nocapture %4, float* nocapture %5, float* nocapture %6, float (float)* nocapture %7, float (float, float)* nocapture %8) {
%10 = icmp slt i32 %1, 1
br i1 %10, label %28, label %11
11: ; preds = %9
%12 = add nuw i32 %1, 1
%13 = zext i32 %12 to i64
br label %14
14: ; preds = %11, %14
%15 = phi i64 [ 1, %11 ], [ %26, %14 ]
%16 = phi float [ 0.000000e+00, %11 ], [ %25, %14 ]
%17 = getelementptr inbounds float, float* %4, i64 %15
%18 = load float, float* %17
%19 = tail call float %8(float %0, float %18)
%20 = getelementptr inbounds float, float* %6, i64 %15
%21 = load float, float* %20
%22 = fmul float %19, %21
%23 = getelementptr inbounds float, float* %5, i64 %15
%24 = load float, float* %23
%25 = tail call float @llvm.fmuladd.f32(float %22, float %24, float %16)
%26 = add nuw nsw i64 %15, 1
%27 = icmp eq i64 %26, %13
br i1 %27, label %28, label %14
28: ; preds = %14, %9
%29 = phi float [ 0.000000e+00, %9 ], [ %25, %14 ]
%30 = tail call float %7(float %0)
%31 = fadd float %29, %30
ret float %31
}