#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 fabs(float const);
int /*<<< orphan*/ printf(char *, float);
int check_output(const float *data_in, unsigned len, float allowable) {
  float max_abs = 0.0;
  unsigned k;
  for (k = 0; k < len; k++) {
    float temp = fabs(data_in[k]);
    max_abs = ((max_abs) > (temp) ? (max_abs) : (temp));
  }
  if (max_abs < 0.95 - allowable) {
    printf("Error : max_abs (%f) too small.\n", max_abs);
    return 1;
  } else if (max_abs > .95 + allowable) {
    printf("Error : max_abs (%f) too big.\n", max_abs);
    return 1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<check_output>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movss  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x14(%rbp),%eax
jae    11a5 <check_output+0x85>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%ecx
movss  (%rax,%rcx,4),%xmm0
call   1040 <fabs@plt>
movss  %xmm0,-0x24(%rbp)
movss  -0x1c(%rbp),%xmm0
ucomiss -0x24(%rbp),%xmm0
jbe    1183 <check_output+0x63>
movss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
jmp    118d <check_output+0x6d>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1143 <check_output+0x23>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movss  -0x18(%rbp),%xmm0
cvtss2sd %xmm0,%xmm2
movsd  0xe41(%rip),%xmm0
subsd  %xmm2,%xmm0
ucomisd %xmm1,%xmm0
jbe    11ea <check_output+0xca>
movss  -0x1c(%rbp),%xmm0
lea    0xe2f(%rip),%rdi
call   1030 <printf@plt>
movl   $0x1,-0x4(%rbp)
jmp    123b <check_output+0x11b>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movss  -0x18(%rbp),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  0xdfc(%rip),%xmm1
addsd  %xmm2,%xmm1
ucomisd %xmm1,%xmm0
jbe    122f <check_output+0x10f>
movss  -0x1c(%rbp),%xmm0
lea    0xe0b(%rip),%rdi
call   1030 <printf@plt>
movl   $0x1,-0x4(%rbp)
jmp    123b <check_output+0x11b>
jmp    1234 <check_output+0x114>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<check_output>:
push   %rax
movaps %xmm0,%xmm1
test   %esi,%esi
je     1130 <check_output+0x20>
mov    %esi,%ecx
lea    -0x1(%rcx),%rdx
mov    %ecx,%eax
and    $0x3,%eax
cmp    $0x3,%rdx
jae    1138 <check_output+0x28>
xorps  %xmm0,%xmm0
xor    %edx,%edx
jmp    118c <check_output+0x7c>
xorps  %xmm0,%xmm0
jmp    11b5 <check_output+0xa5>
and    $0xfffffffc,%ecx
xorps  %xmm0,%xmm0
xor    %edx,%edx
movaps 0xeb9(%rip),%xmm2
nopw   0x0(%rax,%rax,1)
movss  (%rdi,%rdx,4),%xmm3
movss  0x4(%rdi,%rdx,4),%xmm4
movss  0x8(%rdi,%rdx,4),%xmm5
movss  0xc(%rdi,%rdx,4),%xmm6
andps  %xmm2,%xmm3
maxss  %xmm3,%xmm0
andps  %xmm2,%xmm4
maxss  %xmm4,%xmm0
andps  %xmm2,%xmm5
maxss  %xmm5,%xmm0
andps  %xmm2,%xmm6
maxss  %xmm6,%xmm0
add    $0x4,%rdx
cmp    %rdx,%rcx
jne    1150 <check_output+0x40>
test   %rax,%rax
je     11b5 <check_output+0xa5>
lea    (%rdi,%rdx,4),%rcx
xor    %edx,%edx
movaps 0xe62(%rip),%xmm2
xchg   %ax,%ax
movss  (%rcx,%rdx,4),%xmm3
andps  %xmm2,%xmm3
maxss  %xmm3,%xmm0
add    $0x1,%rdx
cmp    %rdx,%rax
jne    11a0 <check_output+0x90>
xorps  %xmm2,%xmm2
cvtss2sd %xmm0,%xmm2
cvtss2sd %xmm1,%xmm1
movsd  0xe48(%rip),%xmm3
subsd  %xmm1,%xmm3
ucomisd %xmm2,%xmm3
jbe    11db <check_output+0xcb>
lea    0xe3f(%rip),%rdi
jmp    11f2 <check_output+0xe2>
addsd  0xe2d(%rip),%xmm1
xor    %eax,%eax
ucomisd %xmm1,%xmm2
jbe    11fc <check_output+0xec>
lea    0xe47(%rip),%rdi
call   1030 <printf@plt>
mov    $0x1,%eax
pop    %rcx
ret

LLVM IR (-O0):
@.str = [33 x i8] c"Error : max_abs (%f) too small.\0A\00"
@.str.1 = [31 x i8] c"Error : max_abs (%f) too big.\0A\00"
define i32 @check_output(float* %0, i32 %1, float %2) {
%4 = alloca i32
%5 = alloca float*
%6 = alloca i32
%7 = alloca float
%8 = alloca float
%9 = alloca i32
%10 = alloca float
store float* %0, float** %5
store i32 %1, i32* %6
store float %2, float* %7
store float 0.000000e+00, float* %8
store i32 0, i32* %9
br label %11
11: ; preds = %31, %3
%12 = load i32, i32* %9
%13 = load i32, i32* %6
%14 = icmp ult i32 %12, %13
br i1 %14, label %15, label %34
15: ; preds = %11
%16 = load float*, float** %5
%17 = load i32, i32* %9
%18 = zext i32 %17 to i64
%19 = getelementptr inbounds float, float* %16, i64 %18
%20 = load float, float* %19
%21 = call float @fabs(float %20)
store float %21, float* %10
%22 = load float, float* %8
%23 = load float, float* %10
%24 = fcmp ogt float %22, %23
br i1 %24, label %25, label %27
25: ; preds = %15
%26 = load float, float* %8
br label %29
27: ; preds = %15
%28 = load float, float* %10
br label %29
29: ; preds = %27, %25
%30 = phi float [ %26, %25 ], [ %28, %27 ]
store float %30, float* %8
br label %31
31: ; preds = %29
%32 = load i32, i32* %9
%33 = add i32 %32, 1
store i32 %33, i32* %9
br label %11
34: ; preds = %11
%35 = load float, float* %8
%36 = fpext float %35 to double
%37 = load float, float* %7
%38 = fpext float %37 to double
%39 = fsub double 0x3FEE666666666666, %38
%40 = fcmp olt double %36, %39
br i1 %40, label %41, label %44
41: ; preds = %34
%42 = load float, float* %8
%43 = call i32 @printf(i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i64 0, i64 0), float %42)
store i32 1, i32* %4
br label %56
44: ; preds = %34
%45 = load float, float* %8
%46 = fpext float %45 to double
%47 = load float, float* %7
%48 = fpext float %47 to double
%49 = fadd double 0x3FEE666666666666, %48
%50 = fcmp ogt double %46, %49
br i1 %50, label %51, label %54
51: ; preds = %44
%52 = load float, float* %8
%53 = call i32 @printf(i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str.1, i64 0, i64 0), float %52)
store i32 1, i32* %4
br label %56
54: ; preds = %44
br label %55
55: ; preds = %54
store i32 0, i32* %4
br label %56
56: ; preds = %55, %51, %41
%57 = load i32, i32* %4
ret i32 %57
}

