double zero_mean(float *f, int npts, char *format) {
  int i, n;
  double u;
  for (u = n = i = 0; i < npts; i++)
    if (format[i] != 'x') {
      n++;
      u += f[i];
    }
  u /= n;
  for (i = 0; i < npts; i++)
    f[i] -= u;
  return u;
}


x86 assembly (clang, -O0):
<zero_mean>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    117d <zero_mean+0x7d>
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x78,%eax
je     116a <zero_mean+0x6a>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    116f <zero_mean+0x6f>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1125 <zero_mean+0x25>
cvtsi2sdl -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    11d4 <zero_mean+0xd4>
movsd  -0x28(%rbp),%xmm1
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
subsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1197 <zero_mean+0x97>
movsd  -0x28(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<zero_mean>:
test   %esi,%esi
jle    114f <zero_mean+0x4f>
mov    %esi,%r8d
cmp    $0x1,%esi
jne    1158 <zero_mean+0x58>
xor    %eax,%eax
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
test   $0x1,%r8b
je     1130 <zero_mean+0x30>
cmpb   $0x78,(%rdx,%rax,1)
je     1130 <zero_mean+0x30>
add    $0x1,%ecx
movss  (%rdi,%rax,4),%xmm1
cvtss2sd %xmm1,%xmm1
addsd  %xmm1,%xmm0
xorps  %xmm1,%xmm1
cvtsi2sd %ecx,%xmm1
divsd  %xmm1,%xmm0
test   %esi,%esi
jle    12ef <zero_mean+0x1ef>
cmp    $0x8,%esi
jae    11a9 <zero_mean+0xa9>
xor    %ecx,%ecx
jmp    12d0 <zero_mean+0x1d0>
movsd  0xea9(%rip),%xmm0
ret
mov    %r8d,%r9d
and    $0xfffffffe,%r9d
xor    %eax,%eax
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
jmp    1179 <zero_mean+0x79>
nopl   0x0(%rax)
add    $0x2,%rax
cmp    %rax,%r9
je     1114 <zero_mean+0x14>
cmpb   $0x78,(%rdx,%rax,1)
je     118f <zero_mean+0x8f>
add    $0x1,%ecx
movss  (%rdi,%rax,4),%xmm1
cvtss2sd %xmm1,%xmm1
addsd  %xmm1,%xmm0
cmpb   $0x78,0x1(%rdx,%rax,1)
je     1170 <zero_mean+0x70>
add    $0x1,%ecx
movss  0x4(%rdi,%rax,4),%xmm1
cvtss2sd %xmm1,%xmm1
addsd  %xmm1,%xmm0
jmp    1170 <zero_mean+0x70>
mov    %r8d,%ecx
and    $0xfffffff8,%ecx
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
lea    -0x8(%rcx),%rdx
mov    %rdx,%rax
shr    $0x3,%rax
add    $0x1,%rax
test   %rdx,%rdx
je     12f0 <zero_mean+0x1f0>
mov    %rax,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
cvtps2pd 0x8(%rdi,%rdx,4),%xmm2
cvtps2pd (%rdi,%rdx,4),%xmm3
cvtps2pd 0x18(%rdi,%rdx,4),%xmm4
cvtps2pd 0x10(%rdi,%rdx,4),%xmm5
subpd  %xmm1,%xmm3
subpd  %xmm1,%xmm2
subpd  %xmm1,%xmm5
subpd  %xmm1,%xmm4
cvtpd2ps %xmm2,%xmm2
cvtpd2ps %xmm3,%xmm3
cvtpd2ps %xmm4,%xmm4
unpcklpd %xmm2,%xmm3
cvtpd2ps %xmm5,%xmm2
unpcklpd %xmm4,%xmm2
movupd %xmm3,(%rdi,%rdx,4)
movupd %xmm2,0x10(%rdi,%rdx,4)
cvtps2pd 0x28(%rdi,%rdx,4),%xmm2
cvtps2pd 0x20(%rdi,%rdx,4),%xmm3
cvtps2pd 0x38(%rdi,%rdx,4),%xmm4
cvtps2pd 0x30(%rdi,%rdx,4),%xmm5
subpd  %xmm1,%xmm3
subpd  %xmm1,%xmm2
subpd  %xmm1,%xmm5
subpd  %xmm1,%xmm4
cvtpd2ps %xmm2,%xmm2
cvtpd2ps %xmm3,%xmm3
cvtpd2ps %xmm4,%xmm4
unpcklpd %xmm2,%xmm3
cvtpd2ps %xmm5,%xmm2
unpcklpd %xmm4,%xmm2
movupd %xmm3,0x20(%rdi,%rdx,4)
movupd %xmm2,0x30(%rdi,%rdx,4)
add    $0x10,%rdx
add    $0xfffffffffffffffe,%rsi
jne    11e0 <zero_mean+0xe0>
test   $0x1,%al
je     12c6 <zero_mean+0x1c6>
cvtps2pd 0x8(%rdi,%rdx,4),%xmm2
cvtps2pd (%rdi,%rdx,4),%xmm3
cvtps2pd 0x18(%rdi,%rdx,4),%xmm4
cvtps2pd 0x10(%rdi,%rdx,4),%xmm5
subpd  %xmm1,%xmm3
subpd  %xmm1,%xmm2
subpd  %xmm1,%xmm5
subpd  %xmm1,%xmm4
cvtpd2ps %xmm2,%xmm1
cvtpd2ps %xmm3,%xmm2
cvtpd2ps %xmm4,%xmm3
cvtpd2ps %xmm5,%xmm4
unpcklpd %xmm1,%xmm2
unpcklpd %xmm3,%xmm4
movupd %xmm2,(%rdi,%rdx,4)
movupd %xmm4,0x10(%rdi,%rdx,4)
cmp    %r8,%rcx
je     12ef <zero_mean+0x1ef>
nopl   0x0(%rax,%rax,1)
movss  (%rdi,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm1
subsd  %xmm0,%xmm1
cvtsd2ss %xmm1,%xmm1
movss  %xmm1,(%rdi,%rcx,4)
add    $0x1,%rcx
cmp    %rcx,%r8
jne    12d0 <zero_mean+0x1d0>
ret
xor    %edx,%edx
test   $0x1,%al
jne    1280 <zero_mean+0x180>
jmp    12c6 <zero_mean+0x1c6>

LLVM IR (-O0):
define double @zero_mean(float* %0, i32 %1, i8* %2) {
%4 = alloca float*
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca double
store float* %0, float** %4
store i32 %1, i32* %5
store i8* %2, i8** %6
store i32 0, i32* %7
store i32 0, i32* %8
store double 0.000000e+00, double* %9
br label %10
10: ; preds = %34, %3
%11 = load i32, i32* %7
%12 = load i32, i32* %5
%13 = icmp slt i32 %11, %12
br i1 %13, label %14, label %37
14: ; preds = %10
%15 = load i8*, i8** %6
%16 = load i32, i32* %7
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %15, i64 %17
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = icmp ne i32 %20, 120
br i1 %21, label %22, label %33
22: ; preds = %14
%23 = load i32, i32* %8
%24 = add nsw i32 %23, 1
store i32 %24, i32* %8
%25 = load float*, float** %4
%26 = load i32, i32* %7
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds float, float* %25, i64 %27
%29 = load float, float* %28
%30 = fpext float %29 to double
%31 = load double, double* %9
%32 = fadd double %31, %30
store double %32, double* %9
br label %33
33: ; preds = %22, %14
br label %34
34: ; preds = %33
%35 = load i32, i32* %7
%36 = add nsw i32 %35, 1
store i32 %36, i32* %7
br label %10
37: ; preds = %10
%38 = load i32, i32* %8
%39 = sitofp i32 %38 to double
%40 = load double, double* %9
%41 = fdiv double %40, %39
store double %41, double* %9
store i32 0, i32* %7
br label %42
42: ; preds = %56, %37
%43 = load i32, i32* %7
%44 = load i32, i32* %5
%45 = icmp slt i32 %43, %44
br i1 %45, label %46, label %59
46: ; preds = %42
%47 = load double, double* %9
%48 = load float*, float** %4
%49 = load i32, i32* %7
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds float, float* %48, i64 %50
%52 = load float, float* %51
%53 = fpext float %52 to double
%54 = fsub double %53, %47
%55 = fptrunc double %54 to float
store float %55, float* %51
br label %56
56: ; preds = %46
%57 = load i32, i32* %7
%58 = add nsw i32 %57, 1
store i32 %58, i32* %7
br label %42
59: ; preds = %42
%60 = load double, double* %9
ret double %60
}

LLVM IR (-O2):
define double @zero_mean(float* nocapture %0, i32 %1, i8* nocapture %2) {
%4 = icmp sgt i32 %1, 0
br i1 %4, label %5, label %148
5: ; preds = %3
%6 = zext i32 %1 to i64
%7 = and i64 %6, 1
%8 = icmp eq i32 %1, 1
br i1 %8, label %44, label %9
9: ; preds = %5
%10 = and i64 %6, 4294967294
br label %11
11: ; preds = %38, %9
%12 = phi i64 [ 0, %9 ], [ %41, %38 ]
%13 = phi double [ 0.000000e+00, %9 ], [ %40, %38 ]
%14 = phi i32 [ 0, %9 ], [ %39, %38 ]
%15 = phi i64 [ 0, %9 ], [ %42, %38 ]
%16 = getelementptr inbounds i8, i8* %2, i64 %12
%17 = load i8, i8* %16
%18 = icmp eq i8 %17, 120
br i1 %18, label %25, label %19
19: ; preds = %11
%20 = add nsw i32 %14, 1
%21 = getelementptr inbounds float, float* %0, i64 %12
%22 = load float, float* %21
%23 = fpext float %22 to double
%24 = fadd double %13, %23
br label %25
25: ; preds = %11, %19
%26 = phi i32 [ %20, %19 ], [ %14, %11 ]
%27 = phi double [ %24, %19 ], [ %13, %11 ]
%28 = or i64 %12, 1
%29 = getelementptr inbounds i8, i8* %2, i64 %28
%30 = load i8, i8* %29
%31 = icmp eq i8 %30, 120
br i1 %31, label %38, label %32
32: ; preds = %25
%33 = add nsw i32 %26, 1
%34 = getelementptr inbounds float, float* %0, i64 %28
%35 = load float, float* %34
%36 = fpext float %35 to double
%37 = fadd double %27, %36
br label %38
38: ; preds = %32, %25
%39 = phi i32 [ %33, %32 ], [ %26, %25 ]
%40 = phi double [ %37, %32 ], [ %27, %25 ]
%41 = add nuw nsw i64 %12, 2
%42 = add i64 %15, 2
%43 = icmp eq i64 %42, %10
br i1 %43, label %44, label %11
44: ; preds = %38, %5
%45 = phi i32 [ undef, %5 ], [ %39, %38 ]
%46 = phi double [ undef, %5 ], [ %40, %38 ]
%47 = phi i64 [ 0, %5 ], [ %41, %38 ]
%48 = phi double [ 0.000000e+00, %5 ], [ %40, %38 ]
%49 = phi i32 [ 0, %5 ], [ %39, %38 ]
%50 = icmp eq i64 %7, 0
br i1 %50, label %61, label %51
51: ; preds = %44
%52 = getelementptr inbounds i8, i8* %2, i64 %47
%53 = load i8, i8* %52
%54 = icmp eq i8 %53, 120
br i1 %54, label %61, label %55
55: ; preds = %51
%56 = add nsw i32 %49, 1
%57 = getelementptr inbounds float, float* %0, i64 %47
%58 = load float, float* %57
%59 = fpext float %58 to double
%60 = fadd double %48, %59
br label %61
61: ; preds = %51, %55, %44
%62 = phi i32 [ %45, %44 ], [ %56, %55 ], [ %49, %51 ]
%63 = phi double [ %46, %44 ], [ %60, %55 ], [ %48, %51 ]
%64 = sitofp i32 %62 to double
%65 = fdiv double %63, %64
br i1 %4, label %66, label %148
66: ; preds = %61
%67 = zext i32 %1 to i64
%68 = icmp ult i32 %1, 8
br i1 %68, label %137, label %69
69: ; preds = %66
%70 = and i64 %6, 4294967288
%71 = insertelement <4 x double> poison, double %65, i64 0
%72 = shufflevector <4 x double> %71, <4 x double> poison, <4 x i32> zeroinitializer
%73 = insertelement <4 x double> poison, double %65, i64 0
%74 = shufflevector <4 x double> %73, <4 x double> poison, <4 x i32> zeroinitializer
%75 = add nsw i64 %70, -8
%76 = lshr exact i64 %75, 3
%77 = add nuw nsw i64 %76, 1
%78 = and i64 %77, 1
%79 = icmp eq i64 %75, 0
br i1 %79, label %117, label %80
80: ; preds = %69
%81 = and i64 %77, 4611686018427387902
br label %82
82: ; preds = %82, %80
%83 = phi i64 [ 0, %80 ], [ %114, %82 ]
%84 = phi i64 [ 0, %80 ], [ %115, %82 ]
%85 = getelementptr inbounds float, float* %0, i64 %83
%86 = bitcast float* %85 to <4 x float>*
%87 = load <4 x float>, <4 x float>* %86
%88 = getelementptr inbounds float, float* %85, i64 4
%89 = bitcast float* %88 to <4 x float>*
%90 = load <4 x float>, <4 x float>* %89
%91 = fpext <4 x float> %87 to <4 x double>
%92 = fpext <4 x float> %90 to <4 x double>
%93 = fsub <4 x double> %91, %72
%94 = fsub <4 x double> %92, %74
%95 = fptrunc <4 x double> %93 to <4 x float>
%96 = fptrunc <4 x double> %94 to <4 x float>
%97 = bitcast float* %85 to <4 x float>*
store <4 x float> %95, <4 x float>* %97
%98 = bitcast float* %88 to <4 x float>*
store <4 x float> %96, <4 x float>* %98
%99 = or i64 %83, 8
%100 = getelementptr inbounds float, float* %0, i64 %99
%101 = bitcast float* %100 to <4 x float>*
%102 = load <4 x float>, <4 x float>* %101
%103 = getelementptr inbounds float, float* %100, i64 4
%104 = bitcast float* %103 to <4 x float>*
%105 = load <4 x float>, <4 x float>* %104
%106 = fpext <4 x float> %102 to <4 x double>
%107 = fpext <4 x float> %105 to <4 x double>
%108 = fsub <4 x double> %106, %72
%109 = fsub <4 x double> %107, %74
%110 = fptrunc <4 x double> %108 to <4 x float>
%111 = fptrunc <4 x double> %109 to <4 x float>
%112 = bitcast float* %100 to <4 x float>*
store <4 x float> %110, <4 x float>* %112
%113 = bitcast float* %103 to <4 x float>*
store <4 x float> %111, <4 x float>* %113
%114 = add nuw i64 %83, 16
%115 = add i64 %84, 2
%116 = icmp eq i64 %115, %81
br i1 %116, label %117, label %82
117: ; preds = %82, %69
%118 = phi i64 [ 0, %69 ], [ %114, %82 ]
%119 = icmp eq i64 %78, 0
br i1 %119, label %135, label %120
120: ; preds = %117
%121 = getelementptr inbounds float, float* %0, i64 %118
%122 = bitcast float* %121 to <4 x float>*
%123 = load <4 x float>, <4 x float>* %122
%124 = getelementptr inbounds float, float* %121, i64 4
%125 = bitcast float* %124 to <4 x float>*
%126 = load <4 x float>, <4 x float>* %125
%127 = fpext <4 x float> %123 to <4 x double>
%128 = fpext <4 x float> %126 to <4 x double>
%129 = fsub <4 x double> %127, %72
%130 = fsub <4 x double> %128, %74
%131 = fptrunc <4 x double> %129 to <4 x float>
%132 = fptrunc <4 x double> %130 to <4 x float>
%133 = bitcast float* %121 to <4 x float>*
store <4 x float> %131, <4 x float>* %133
%134 = bitcast float* %124 to <4 x float>*
store <4 x float> %132, <4 x float>* %134
br label %135
135: ; preds = %117, %120
%136 = icmp eq i64 %70, %6
br i1 %136, label %148, label %137
137: ; preds = %66, %135
%138 = phi i64 [ 0, %66 ], [ %70, %135 ]
br label %139
139: ; preds = %137, %139
%140 = phi i64 [ %146, %139 ], [ %138, %137 ]
%141 = getelementptr inbounds float, float* %0, i64 %140
%142 = load float, float* %141
%143 = fpext float %142 to double
%144 = fsub double %143, %65
%145 = fptrunc double %144 to float
store float %145, float* %141
%146 = add nuw nsw i64 %140, 1
%147 = icmp eq i64 %146, %67
br i1 %147, label %148, label %139
148: ; preds = %139, %135, %3, %61
%149 = phi double [ %65, %61 ], [ 0x7FF8000000000000, %3 ], [ %65, %135 ], [ %65, %139 ]
ret double %149
}