#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 */
float FLT_MAX;
float FLT_MIN;
void array_stats(float img[], int npx, float *minval, float *maxval,
                 float *mean, float *var) {
  int i;
  double t, s1, s2, y0, ts1, ts2;
  float mini, maxi, tmin, tmax;
  mini = FLT_MAX;
  maxi = FLT_MIN;
  s1 = 0.;
  s2 = 0.;
  y0 = img[0];
#pragma omp parallel private(i, t, ts1, ts2, tmin, tmax)
  {
    tmin = FLT_MAX;
    tmax = FLT_MIN;
    ts1 = 0.;
    ts2 = 0.;
#pragma omp for
    for (i = 0; i < npx; i++) {
      t = img[i] - y0;
      ts1 = ts1 + t;
      ts2 = ts2 + t * t;
      if (img[i] < tmin)
        tmin = img[i];
      if (img[i] > tmax)
        tmax = img[i];
    }
#pragma omp critical
    {
      s1 += ts1;
      s2 += ts2;
      if (tmin < mini)
        mini = tmin;
      if (tmax > maxi)
        maxi = tmax;
    }
  }
  *mean = (float)(s1 / npx + y0);
  *var = (float)((s2 - (s1 * s1 / npx)) / npx);
  *minval = mini;
  *maxval = maxi;
}


