#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 NAN;
float fabsf(float const);
int /*<<< orphan*/ free(float *);
float *malloc(size_t);
float const medianf(float const *, size_t);
float madf(const float *x, size_t n, const float *med) {
  const float mad_scaling_factor = 1.4826;
  if (NULL == x) {
    return NAN;
  }
  if (1 == n) {
    return 0.0f;
  }
  float *absdiff = malloc(n * sizeof(float));
  if (NULL == absdiff) {
    return NAN;
  }
  const float _med = (NULL == med) ? medianf(x, n) : *med;
  for (size_t i = 0; i < n; i++) {
    absdiff[i] = fabsf(x[i] - _med);
  }
  const float mad = medianf(absdiff, n);
  free(absdiff);
  return mad * mad_scaling_factor;
}


x86 assembly (clang, -O0):
<madf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
movss  0xeb4(%rip),%xmm0
movss  %xmm0,-0x24(%rbp)
xor    %eax,%eax
cmp    -0x10(%rbp),%rax
jne    1172 <madf+0x42>
mov    0x2e94(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1278 <madf+0x148>
mov    $0x1,%eax
cmp    -0x18(%rbp),%rax
jne    118e <madf+0x5e>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1278 <madf+0x148>
mov    -0x18(%rbp),%rdi
shl    $0x2,%rdi
call   1050 <malloc@plt>
mov    %rax,-0x30(%rbp)
xor    %eax,%eax
cmp    -0x30(%rbp),%rax
jne    11c0 <madf+0x90>
mov    0x2e46(%rip),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1278 <madf+0x148>
xor    %eax,%eax
cmp    -0x20(%rbp),%rax
jne    11e3 <madf+0xb3>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <medianf@plt>
movss  %xmm0,-0x48(%rbp)
jmp    11f0 <madf+0xc0>
mov    -0x20(%rbp),%rax
movss  (%rax),%xmm0
movss  %xmm0,-0x48(%rbp)
movss  -0x48(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    124b <madf+0x11b>
mov    -0x10(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
subss  -0x34(%rbp),%xmm0
movaps 0xde7(%rip),%xmm1
pand   %xmm1,%xmm0
mov    -0x30(%rbp),%rax
mov    -0x40(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1202 <madf+0xd2>
mov    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <medianf@plt>
movss  %xmm0,-0x44(%rbp)
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
movss  0xd92(%rip),%xmm0
mulss  -0x44(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<madf>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
test   %rdi,%rdi
je     117d <madf+0x4d>
mov    %rsi,%r14
xorps  %xmm0,%xmm0
cmp    $0x1,%rsi
je     12c2 <madf+0x192>
mov    %rdx,%r12
mov    %rdi,%rbx
lea    0x0(,%r14,4),%rdi
call   1050 <malloc@plt>
test   %rax,%rax
je     117d <madf+0x4d>
mov    %rax,%r15
test   %r12,%r12
je     118d <madf+0x5d>
movss  (%r12),%xmm0
test   %r14,%r14
jne    11a1 <madf+0x71>
jmp    129b <madf+0x16b>
mov    0x2e74(%rip),%rax
movss  (%rax),%xmm0
jmp    12c2 <madf+0x192>
mov    %rbx,%rdi
mov    %r14,%rsi
call   1040 <medianf@plt>
test   %r14,%r14
je     129b <madf+0x16b>
cmp    $0x8,%r14
jae    11ae <madf+0x7e>
xor    %eax,%eax
jmp    126d <madf+0x13d>
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     12ce <madf+0x19e>
mov    %rdx,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %ecx,%ecx
movaps 0xe1c(%rip),%xmm2
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movups (%rbx,%rcx,4),%xmm3
movups 0x10(%rbx,%rcx,4),%xmm4
subps  %xmm1,%xmm3
subps  %xmm1,%xmm4
andps  %xmm2,%xmm3
andps  %xmm2,%xmm4
movups %xmm3,(%r15,%rcx,4)
movups %xmm4,0x10(%r15,%rcx,4)
movups 0x20(%rbx,%rcx,4),%xmm3
movups 0x30(%rbx,%rcx,4),%xmm4
subps  %xmm1,%xmm3
subps  %xmm1,%xmm4
andps  %xmm2,%xmm3
andps  %xmm2,%xmm4
movups %xmm3,0x20(%r15,%rcx,4)
movups %xmm4,0x30(%r15,%rcx,4)
add    $0x10,%rcx
add    $0xfffffffffffffffe,%rsi
jne    11f0 <madf+0xc0>
test   $0x1,%dl
je     1268 <madf+0x138>
movups (%rbx,%rcx,4),%xmm2
movups 0x10(%rbx,%rcx,4),%xmm3
subps  %xmm1,%xmm2
subps  %xmm1,%xmm3
movaps 0xda9(%rip),%xmm1
andps  %xmm1,%xmm2
andps  %xmm1,%xmm3
movups %xmm2,(%r15,%rcx,4)
movups %xmm3,0x10(%r15,%rcx,4)
cmp    %r14,%rax
je     129b <madf+0x16b>
movaps 0xd8c(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movss  (%rbx,%rax,4),%xmm2
subss  %xmm0,%xmm2
andps  %xmm1,%xmm2
movss  %xmm2,(%r15,%rax,4)
add    $0x1,%rax
cmp    %rax,%r14
jne    1280 <madf+0x150>
mov    %r15,%rdi
mov    %r14,%rsi
call   1040 <medianf@plt>
movss  %xmm0,0x4(%rsp)
mov    %r15,%rdi
call   1030 <free@plt>
movss  0x4(%rsp),%xmm0
mulss  0xd4e(%rip),%xmm0
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret
xor    %ecx,%ecx
test   $0x1,%dl
jne    1241 <madf+0x111>
jmp    1268 <madf+0x138>

LLVM IR (-O0):
@NAN = global float 0.000000e+00
define float @madf(float* %0, i64 %1, float* %2) {
%4 = alloca float
%5 = alloca float*
%6 = alloca i64
%7 = alloca float*
%8 = alloca float
%9 = alloca float*
%10 = alloca float
%11 = alloca i64
%12 = alloca float
store float* %0, float** %5
store i64 %1, i64* %6
store float* %2, float** %7
store float 0x3FF7B8BAC0000000, float* %8
%13 = load float*, float** %5
%14 = icmp eq float* null, %13
br i1 %14, label %15, label %17
15: ; preds = %3
%16 = load float, float* @NAN
store float %16, float* %4
br label %67
17: ; preds = %3
%18 = load i64, i64* %6
%19 = icmp eq i64 1, %18
br i1 %19, label %20, label %21
20: ; preds = %17
store float 0.000000e+00, float* %4
br label %67
21: ; preds = %17
%22 = load i64, i64* %6
%23 = mul i64 %22, 4
%24 = call float* @malloc(i64 %23)
store float* %24, float** %9
%25 = load float*, float** %9
%26 = icmp eq float* null, %25
br i1 %26, label %27, label %29
27: ; preds = %21
%28 = load float, float* @NAN
store float %28, float* %4
br label %67
29: ; preds = %21
%30 = load float*, float** %7
%31 = icmp eq float* null, %30
br i1 %31, label %32, label %36
32: ; preds = %29
%33 = load float*, float** %5
%34 = load i64, i64* %6
%35 = call float @medianf(float* %33, i64 %34)
br label %39
36: ; preds = %29
%37 = load float*, float** %7
%38 = load float, float* %37
br label %39
39: ; preds = %36, %32
%40 = phi float [ %35, %32 ], [ %38, %36 ]
store float %40, float* %10
store i64 0, i64* %11
br label %41
41: ; preds = %56, %39
%42 = load i64, i64* %11
%43 = load i64, i64* %6
%44 = icmp ult i64 %42, %43
br i1 %44, label %45, label %59
45: ; preds = %41
%46 = load float*, float** %5
%47 = load i64, i64* %11
%48 = getelementptr inbounds float, float* %46, i64 %47
%49 = load float, float* %48
%50 = load float, float* %10
%51 = fsub float %49, %50
%52 = call float @llvm.fabs.f32(float %51)
%53 = load float*, float** %9
%54 = load i64, i64* %11
%55 = getelementptr inbounds float, float* %53, i64 %54
store float %52, float* %55
br label %56
56: ; preds = %45
%57 = load i64, i64* %11
%58 = add i64 %57, 1
store i64 %58, i64* %11
br label %41
59: ; preds = %41
%60 = load float*, float** %9
%61 = load i64, i64* %6
%62 = call float @medianf(float* %60, i64 %61)
store float %62, float* %12
%63 = load float*, float** %9
%64 = call i32 @free(float* %63)
%65 = load float, float* %12
%66 = fmul float %65, 0x3FF7B8BAC0000000
store float %66, float* %4
br label %67
67: ; preds = %59, %27, %20, %15
%68 = load float, float* %4
ret float %68
}

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