#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(int);
float floatsum(float *, size_t);
float floatsummask(float *, unsigned char *, size_t, size_t *);
float floatsumsquared(float *, size_t);
float floatsumsquaredmask(float *, unsigned char *, size_t, size_t *);
float sqrt(float);
void favestd(float *in, size_t size, float *ave, float *std,
             size_t *unmaskedsize, unsigned char *mask) {
  size_t nsize1, nsize2;
  float sum, sum2;
  if (mask == NULL) {
    sum = floatsum(in, size);
    sum2 = floatsumsquared(in, size);
  } else {
    sum = floatsummask(in, mask, size, &nsize1);
    sum2 = floatsumsquaredmask(in, mask, size, &nsize2);
    assert(nsize1 == nsize2);
    size = nsize1;
  }
  *ave = sum / size;
  *std = sqrt((sum2 - sum * sum / size) / size);
  *unmaskedsize = size;
}


x86 assembly (clang, -O0):
<favestd>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
cmpq   $0x0,-0x30(%rbp)
jne    11b4 <favestd+0x54>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1040 <floatsum@plt>
movss  %xmm0,-0x44(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1050 <floatsumsquared@plt>
movss  %xmm0,-0x48(%rbp)
jmp    1205 <favestd+0xa5>
mov    -0x8(%rbp),%rdi
mov    -0x30(%rbp),%rsi
mov    -0x10(%rbp),%rdx
lea    -0x38(%rbp),%rcx
call   1080 <floatsummask@plt>
movss  %xmm0,-0x44(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x30(%rbp),%rsi
mov    -0x10(%rbp),%rdx
lea    -0x40(%rbp),%rcx
call   1060 <floatsumsquaredmask@plt>
movss  %xmm0,-0x48(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x40(%rbp),%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
mov    -0x38(%rbp),%rax
mov    %rax,-0x10(%rbp)
movss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x54(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
shr    %rdx
mov    %eax,%ecx
and    $0x1,%ecx
or     %rdx,%rcx
cvtsi2ss %rcx,%xmm0
addss  %xmm0,%xmm0
cvtsi2ss %rax,%xmm1
movss  %xmm1,-0x50(%rbp)
test   %rax,%rax
movss  %xmm0,-0x4c(%rbp)
js     124c <favestd+0xec>
movss  -0x50(%rbp),%xmm0
movss  %xmm0,-0x4c(%rbp)
movss  -0x54(%rbp),%xmm0
movss  -0x4c(%rbp),%xmm1
divss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x48(%rbp),%xmm0
movss  %xmm0,-0x64(%rbp)
movss  -0x44(%rbp),%xmm0
mulss  %xmm0,%xmm0
movss  %xmm0,-0x60(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
shr    %rdx
mov    %eax,%ecx
and    $0x1,%ecx
or     %rdx,%rcx
cvtsi2ss %rcx,%xmm0
addss  %xmm0,%xmm0
cvtsi2ss %rax,%xmm1
movss  %xmm1,-0x5c(%rbp)
test   %rax,%rax
movss  %xmm0,-0x58(%rbp)
js     12b7 <favestd+0x157>
movss  -0x5c(%rbp),%xmm0
movss  %xmm0,-0x58(%rbp)
movss  -0x64(%rbp),%xmm0
movss  -0x60(%rbp),%xmm2
movss  -0x58(%rbp),%xmm1
divss  %xmm1,%xmm2
subss  %xmm2,%xmm0
divss  %xmm1,%xmm0
call   1070 <sqrt@plt>
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x10(%rbp),%rcx
mov    -0x28(%rbp),%rax
mov    %rcx,(%rax)
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<favestd>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %r8,%r14
mov    %rcx,%r15
mov    %rdx,%r12
mov    %rsi,%r13
mov    %rdi,%rbx
test   %r9,%r9
je     11dc <favestd+0x7c>
mov    %r9,%rbp
lea    0x8(%rsp),%rcx
mov    %rbx,%rdi
mov    %r9,%rsi
mov    %r13,%rdx
call   1080 <floatsummask@plt>
movss  %xmm0,0x4(%rsp)
lea    0x10(%rsp),%rcx
mov    %rbx,%rdi
mov    %rbp,%rsi
mov    %r13,%rdx
call   1060 <floatsumsquaredmask@plt>
movss  %xmm0,(%rsp)
mov    0x8(%rsp),%rax
xor    %edi,%edi
cmp    0x10(%rsp),%rax
sete   %dil
call   1030 <assert@plt>
mov    0x8(%rsp),%r13
test   %r13,%r13
js     1202 <favestd+0xa2>
cvtsi2ss %r13,%xmm3
jmp    121a <favestd+0xba>
mov    %rbx,%rdi
mov    %r13,%rsi
call   1040 <floatsum@plt>
movss  %xmm0,0x4(%rsp)
mov    %rbx,%rdi
mov    %r13,%rsi
call   1050 <floatsumsquared@plt>
movss  %xmm0,(%rsp)
test   %r13,%r13
jns    11d5 <favestd+0x75>
mov    %r13,%rax
shr    %rax
mov    %r13d,%ecx
and    $0x1,%ecx
or     %rax,%rcx
cvtsi2ss %rcx,%xmm3
addss  %xmm3,%xmm3
movss  0x4(%rsp),%xmm2
movss  (%rsp),%xmm0
movaps %xmm2,%xmm1
divss  %xmm3,%xmm1
movss  %xmm1,(%r12)
mulss  %xmm2,%xmm2
divss  %xmm3,%xmm2
subss  %xmm2,%xmm0
divss  %xmm3,%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jb     1250 <favestd+0xf0>
sqrtss %xmm0,%xmm0
jmp    1255 <favestd+0xf5>
call   1070 <sqrt@plt>
movss  %xmm0,(%r15)
mov    %r13,(%r14)
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @favestd(float* %0, i64 %1, float* %2, float* %3, i64* %4, i8* %5) {
%7 = alloca float*
%8 = alloca i64
%9 = alloca float*
%10 = alloca float*
%11 = alloca i64*
%12 = alloca i8*
%13 = alloca i64
%14 = alloca i64
%15 = alloca float
%16 = alloca float
store float* %0, float** %7
store i64 %1, i64* %8
store float* %2, float** %9
store float* %3, float** %10
store i64* %4, i64** %11
store i8* %5, i8** %12
%17 = load i8*, i8** %12
%18 = icmp eq i8* %17, null
br i1 %18, label %19, label %26
19: ; preds = %6
%20 = load float*, float** %7
%21 = load i64, i64* %8
%22 = call float @floatsum(float* %20, i64 %21)
store float %22, float* %15
%23 = load float*, float** %7
%24 = load i64, i64* %8
%25 = call float @floatsumsquared(float* %23, i64 %24)
store float %25, float* %16
br label %41
26: ; preds = %6
%27 = load float*, float** %7
%28 = load i8*, i8** %12
%29 = load i64, i64* %8
%30 = call float @floatsummask(float* %27, i8* %28, i64 %29, i64* %13)
store float %30, float* %15
%31 = load float*, float** %7
%32 = load i8*, i8** %12
%33 = load i64, i64* %8
%34 = call float @floatsumsquaredmask(float* %31, i8* %32, i64 %33, i64* %14)
store float %34, float* %16
%35 = load i64, i64* %13
%36 = load i64, i64* %14
%37 = icmp eq i64 %35, %36
%38 = zext i1 %37 to i32
%39 = call i32 @assert(i32 %38)
%40 = load i64, i64* %13
store i64 %40, i64* %8
br label %41
41: ; preds = %26, %19
%42 = load float, float* %15
%43 = load i64, i64* %8
%44 = uitofp i64 %43 to float
%45 = fdiv float %42, %44
%46 = load float*, float** %9
store float %45, float* %46
%47 = load float, float* %16
%48 = load float, float* %15
%49 = load float, float* %15
%50 = fmul float %48, %49
%51 = load i64, i64* %8
%52 = uitofp i64 %51 to float
%53 = fdiv float %50, %52
%54 = fsub float %47, %53
%55 = load i64, i64* %8
%56 = uitofp i64 %55 to float
%57 = fdiv float %54, %56
%58 = call float @sqrt(float %57)
%59 = load float*, float** %10
store float %58, float* %59
%60 = load i64, i64* %8
%61 = load i64*, i64** %11
store i64 %60, i64* %61
ret void
}

LLVM IR (-O2):
define void @favestd(float* %0, i64 %1, float* nocapture writeonly %2, float* nocapture writeonly %3, i64* nocapture writeonly %4, i8* %5) {
%7 = alloca i64
%8 = alloca i64
%9 = bitcast i64* %7 to i8*
%10 = bitcast i64* %8 to i8*
%11 = icmp eq i8* %5, null
br i1 %11, label %12, label %15
12: ; preds = %6
%13 = tail call float @floatsum(float* %0, i64 %1)
%14 = tail call float @floatsumsquared(float* %0, i64 %1)
br label %24
15: ; preds = %6
%16 = call float @floatsummask(float* %0, i8* %5, i64 %1, i64* %7)
%17 = call float @floatsumsquaredmask(float* %0, i8* %5, i64 %1, i64* %8)
%18 = load i64, i64* %7
%19 = load i64, i64* %8
%20 = icmp eq i64 %18, %19
%21 = zext i1 %20 to i32
%22 = call i32 @assert(i32 %21)
%23 = load i64, i64* %7
br label %24
24: ; preds = %15, %12
%25 = phi i64 [ %1, %12 ], [ %23, %15 ]
%26 = phi float [ %13, %12 ], [ %16, %15 ]
%27 = phi float [ %14, %12 ], [ %17, %15 ]
%28 = uitofp i64 %25 to float
%29 = fdiv float %26, %28
store float %29, float* %2
%30 = fmul float %26, %26
%31 = fdiv float %30, %28
%32 = fsub float %27, %31
%33 = fdiv float %32, %28
%34 = call float @sqrt(float %33)
store float %34, float* %3
store i64 %25, i64* %4
ret void
}