x86 assembly (clang, -O0):
<array_stats>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    0x2ebe(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x6c(%rbp)
mov    0x2eb6(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x70(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    0x2e7d(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x74(%rbp)
mov    0x2e75(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x78(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    124e <array_stats+0x14e>
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
subsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x60(%rbp),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x68(%rbp),%xmm1
movsd  -0x40(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
movss  -0x74(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1212 <array_stats+0x112>
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x74(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
ucomiss -0x78(%rbp),%xmm0
jbe    123b <array_stats+0x13b>
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x78(%rbp)
jmp    1240 <array_stats+0x140>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1193 <array_stats+0x93>
movsd  -0x60(%rbp),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x68(%rbp),%xmm0
addsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movss  -0x74(%rbp),%xmm1
movss  -0x6c(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1289 <array_stats+0x189>
movss  -0x74(%rbp),%xmm0
movss  %xmm0,-0x6c(%rbp)
movss  -0x78(%rbp),%xmm0
ucomiss -0x70(%rbp),%xmm0
jbe    12a2 <array_stats+0x1a2>
movss  -0x78(%rbp),%xmm0
movss  %xmm0,-0x70(%rbp)
movsd  -0x48(%rbp),%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
divsd  %xmm1,%xmm0
addsd  -0x58(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,(%rax)
movsd  -0x50(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm1
mulsd  -0x48(%rbp),%xmm1
cvtsi2sdl -0xc(%rbp),%xmm2
divsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
cvtsi2sdl -0xc(%rbp),%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x30(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x6c(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x70(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<array_stats>:
push   %rbx
mov    0x2ed8(%rip),%rax
movss  (%rax),%xmm9
mov    0x2ed4(%rip),%rax
movss  (%rax),%xmm10
movss  (%rdi),%xmm5
cvtss2sd %xmm5,%xmm11
test   %esi,%esi
jle    1172 <array_stats+0x72>
movaps %xmm11,%xmm2
subsd  %xmm11,%xmm2
xorpd  %xmm8,%xmm8
movapd %xmm2,%xmm1
addsd  %xmm8,%xmm1
mulsd  %xmm2,%xmm2
addsd  %xmm8,%xmm2
movaps %xmm5,%xmm6
minss  %xmm9,%xmm6
maxss  %xmm10,%xmm5
cmp    $0x1,%esi
je     123a <array_stats+0x13a>
mov    %esi,%r10d
add    $0xffffffffffffffff,%r10
cmp    $0x2,%esi
jne    1187 <array_stats+0x87>
mov    $0x1,%eax
jmp    1206 <array_stats+0x106>
xorpd  %xmm1,%xmm1
xorpd  %xmm2,%xmm2
movaps %xmm9,%xmm6
movaps %xmm10,%xmm5
jmp    1244 <array_stats+0x144>
mov    %r10,%r11
and    $0xfffffffffffffffe,%r11
neg    %r11
mov    $0x1,%eax
movaps %xmm5,%xmm7
nopl   0x0(%rax)
movss  (%rdi,%rax,4),%xmm3
movss  0x4(%rdi,%rax,4),%xmm5
xorps  %xmm4,%xmm4
cvtss2sd %xmm3,%xmm4
subsd  %xmm11,%xmm4
addsd  %xmm4,%xmm1
mulsd  %xmm4,%xmm4
addsd  %xmm2,%xmm4
movaps %xmm3,%xmm0
minss  %xmm6,%xmm0
maxss  %xmm7,%xmm3
xorps  %xmm2,%xmm2
cvtss2sd %xmm5,%xmm2
subsd  %xmm11,%xmm2
addsd  %xmm2,%xmm1
mulsd  %xmm2,%xmm2
addsd  %xmm4,%xmm2
movaps %xmm5,%xmm6
minss  %xmm0,%xmm6
maxss  %xmm3,%xmm5
lea    (%r11,%rax,1),%rbx
add    $0x2,%rbx
add    $0x2,%rax
movaps %xmm5,%xmm7
cmp    $0x1,%rbx
jne    11a0 <array_stats+0xa0>
test   $0x1,%r10b
je     123a <array_stats+0x13a>
movss  (%rdi,%rax,4),%xmm0
xorps  %xmm3,%xmm3
cvtss2sd %xmm0,%xmm3
subsd  %xmm11,%xmm3
addsd  %xmm3,%xmm1
mulsd  %xmm3,%xmm3
addsd  %xmm3,%xmm2
movaps %xmm0,%xmm3
minss  %xmm6,%xmm3
maxss  %xmm5,%xmm0
movaps %xmm3,%xmm6
movaps %xmm0,%xmm5
addsd  %xmm8,%xmm1
addsd  %xmm8,%xmm2
minss  %xmm9,%xmm6
maxss  %xmm10,%xmm5
xorps  %xmm0,%xmm0
cvtsi2sd %esi,%xmm0
movapd %xmm1,%xmm3
divsd  %xmm0,%xmm3
addsd  %xmm11,%xmm3
cvtsd2ss %xmm3,%xmm3
mulsd  %xmm1,%xmm1
divsd  %xmm0,%xmm1
subsd  %xmm1,%xmm2
divsd  %xmm0,%xmm2
xorps  %xmm0,%xmm0
cvtsd2ss %xmm2,%xmm0
movss  %xmm3,(%r8)
movss  %xmm0,(%r9)
movss  %xmm6,(%rdx)
movss  %xmm5,(%rcx)
pop    %rbx
ret

LLVM IR (-O0):
@FLT_MAX = global float 0.000000e+00
@FLT_MIN = global float 0.000000e+00
define void @array_stats(float* %0, i32 %1, float* %2, float* %3, float* %4, float* %5) {
%7 = alloca float*
%8 = alloca i32
%9 = alloca float*
%10 = alloca float*
%11 = alloca float*
%12 = alloca float*
%13 = alloca i32
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca float
%21 = alloca float
%22 = alloca float
%23 = alloca float
store float* %0, float** %7
store i32 %1, i32* %8
store float* %2, float** %9
store float* %3, float** %10
store float* %4, float** %11
store float* %5, float** %12
%24 = load float, float* @FLT_MAX
store float %24, float* %20
%25 = load float, float* @FLT_MIN
store float %25, float* %21
store double 0.000000e+00, double* %15
store double 0.000000e+00, double* %16
%26 = load float*, float** %7
%27 = getelementptr inbounds float, float* %26, i64 0
%28 = load float, float* %27
%29 = fpext float %28 to double
store double %29, double* %17
%30 = load float, float* @FLT_MAX
store float %30, float* %22
%31 = load float, float* @FLT_MIN
store float %31, float* %23
store double 0.000000e+00, double* %18
store double 0.000000e+00, double* %19
store i32 0, i32* %13
br label %32
32: ; preds = %80, %6
%33 = load i32, i32* %13
%34 = load i32, i32* %8
%35 = icmp slt i32 %33, %34
br i1 %35, label %36, label %83
36: ; preds = %32
%37 = load float*, float** %7
%38 = load i32, i32* %13
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds float, float* %37, i64 %39
%41 = load float, float* %40
%42 = fpext float %41 to double
%43 = load double, double* %17
%44 = fsub double %42, %43
store double %44, double* %14
%45 = load double, double* %18
%46 = load double, double* %14
%47 = fadd double %45, %46
store double %47, double* %18
%48 = load double, double* %19
%49 = load double, double* %14
%50 = load double, double* %14
%51 = call double @llvm.fmuladd.f64(double %49, double %50, double %48)
store double %51, double* %19
%52 = load float*, float** %7
%53 = load i32, i32* %13
%54 = sext i32 %53 to i64
%55 = getelementptr inbounds float, float* %52, i64 %54
%56 = load float, float* %55
%57 = load float, float* %22
%58 = fcmp olt float %56, %57
br i1 %58, label %59, label %65
59: ; preds = %36
%60 = load float*, float** %7
%61 = load i32, i32* %13
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds float, float* %60, i64 %62
%64 = load float, float* %63
store float %64, float* %22
br label %65
65: ; preds = %59, %36
%66 = load float*, float** %7
%67 = load i32, i32* %13
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds float, float* %66, i64 %68
%70 = load float, float* %69
%71 = load float, float* %23
%72 = fcmp ogt float %70, %71
br i1 %72, label %73, label %79
73: ; preds = %65
%74 = load float*, float** %7
%75 = load i32, i32* %13
%76 = sext i32 %75 to i64
%77 = getelementptr inbounds float, float* %74, i64 %76
%78 = load float, float* %77
store float %78, float* %23
br label %79
79: ; preds = %73, %65
br label %80
80: ; preds = %79
%81 = load i32, i32* %13
%82 = add nsw i32 %81, 1
store i32 %82, i32* %13
br label %32
83: ; preds = %32
%84 = load double, double* %18
%85 = load double, double* %15
%86 = fadd double %85, %84
store double %86, double* %15
%87 = load double, double* %19
%88 = load double, double* %16
%89 = fadd double %88, %87
store double %89, double* %16
%90 = load float, float* %22
%91 = load float, float* %20
%92 = fcmp olt float %90, %91
br i1 %92, label %93, label %95
93: ; preds = %83
%94 = load float, float* %22
store float %94, float* %20
br label %95
95: ; preds = %93, %83
%96 = load float, float* %23
%97 = load float, float* %21
%98 = fcmp ogt float %96, %97
br i1 %98, label %99, label %101
99: ; preds = %95
%100 = load float, float* %23
store float %100, float* %21
br label %101
101: ; preds = %99, %95
%102 = load double, double* %15
%103 = load i32, i32* %8
%104 = sitofp i32 %103 to double
%105 = fdiv double %102, %104
%106 = load double, double* %17
%107 = fadd double %105, %106
%108 = fptrunc double %107 to float
%109 = load float*, float** %11
store float %108, float* %109
%110 = load double, double* %16
%111 = load double, double* %15
%112 = load double, double* %15
%113 = fmul double %111, %112
%114 = load i32, i32* %8
%115 = sitofp i32 %114 to double
%116 = fdiv double %113, %115
%117 = fsub double %110, %116
%118 = load i32, i32* %8
%119 = sitofp i32 %118 to double
%120 = fdiv double %117, %119
%121 = fptrunc double %120 to float
%122 = load float*, float** %12
store float %121, float* %122
%123 = load float, float* %20
%124 = load float*, float** %9
store float %123, float* %124
%125 = load float, float* %21
%126 = load float*, float** %10
store float %125, float* %126
ret void
}

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