LLVM IR (-O2):
@.str = [33 x i8] c"Error : max_abs (%f) too small.\0A\00"
@.str.1 = [31 x i8] c"Error : max_abs (%f) too big.\0A\00"
define i32 @check_output(float* nocapture %0, i32 %1, float %2) {
%4 = icmp eq i32 %1, 0
br i1 %4, label %59, label %5
5: ; preds = %3
%6 = zext i32 %1 to i64
%7 = add nsw i64 %6, -1
%8 = and i64 %6, 3
%9 = icmp ult i64 %7, 3
br i1 %9, label %42, label %10
10: ; preds = %5
%11 = and i64 %6, 4294967292
br label %12
12: ; preds = %12, %10
%13 = phi i64 [ 0, %10 ], [ %39, %12 ]
%14 = phi float [ 0.000000e+00, %10 ], [ %38, %12 ]
%15 = phi i64 [ 0, %10 ], [ %40, %12 ]
%16 = getelementptr inbounds float, float* %0, i64 %13
%17 = load float, float* %16
%18 = tail call float @llvm.fabs.f32(float %17)
%19 = fcmp ogt float %14, %18
%20 = select i1 %19, float %14, float %18
%21 = or i64 %13, 1
%22 = getelementptr inbounds float, float* %0, i64 %21
%23 = load float, float* %22
%24 = tail call float @llvm.fabs.f32(float %23)
%25 = fcmp ogt float %20, %24
%26 = select i1 %25, float %20, float %24
%27 = or i64 %13, 2
%28 = getelementptr inbounds float, float* %0, i64 %27
%29 = load float, float* %28
%30 = tail call float @llvm.fabs.f32(float %29)
%31 = fcmp ogt float %26, %30
%32 = select i1 %31, float %26, float %30
%33 = or i64 %13, 3
%34 = getelementptr inbounds float, float* %0, i64 %33
%35 = load float, float* %34
%36 = tail call float @llvm.fabs.f32(float %35)
%37 = fcmp ogt float %32, %36
%38 = select i1 %37, float %32, float %36
%39 = add nuw nsw i64 %13, 4
%40 = add i64 %15, 4
%41 = icmp eq i64 %40, %11
br i1 %41, label %42, label %12
42: ; preds = %12, %5
%43 = phi float [ undef, %5 ], [ %38, %12 ]
%44 = phi i64 [ 0, %5 ], [ %39, %12 ]
%45 = phi float [ 0.000000e+00, %5 ], [ %38, %12 ]
%46 = icmp eq i64 %8, 0
br i1 %46, label %59, label %47
47: ; preds = %42, %47
%48 = phi i64 [ %56, %47 ], [ %44, %42 ]
%49 = phi float [ %55, %47 ], [ %45, %42 ]
%50 = phi i64 [ %57, %47 ], [ 0, %42 ]
%51 = getelementptr inbounds float, float* %0, i64 %48
%52 = load float, float* %51
%53 = tail call float @llvm.fabs.f32(float %52)
%54 = fcmp ogt float %49, %53
%55 = select i1 %54, float %49, float %53
%56 = add nuw nsw i64 %48, 1
%57 = add i64 %50, 1
%58 = icmp eq i64 %57, %8
br i1 %58, label %59, label %47
59: ; preds = %42, %47, %3
%60 = phi float [ 0.000000e+00, %3 ], [ %43, %42 ], [ %55, %47 ]
%61 = fpext float %60 to double
%62 = fpext float %2 to double
%63 = fsub double 0x3FEE666666666666, %62
%64 = fcmp ogt double %63, %61
br i1 %64, label %68, label %65
65: ; preds = %59
%66 = fadd double %62, 0x3FEE666666666666
%67 = fcmp olt double %66, %61
br i1 %67, label %68, label %71
68: ; preds = %65, %59
%69 = phi i8* [ getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i64 0, i64 0), %59 ], [ getelementptr inbounds ([31 x i8], [31 x i8]* @.str.1, i64 0, i64 0), %65 ]
%70 = tail call i32 @printf(i8* %69, float %60)
br label %71
71: ; preds = %68, %65
%72 = phi i32 [ 0, %65 ], [ 1, %68 ]
ret i32 %72
}