float pclin_mean(float *dx, float *f, int n, float periodic) {
  int i;
  float sum;
  float x;
  float f1, f2;
  float thisdx;
  x = 0.0;
  sum = 0.0;
  f1 = f[0];
  for (i = 1; i < n; i++) {
    f2 = f[i];
    thisdx = dx[i];
    sum += 0.5 * (f1 + f2) * thisdx;
    x += thisdx;
    f1 = f2;
  }
  if (periodic) {
    sum += 0.5 * (f[n - 1] + f[0]) * dx[0];
    x += dx[0];
  }
  return sum / x;
}


x86 assembly (clang, -O0):
<pclin_mean>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movss  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x28(%rbp)
movl   $0x1,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11cc <pclin_mean+0xcc>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x28(%rbp),%xmm0
addss  -0x2c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xe82(%rip),%xmm0
mulsd  %xmm1,%xmm0
movss  -0x30(%rbp),%xmm1
cvtss2sd %xmm1,%xmm2
movss  -0x20(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x30(%rbp),%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1138 <pclin_mean+0x38>
movss  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    11e8 <pclin_mean+0xe8>
jp     11e8 <pclin_mean+0xe8>
jmp    124a <pclin_mean+0x14a>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x10(%rbp),%rax
addss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xdf2(%rip),%xmm0
mulsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm1
cvtss2sd %xmm1,%xmm2
movss  -0x20(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0x20(%rbp),%xmm0
divss  -0x24(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<pclin_mean>:
movss  (%rsi),%xmm9
xorps  %xmm8,%xmm8
xorps  %xmm2,%xmm2
xorps  %xmm11,%xmm11
cmp    $0x2,%edx
jl     1241 <pclin_mean+0x141>
mov    %edx,%r8d
add    $0xffffffffffffffff,%r8
cmp    $0x2,%edx
jne    1143 <pclin_mean+0x43>
xorps  %xmm2,%xmm2
xorps  %xmm6,%xmm6
mov    $0x1,%ecx
movaps %xmm9,%xmm5
test   $0x1,%r8b
jne    120c <pclin_mean+0x10c>
jmp    1241 <pclin_mean+0x141>
mov    %r8,%r9
and    $0xfffffffffffffffe,%r9
neg    %r9
xorps  %xmm11,%xmm11
mov    $0x1,%ecx
movsd  0xea1(%rip),%xmm10
movaps %xmm9,%xmm5
xorps  %xmm2,%xmm2
cs nopw 0x0(%rax,%rax,1)
movss  (%rsi,%rcx,4),%xmm7
addss  %xmm7,%xmm5
xorps  %xmm4,%xmm4
cvtss2sd %xmm5,%xmm4
movss  0x4(%rsi,%rcx,4),%xmm5
mulsd  %xmm10,%xmm4
movss  (%rdi,%rcx,4),%xmm3
movss  0x4(%rdi,%rcx,4),%xmm6
xorps  %xmm1,%xmm1
cvtss2sd %xmm3,%xmm1
mulsd  %xmm4,%xmm1
xorps  %xmm4,%xmm4
cvtss2sd %xmm11,%xmm4
addsd  %xmm1,%xmm4
xorps  %xmm1,%xmm1
cvtsd2ss %xmm4,%xmm1
addss  %xmm3,%xmm2
addss  %xmm5,%xmm7
xorps  %xmm3,%xmm3
cvtss2sd %xmm7,%xmm3
mulsd  %xmm10,%xmm3
xorps  %xmm4,%xmm4
cvtss2sd %xmm6,%xmm4
mulsd  %xmm3,%xmm4
cvtss2sd %xmm1,%xmm1
addsd  %xmm4,%xmm1
xorps  %xmm11,%xmm11
cvtsd2ss %xmm1,%xmm11
addss  %xmm6,%xmm2
lea    (%r9,%rcx,1),%rax
add    $0x2,%rax
add    $0x2,%rcx
cmp    $0x1,%rax
jne    1170 <pclin_mean+0x70>
xorps  %xmm6,%xmm6
cvtss2sd %xmm11,%xmm6
test   $0x1,%r8b
je     1241 <pclin_mean+0x141>
movss  (%rdi,%rcx,4),%xmm1
addss  (%rsi,%rcx,4),%xmm5
xorps  %xmm3,%xmm3
cvtss2sd %xmm5,%xmm3
mulsd  0xddb(%rip),%xmm3
xorps  %xmm4,%xmm4
cvtss2sd %xmm1,%xmm4
mulsd  %xmm3,%xmm4
addsd  %xmm6,%xmm4
xorps  %xmm11,%xmm11
cvtsd2ss %xmm4,%xmm11
addss  %xmm1,%xmm2
ucomiss %xmm8,%xmm0
jne    1249 <pclin_mean+0x149>
jnp    128b <pclin_mean+0x18b>
movslq %edx,%rax
addss  -0x4(%rsi,%rax,4),%xmm9
xorps  %xmm0,%xmm0
cvtss2sd %xmm9,%xmm0
mulsd  0xd9d(%rip),%xmm0
movss  (%rdi),%xmm1
xorps  %xmm3,%xmm3
cvtss2sd %xmm1,%xmm3
mulsd  %xmm0,%xmm3
xorps  %xmm0,%xmm0
cvtss2sd %xmm11,%xmm0
addsd  %xmm3,%xmm0
xorps  %xmm11,%xmm11
cvtsd2ss %xmm0,%xmm11
addss  %xmm1,%xmm2
divss  %xmm2,%xmm11
movaps %xmm11,%xmm0
ret

LLVM IR (-O0):
define float @pclin_mean(float* %0, float* %1, i32 %2, float %3) {
%5 = alloca float*
%6 = alloca float*
%7 = alloca i32
%8 = alloca float
%9 = alloca i32
%10 = alloca float
%11 = alloca float
%12 = alloca float
%13 = alloca float
%14 = alloca float
store float* %0, float** %5
store float* %1, float** %6
store i32 %2, i32* %7
store float %3, float* %8
store float 0.000000e+00, float* %11
store float 0.000000e+00, float* %10
%15 = load float*, float** %6
%16 = getelementptr inbounds float, float* %15, i64 0
%17 = load float, float* %16
store float %17, float* %12
store i32 1, i32* %9
br label %18
18: ; preds = %48, %4
%19 = load i32, i32* %9
%20 = load i32, i32* %7
%21 = icmp slt i32 %19, %20
br i1 %21, label %22, label %51
22: ; preds = %18
%23 = load float*, float** %6
%24 = load i32, i32* %9
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds float, float* %23, i64 %25
%27 = load float, float* %26
store float %27, float* %13
%28 = load float*, float** %5
%29 = load i32, i32* %9
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds float, float* %28, i64 %30
%32 = load float, float* %31
store float %32, float* %14
%33 = load float, float* %12
%34 = load float, float* %13
%35 = fadd float %33, %34
%36 = fpext float %35 to double
%37 = fmul double 5.000000e-01, %36
%38 = load float, float* %14
%39 = fpext float %38 to double
%40 = load float, float* %10
%41 = fpext float %40 to double
%42 = call double @llvm.fmuladd.f64(double %37, double %39, double %41)
%43 = fptrunc double %42 to float
store float %43, float* %10
%44 = load float, float* %14
%45 = load float, float* %11
%46 = fadd float %45, %44
store float %46, float* %11
%47 = load float, float* %13
store float %47, float* %12
br label %48
48: ; preds = %22
%49 = load i32, i32* %9
%50 = add nsw i32 %49, 1
store i32 %50, i32* %9
br label %18
51: ; preds = %18
%52 = load float, float* %8
%53 = fcmp une float %52, 0.000000e+00
br i1 %53, label %54, label %80
54: ; preds = %51
%55 = load float*, float** %6
%56 = load i32, i32* %7
%57 = sub nsw i32 %56, 1
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds float, float* %55, i64 %58
%60 = load float, float* %59
%61 = load float*, float** %6
%62 = getelementptr inbounds float, float* %61, i64 0
%63 = load float, float* %62
%64 = fadd float %60, %63
%65 = fpext float %64 to double
%66 = fmul double 5.000000e-01, %65
%67 = load float*, float** %5
%68 = getelementptr inbounds float, float* %67, i64 0
%69 = load float, float* %68
%70 = fpext float %69 to double
%71 = load float, float* %10
%72 = fpext float %71 to double
%73 = call double @llvm.fmuladd.f64(double %66, double %70, double %72)
%74 = fptrunc double %73 to float
store float %74, float* %10
%75 = load float*, float** %5
%76 = getelementptr inbounds float, float* %75, i64 0
%77 = load float, float* %76
%78 = load float, float* %11
%79 = fadd float %78, %77
store float %79, float* %11
br label %80
80: ; preds = %54, %51
%81 = load float, float* %10
%82 = load float, float* %11
%83 = fdiv float %81, %82
ret float %83
}

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