int wcsutil_Eq(int nelem, double tol, const double *arr1, const double *arr2) {
  int i;
  if (nelem == 0)
    return 1;
  if (nelem < 0)
    return 0;
  if (arr1 == 0x0 && arr2 == 0x0)
    return 1;
  if (arr1 == 0x0 || arr2 == 0x0)
    return 0;
  if (tol == 0.0) {
    for (i = 0; i < nelem; i++, arr1++, arr2++) {
      if (*arr1 != *arr2)
        return 0;
    }
  } else {
    for (i = 0; i < nelem; i++, arr1++, arr2++) {
      if (*arr1 == 987654321.0e99 && *arr2 != 987654321.0e99)
        return 0;
      if (*arr1 != 987654321.0e99 && *arr2 == 987654321.0e99)
        return 0;
      if (fabs(*arr1 - *arr2) > 0.5 * tol)
        return 0;
    }
  }
  return 1;
}


x86 assembly (clang, -O0):
<wcsutil_Eq>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
cmpl   $0x0,-0x8(%rbp)
jne    112a <wcsutil_Eq+0x2a>
movl   $0x1,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
cmpl   $0x0,-0x8(%rbp)
jge    1140 <wcsutil_Eq+0x40>
movl   $0x0,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
cmpq   $0x0,-0x18(%rbp)
jne    1162 <wcsutil_Eq+0x62>
cmpq   $0x0,-0x20(%rbp)
jne    1162 <wcsutil_Eq+0x62>
movl   $0x1,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
cmpq   $0x0,-0x18(%rbp)
je     1178 <wcsutil_Eq+0x78>
cmpq   $0x0,-0x20(%rbp)
jne    1184 <wcsutil_Eq+0x84>
movl   $0x0,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
movsd  -0x10(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    120c <wcsutil_Eq+0x10c>
jp     120c <wcsutil_Eq+0x10c>
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    1207 <wcsutil_Eq+0x107>
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
ucomisd (%rax),%xmm0
jne    11d0 <wcsutil_Eq+0xd0>
jp     11d0 <wcsutil_Eq+0xd0>
jmp    11dc <wcsutil_Eq+0xdc>
movl   $0x0,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
jmp    11e1 <wcsutil_Eq+0xe1>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x18(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x20(%rbp)
jmp    11a3 <wcsutil_Eq+0xa3>
jmp    132f <wcsutil_Eq+0x22f>
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    132a <wcsutil_Eq+0x22a>
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xdd1(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1270 <wcsutil_Eq+0x170>
jp     1270 <wcsutil_Eq+0x170>
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xdb1(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1264 <wcsutil_Eq+0x164>
jp     1264 <wcsutil_Eq+0x164>
jmp    1270 <wcsutil_Eq+0x170>
movl   $0x0,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xd80(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1295 <wcsutil_Eq+0x195>
jp     1295 <wcsutil_Eq+0x195>
jmp    12c1 <wcsutil_Eq+0x1c1>
mov    -0x20(%rbp),%rax
movsd  (%rax),%xmm0
movsd  0xd5b(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    12c1 <wcsutil_Eq+0x1c1>
jp     12c1 <wcsutil_Eq+0x1c1>
movl   $0x0,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
mov    -0x18(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x20(%rbp),%rax
subsd  (%rax),%xmm0
movaps 0xd38(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  0xd24(%rip),%xmm1
mulsd  -0x10(%rbp),%xmm1
ucomisd %xmm1,%xmm0
jbe    12ff <wcsutil_Eq+0x1ff>
movl   $0x0,-0x4(%rbp)
jmp    1336 <wcsutil_Eq+0x236>
jmp    1304 <wcsutil_Eq+0x204>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x18(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x20(%rbp)
jmp    1213 <wcsutil_Eq+0x113>
jmp    132f <wcsutil_Eq+0x22f>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<wcsutil_Eq>:
test   %edi,%edi
je     1112 <wcsutil_Eq+0x12>
xor    %eax,%eax
test   %edi,%edi
js     1117 <wcsutil_Eq+0x17>
mov    %rsi,%rcx
or     %rdx,%rcx
jne    1118 <wcsutil_Eq+0x18>
mov    $0x1,%eax
ret
test   %rsi,%rsi
je     1117 <wcsutil_Eq+0x17>
test   %rdx,%rdx
je     1117 <wcsutil_Eq+0x17>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1158 <wcsutil_Eq+0x58>
jp     1158 <wcsutil_Eq+0x58>
mov    %edi,%ecx
xor    %eax,%eax
xor    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsd  (%rsi,%rdi,8),%xmm0
ucomisd (%rdx,%rdi,8),%xmm0
jne    1117 <wcsutil_Eq+0x17>
jp     1117 <wcsutil_Eq+0x17>
add    $0x1,%rdi
cmp    %edi,%ecx
jne    1140 <wcsutil_Eq+0x40>
jmp    1112 <wcsutil_Eq+0x12>
mulsd  0xea0(%rip),%xmm0
mov    %edi,%ecx
xor    %edi,%edi
movsd  0xe9c(%rip),%xmm1
movapd 0xe9c(%rip),%xmm2
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsd  (%rsi,%rdi,8),%xmm3
ucomisd %xmm1,%xmm3
jne    119a <wcsutil_Eq+0x9a>
jp     119a <wcsutil_Eq+0x9a>
movsd  (%rdx,%rdi,8),%xmm4
ucomisd %xmm1,%xmm4
jne    11d4 <wcsutil_Eq+0xd4>
jp     11d4 <wcsutil_Eq+0xd4>
xor    %eax,%eax
ucomisd %xmm1,%xmm3
movsd  (%rdx,%rdi,8),%xmm4
jne    11a9 <wcsutil_Eq+0xa9>
jnp    11b5 <wcsutil_Eq+0xb5>
ucomisd %xmm1,%xmm4
jne    11b5 <wcsutil_Eq+0xb5>
jnp    1117 <wcsutil_Eq+0x17>
subsd  %xmm4,%xmm3
andpd  %xmm2,%xmm3
ucomisd %xmm0,%xmm3
ja     1117 <wcsutil_Eq+0x17>
add    $0x1,%rdi
cmp    %edi,%ecx
jne    1180 <wcsutil_Eq+0x80>
jmp    1112 <wcsutil_Eq+0x12>
xor    %eax,%eax
ret

LLVM IR (-O0):
define i32 @wcsutil_Eq(i32 %0, double %1, double* %2, double* %3) {
%5 = alloca i32
%6 = alloca i32
%7 = alloca double
%8 = alloca double*
%9 = alloca double*
%10 = alloca i32
store i32 %0, i32* %6
store double %1, double* %7
store double* %2, double** %8
store double* %3, double** %9
%11 = load i32, i32* %6
%12 = icmp eq i32 %11, 0
br i1 %12, label %13, label %14
13: ; preds = %4
store i32 1, i32* %5
br label %100
14: ; preds = %4
%15 = load i32, i32* %6
%16 = icmp slt i32 %15, 0
br i1 %16, label %17, label %18
17: ; preds = %14
store i32 0, i32* %5
br label %100
18: ; preds = %14
%19 = load double*, double** %8
%20 = icmp eq double* %19, null
br i1 %20, label %21, label %25
21: ; preds = %18
%22 = load double*, double** %9
%23 = icmp eq double* %22, null
br i1 %23, label %24, label %25
24: ; preds = %21
store i32 1, i32* %5
br label %100
25: ; preds = %21, %18
%26 = load double*, double** %8
%27 = icmp eq double* %26, null
br i1 %27, label %31, label %28
28: ; preds = %25
%29 = load double*, double** %9
%30 = icmp eq double* %29, null
br i1 %30, label %31, label %32
31: ; preds = %28, %25
store i32 0, i32* %5
br label %100
32: ; preds = %28
%33 = load double, double* %7
%34 = fcmp oeq double %33, 0.000000e+00
br i1 %34, label %35, label %56
35: ; preds = %32
store i32 0, i32* %10
br label %36
36: ; preds = %48, %35
%37 = load i32, i32* %10
%38 = load i32, i32* %6
%39 = icmp slt i32 %37, %38
br i1 %39, label %40, label %55
40: ; preds = %36
%41 = load double*, double** %8
%42 = load double, double* %41
%43 = load double*, double** %9
%44 = load double, double* %43
%45 = fcmp une double %42, %44
br i1 %45, label %46, label %47
46: ; preds = %40
store i32 0, i32* %5
br label %100
47: ; preds = %40
br label %48
48: ; preds = %47
%49 = load i32, i32* %10
%50 = add nsw i32 %49, 1
store i32 %50, i32* %10
%51 = load double*, double** %8
%52 = getelementptr inbounds double, double* %51, i32 1
store double* %52, double** %8
%53 = load double*, double** %9
%54 = getelementptr inbounds double, double* %53, i32 1
store double* %54, double** %9
br label %36
55: ; preds = %36
br label %99
56: ; preds = %32
store i32 0, i32* %10
br label %57
57: ; preds = %91, %56
%58 = load i32, i32* %10
%59 = load i32, i32* %6
%60 = icmp slt i32 %58, %59
br i1 %60, label %61, label %98
61: ; preds = %57
%62 = load double*, double** %8
%63 = load double, double* %62
%64 = fcmp oeq double %63, 0x565AEA1D6E56E1C8
br i1 %64, label %65, label %70
65: ; preds = %61
%66 = load double*, double** %9
%67 = load double, double* %66
%68 = fcmp une double %67, 0x565AEA1D6E56E1C8
br i1 %68, label %69, label %70
69: ; preds = %65
store i32 0, i32* %5
br label %100
70: ; preds = %65, %61
%71 = load double*, double** %8
%72 = load double, double* %71
%73 = fcmp une double %72, 0x565AEA1D6E56E1C8
br i1 %73, label %74, label %79
74: ; preds = %70
%75 = load double*, double** %9
%76 = load double, double* %75
%77 = fcmp oeq double %76, 0x565AEA1D6E56E1C8
br i1 %77, label %78, label %79
78: ; preds = %74
store i32 0, i32* %5
br label %100
79: ; preds = %74, %70
%80 = load double*, double** %8
%81 = load double, double* %80
%82 = load double*, double** %9
%83 = load double, double* %82
%84 = fsub double %81, %83
%85 = call double @llvm.fabs.f64(double %84)
%86 = load double, double* %7
%87 = fmul double 5.000000e-01, %86
%88 = fcmp ogt double %85, %87
br i1 %88, label %89, label %90
89: ; preds = %79
store i32 0, i32* %5
br label %100
90: ; preds = %79
br label %91
91: ; preds = %90
%92 = load i32, i32* %10
%93 = add nsw i32 %92, 1
store i32 %93, i32* %10
%94 = load double*, double** %8
%95 = getelementptr inbounds double, double* %94, i32 1
store double* %95, double** %8
%96 = load double*, double** %9
%97 = getelementptr inbounds double, double* %96, i32 1
store double* %97, double** %9
br label %57
98: ; preds = %57
br label %99
99: ; preds = %98, %55
store i32 1, i32* %5
br label %100
100: ; preds = %99, %89, %78, %69, %46, %31, %24, %17, %13
%101 = load i32, i32* %5
ret i32 %101
}

LLVM IR (-O2):
define i32 @wcsutil_Eq(i32 %0, double %1, double* %2, double* %3) {
%5 = icmp eq i32 %0, 0
br i1 %5, label %53, label %6
6: ; preds = %4
%7 = icmp slt i32 %0, 0
br i1 %7, label %53, label %8
8: ; preds = %6
%9 = icmp eq double* %2, null
%10 = icmp eq double* %3, null
%11 = and i1 %9, %10
br i1 %11, label %53, label %12
12: ; preds = %8
%13 = or i1 %9, %10
br i1 %13, label %53, label %14
14: ; preds = %12
%15 = fcmp oeq double %1, 0.000000e+00
br i1 %15, label %18, label %16
16: ; preds = %14
%17 = fmul double %1, 5.000000e-01
br label %30
18: ; preds = %14, %25
%19 = phi i32 [ %26, %25 ], [ 0, %14 ]
%20 = phi double* [ %28, %25 ], [ %3, %14 ]
%21 = phi double* [ %27, %25 ], [ %2, %14 ]
%22 = load double, double* %21
%23 = load double, double* %20
%24 = fcmp une double %22, %23
br i1 %24, label %53, label %25
25: ; preds = %18
%26 = add nuw nsw i32 %19, 1
%27 = getelementptr inbounds double, double* %21, i64 1
%28 = getelementptr inbounds double, double* %20, i64 1
%29 = icmp eq i32 %26, %0
br i1 %29, label %53, label %18
30: ; preds = %16, %48
%31 = phi i32 [ 0, %16 ], [ %49, %48 ]
%32 = phi double* [ %3, %16 ], [ %51, %48 ]
%33 = phi double* [ %2, %16 ], [ %50, %48 ]
%34 = load double, double* %33
%35 = fcmp oeq double %34, 0x565AEA1D6E56E1C8
br i1 %35, label %36, label %39
36: ; preds = %30
%37 = load double, double* %32
%38 = fcmp une double %37, 0x565AEA1D6E56E1C8
br i1 %38, label %53, label %39
39: ; preds = %36, %30
%40 = fcmp une double %34, 0x565AEA1D6E56E1C8
%41 = load double, double* %32
%42 = fcmp oeq double %41, 0x565AEA1D6E56E1C8
%43 = select i1 %40, i1 %42, i1 false
br i1 %43, label %53, label %44
44: ; preds = %39
%45 = fsub double %34, %41
%46 = tail call double @llvm.fabs.f64(double %45)
%47 = fcmp ogt double %46, %17
br i1 %47, label %53, label %48
48: ; preds = %44
%49 = add nuw nsw i32 %31, 1
%50 = getelementptr inbounds double, double* %33, i64 1
%51 = getelementptr inbounds double, double* %32, i64 1
%52 = icmp eq i32 %49, %0
br i1 %52, label %53, label %30
53: ; preds = %36, %44, %48, %39, %18, %25, %12, %8, %6, %4
%54 = phi i32 [ 1, %4 ], [ 0, %6 ], [ 1, %8 ], [ 0, %12 ], [ 0, %18 ], [ 1, %25 ], [ 0, %36 ], [ 0, %44 ], [ 1, %48 ], [ 0, %39 ]
ret i32 %54
}