#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ assert(float const *);
float vectorf_mean(float const *, size_t);
void vectorf_remove_mean(const float *self, size_t size, float *output) {
  assert(self);
  assert(output);
  float mean = vectorf_mean(self, size);
  for (size_t i = 0; i < size; i++)
    output[i] = self[i] - mean;
}


x86 assembly (clang, -O0):
<vectorf_remove_mean>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <assert@plt>
mov    -0x18(%rbp),%rdi
call   1030 <assert@plt>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1040 <vectorf_mean@plt>
movss  %xmm0,-0x1c(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    119e <vectorf_remove_mean+0x7e>
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
subss  -0x1c(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1160 <vectorf_remove_mean+0x40>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vectorf_remove_mean>:
push   %r15
push   %r14
push   %rbx
mov    %rdx,%r15
mov    %rsi,%r14
mov    %rdi,%rbx
call   1030 <assert@plt>
mov    %r15,%rdi
call   1030 <assert@plt>
mov    %rbx,%rdi
mov    %r14,%rsi
call   1040 <vectorf_mean@plt>
test   %r14,%r14
je     12a8 <vectorf_remove_mean+0x188>
cmp    $0x8,%r14
jb     116f <vectorf_remove_mean+0x4f>
lea    (%rbx,%r14,4),%rax
cmp    %r15,%rax
jbe    1210 <vectorf_remove_mean+0xf0>
lea    (%r15,%r14,4),%rax
cmp    %rbx,%rax
jbe    1210 <vectorf_remove_mean+0xf0>
xor    %eax,%eax
mov    %rax,%rcx
not    %rcx
add    %r14,%rcx
mov    %r14,%rdx
and    $0x3,%rdx
je     11a9 <vectorf_remove_mean+0x89>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movss  (%rbx,%rax,4),%xmm1
subss  %xmm0,%xmm1
movss  %xmm1,(%r15,%rax,4)
add    $0x1,%rax
add    $0xffffffffffffffff,%rdx
jne    1190 <vectorf_remove_mean+0x70>
cmp    $0x3,%rcx
jb     12a8 <vectorf_remove_mean+0x188>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movss  (%rbx,%rax,4),%xmm1
subss  %xmm0,%xmm1
movss  %xmm1,(%r15,%rax,4)
movss  0x4(%rbx,%rax,4),%xmm1
subss  %xmm0,%xmm1
movss  %xmm1,0x4(%r15,%rax,4)
movss  0x8(%rbx,%rax,4),%xmm1
subss  %xmm0,%xmm1
movss  %xmm1,0x8(%r15,%rax,4)
movss  0xc(%rbx,%rax,4),%xmm1
subss  %xmm0,%xmm1
movss  %xmm1,0xc(%r15,%rax,4)
add    $0x4,%rax
cmp    %rax,%r14
jne    11c0 <vectorf_remove_mean+0xa0>
jmp    12a8 <vectorf_remove_mean+0x188>
mov    %r14,%rax
and    $0xfffffffffffffff8,%rax
movaps %xmm0,%xmm1
shufps $0x0,%xmm0,%xmm1
lea    -0x8(%rax),%rcx
mov    %rcx,%rdx
shr    $0x3,%rdx
add    $0x1,%rdx
test   %rcx,%rcx
je     12ae <vectorf_remove_mean+0x18e>
mov    %rdx,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
movups (%rbx,%rcx,4),%xmm2
movups 0x10(%rbx,%rcx,4),%xmm3
subps  %xmm1,%xmm2
subps  %xmm1,%xmm3
movups %xmm2,(%r15,%rcx,4)
movups %xmm3,0x10(%r15,%rcx,4)
movups 0x20(%rbx,%rcx,4),%xmm2
movups 0x30(%rbx,%rcx,4),%xmm3
subps  %xmm1,%xmm2
subps  %xmm1,%xmm3
movups %xmm2,0x20(%r15,%rcx,4)
movups %xmm3,0x30(%r15,%rcx,4)
add    $0x10,%rcx
add    $0xfffffffffffffffe,%rsi
jne    1240 <vectorf_remove_mean+0x120>
test   $0x1,%dl
je     129f <vectorf_remove_mean+0x17f>
movups (%rbx,%rcx,4),%xmm2
movups 0x10(%rbx,%rcx,4),%xmm3
subps  %xmm1,%xmm2
subps  %xmm1,%xmm3
movups %xmm2,(%r15,%rcx,4)
movups %xmm3,0x10(%r15,%rcx,4)
cmp    %r14,%rax
jne    1171 <vectorf_remove_mean+0x51>
pop    %rbx
pop    %r14
pop    %r15
ret
xor    %ecx,%ecx
test   $0x1,%dl
jne    1285 <vectorf_remove_mean+0x165>
jmp    129f <vectorf_remove_mean+0x17f>

LLVM IR (-O0):
define void @vectorf_remove_mean(float* %0, i64 %1, float* %2) {
%4 = alloca float*
%5 = alloca i64
%6 = alloca float*
%7 = alloca float
%8 = alloca i64
store float* %0, float** %4
store i64 %1, i64* %5
store float* %2, float** %6
%9 = load float*, float** %4
%10 = call i32 @assert(float* %9)
%11 = load float*, float** %6
%12 = call i32 @assert(float* %11)
%13 = load float*, float** %4
%14 = load i64, i64* %5
%15 = call float @vectorf_mean(float* %13, i64 %14)
store float %15, float* %7
store i64 0, i64* %8
br label %16
16: ; preds = %30, %3
%17 = load i64, i64* %8
%18 = load i64, i64* %5
%19 = icmp ult i64 %17, %18
br i1 %19, label %20, label %33
20: ; preds = %16
%21 = load float*, float** %4
%22 = load i64, i64* %8
%23 = getelementptr inbounds float, float* %21, i64 %22
%24 = load float, float* %23
%25 = load float, float* %7
%26 = fsub float %24, %25
%27 = load float*, float** %6
%28 = load i64, i64* %8
%29 = getelementptr inbounds float, float* %27, i64 %28
store float %26, float* %29
br label %30
30: ; preds = %20
%31 = load i64, i64* %8
%32 = add i64 %31, 1
store i64 %32, i64* %8
br label %16
33: ; preds = %16
ret void
}

LLVM IR (-O2):
define void @vectorf_remove_mean(float* %0, i64 %1, float* %2) {
%4 = tail call i32 @assert(float* %0)
%5 = tail call i32 @assert(float* %2)
%6 = tail call float @vectorf_mean(float* %0, i64 %1)
%7 = icmp eq i64 %1, 0
br i1 %7, label %97, label %8
8: ; preds = %3
%9 = icmp ult i64 %1, 8
br i1 %9, label %78, label %10
10: ; preds = %8
%11 = getelementptr float, float* %2, i64 %1
%12 = getelementptr float, float* %0, i64 %1
%13 = icmp ugt float* %12, %2
%14 = icmp ugt float* %11, %0
%15 = and i1 %13, %14
br i1 %15, label %78, label %16
16: ; preds = %10
%17 = and i64 %1, -8
%18 = insertelement <4 x float> poison, float %6, i64 0
%19 = shufflevector <4 x float> %18, <4 x float> poison, <4 x i32> zeroinitializer
%20 = insertelement <4 x float> poison, float %6, i64 0
%21 = shufflevector <4 x float> %20, <4 x float> poison, <4 x i32> zeroinitializer
%22 = add i64 %17, -8
%23 = lshr exact i64 %22, 3
%24 = add nuw nsw i64 %23, 1
%25 = and i64 %24, 1
%26 = icmp eq i64 %22, 0
br i1 %26, label %60, label %27
27: ; preds = %16
%28 = and i64 %24, 4611686018427387902
br label %29
29: ; preds = %29, %27
%30 = phi i64 [ 0, %27 ], [ %57, %29 ]
%31 = phi i64 [ 0, %27 ], [ %58, %29 ]
%32 = getelementptr inbounds float, float* %0, i64 %30
%33 = bitcast float* %32 to <4 x float>*
%34 = load <4 x float>, <4 x float>* %33
%35 = getelementptr inbounds float, float* %32, i64 4
%36 = bitcast float* %35 to <4 x float>*
%37 = load <4 x float>, <4 x float>* %36
%38 = fsub <4 x float> %34, %19
%39 = fsub <4 x float> %37, %21
%40 = getelementptr inbounds float, float* %2, i64 %30
%41 = bitcast float* %40 to <4 x float>*
store <4 x float> %38, <4 x float>* %41
%42 = getelementptr inbounds float, float* %40, i64 4
%43 = bitcast float* %42 to <4 x float>*
store <4 x float> %39, <4 x float>* %43
%44 = or i64 %30, 8
%45 = getelementptr inbounds float, float* %0, i64 %44
%46 = bitcast float* %45 to <4 x float>*
%47 = load <4 x float>, <4 x float>* %46
%48 = getelementptr inbounds float, float* %45, i64 4
%49 = bitcast float* %48 to <4 x float>*
%50 = load <4 x float>, <4 x float>* %49
%51 = fsub <4 x float> %47, %19
%52 = fsub <4 x float> %50, %21
%53 = getelementptr inbounds float, float* %2, i64 %44
%54 = bitcast float* %53 to <4 x float>*
store <4 x float> %51, <4 x float>* %54
%55 = getelementptr inbounds float, float* %53, i64 4
%56 = bitcast float* %55 to <4 x float>*
store <4 x float> %52, <4 x float>* %56
%57 = add nuw i64 %30, 16
%58 = add i64 %31, 2
%59 = icmp eq i64 %58, %28
br i1 %59, label %60, label %29
60: ; preds = %29, %16
%61 = phi i64 [ 0, %16 ], [ %57, %29 ]
%62 = icmp eq i64 %25, 0
br i1 %62, label %76, label %63
63: ; preds = %60
%64 = getelementptr inbounds float, float* %0, i64 %61
%65 = bitcast float* %64 to <4 x float>*
%66 = load <4 x float>, <4 x float>* %65
%67 = getelementptr inbounds float, float* %64, i64 4
%68 = bitcast float* %67 to <4 x float>*
%69 = load <4 x float>, <4 x float>* %68
%70 = fsub <4 x float> %66, %19
%71 = fsub <4 x float> %69, %21
%72 = getelementptr inbounds float, float* %2, i64 %61
%73 = bitcast float* %72 to <4 x float>*
store <4 x float> %70, <4 x float>* %73
%74 = getelementptr inbounds float, float* %72, i64 4
%75 = bitcast float* %74 to <4 x float>*
store <4 x float> %71, <4 x float>* %75
br label %76
76: ; preds = %60, %63
%77 = icmp eq i64 %17, %1
br i1 %77, label %97, label %78
78: ; preds = %10, %8, %76
%79 = phi i64 [ 0, %10 ], [ 0, %8 ], [ %17, %76 ]
%80 = xor i64 %79, -1
%81 = add i64 %80, %1
%82 = and i64 %1, 3
%83 = icmp eq i64 %82, 0
br i1 %83, label %94, label %84
84: ; preds = %78, %84
%85 = phi i64 [ %91, %84 ], [ %79, %78 ]
%86 = phi i64 [ %92, %84 ], [ 0, %78 ]
%87 = getelementptr inbounds float, float* %0, i64 %85
%88 = load float, float* %87
%89 = fsub float %88, %6
%90 = getelementptr inbounds float, float* %2, i64 %85
store float %89, float* %90
%91 = add nuw i64 %85, 1
%92 = add i64 %86, 1
%93 = icmp eq i64 %92, %82
br i1 %93, label %94, label %84
94: ; preds = %84, %78
%95 = phi i64 [ %79, %78 ], [ %91, %84 ]
%96 = icmp ult i64 %81, 3
br i1 %96, label %97, label %98
97: ; preds = %94, %98, %76, %3
ret void
98: ; preds = %94, %98
%99 = phi i64 [ %119, %98 ], [ %95, %94 ]
%100 = getelementptr inbounds float, float* %0, i64 %99
%101 = load float, float* %100
%102 = fsub float %101, %6
%103 = getelementptr inbounds float, float* %2, i64 %99
store float %102, float* %103
%104 = add nuw i64 %99, 1
%105 = getelementptr inbounds float, float* %0, i64 %104
%106 = load float, float* %105
%107 = fsub float %106, %6
%108 = getelementptr inbounds float, float* %2, i64 %104
store float %107, float* %108
%109 = add nuw i64 %99, 2
%110 = getelementptr inbounds float, float* %0, i64 %109
%111 = load float, float* %110
%112 = fsub float %111, %6
%113 = getelementptr inbounds float, float* %2, i64 %109
store float %112, float* %113
%114 = add nuw i64 %99, 3
%115 = getelementptr inbounds float, float* %0, i64 %114
%116 = load float, float* %115
%117 = fsub float %116, %6
%118 = getelementptr inbounds float, float* %2, i64 %114
store float %117, float* %118
%119 = add nuw i64 %99, 4
%120 = icmp eq i64 %119, %1
br i1 %120, label %97, label %98
}