#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 abs(int);
double fabs(double);
double dget_max_error(double *ref, double *res, int n, int inc) {
  int i;
  double max_err = -1.0;
  double err = -1.0;
  inc = abs(inc);
  for (i = 0; i < n; i++) {
    err = fabs(res[i * inc] - ref[i * inc]);
    if (ref[i * inc] != 0.0)
      err /= fabs(ref[i * inc]);
    if (err > max_err)
      max_err = err;
  }
  return max_err;
}


x86 assembly (clang, -O0):
<dget_max_error>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
movsd  0xed2(%rip),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xec5(%rip),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x18(%rbp),%edi
call   1030 <abs@plt>
mov    %eax,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1218 <dget_max_error+0x108>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
imul   -0x18(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
imul   -0x18(%rbp),%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
movaps 0xe85(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
imul   -0x18(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    11bf <dget_max_error+0xaf>
jp     11bf <dget_max_error+0xaf>
jmp    11eb <dget_max_error+0xdb>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
imul   -0x18(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm1
movaps 0xe37(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
ucomisd -0x28(%rbp),%xmm0
jbe    1205 <dget_max_error+0xf5>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    120a <dget_max_error+0xfa>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1152 <dget_max_error+0x42>
movsd  -0x28(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dget_max_error>:
test   %edx,%edx
jle    1164 <dget_max_error+0x64>
mov    %ecx,%r8d
neg    %r8d
cmovs  %ecx,%r8d
mov    %edx,%ecx
movsd  0xee8(%rip),%xmm3
xor    %edx,%edx
movapd 0xeee(%rip),%xmm1
xorpd  %xmm2,%xmm2
jmp    1145 <dget_max_error+0x45>
nopl   0x0(%rax,%rax,1)
andpd  %xmm1,%xmm0
maxsd  %xmm3,%xmm0
add    %r8d,%edx
movapd %xmm0,%xmm3
add    $0xffffffffffffffff,%rcx
je     1163 <dget_max_error+0x63>
mov    %edx,%eax
movsd  (%rsi,%rax,8),%xmm0
movsd  (%rdi,%rax,8),%xmm4
subsd  %xmm4,%xmm0
ucomisd %xmm2,%xmm4
jne    115d <dget_max_error+0x5d>
jnp    1130 <dget_max_error+0x30>
divsd  %xmm4,%xmm0
jmp    1130 <dget_max_error+0x30>
ret
movsd  0xe94(%rip),%xmm0
ret

LLVM IR (-O0):
define double @dget_max_error(double* %0, double* %1, i32 %2, i32 %3) {
%5 = alloca double*
%6 = alloca double*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca double
%11 = alloca double
store double* %0, double** %5
store double* %1, double** %6
store i32 %2, i32* %7
store i32 %3, i32* %8
store double -1.000000e+00, double* %10
store double -1.000000e+00, double* %11
%12 = load i32, i32* %8
%13 = call i32 @abs(i32 %12)
store i32 %13, i32* %8
store i32 0, i32* %9
br label %14
14: ; preds = %61, %4
%15 = load i32, i32* %9
%16 = load i32, i32* %7
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %64
18: ; preds = %14
%19 = load double*, double** %6
%20 = load i32, i32* %9
%21 = load i32, i32* %8
%22 = mul nsw i32 %20, %21
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds double, double* %19, i64 %23
%25 = load double, double* %24
%26 = load double*, double** %5
%27 = load i32, i32* %9
%28 = load i32, i32* %8
%29 = mul nsw i32 %27, %28
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds double, double* %26, i64 %30
%32 = load double, double* %31
%33 = fsub double %25, %32
%34 = call double @llvm.fabs.f64(double %33)
store double %34, double* %11
%35 = load double*, double** %5
%36 = load i32, i32* %9
%37 = load i32, i32* %8
%38 = mul nsw i32 %36, %37
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds double, double* %35, i64 %39
%41 = load double, double* %40
%42 = fcmp une double %41, 0.000000e+00
br i1 %42, label %43, label %54
43: ; preds = %18
%44 = load double*, double** %5
%45 = load i32, i32* %9
%46 = load i32, i32* %8
%47 = mul nsw i32 %45, %46
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds double, double* %44, i64 %48
%50 = load double, double* %49
%51 = call double @llvm.fabs.f64(double %50)
%52 = load double, double* %11
%53 = fdiv double %52, %51
store double %53, double* %11
br label %54
54: ; preds = %43, %18
%55 = load double, double* %11
%56 = load double, double* %10
%57 = fcmp ogt double %55, %56
br i1 %57, label %58, label %60
58: ; preds = %54
%59 = load double, double* %11
store double %59, double* %10
br label %60
60: ; preds = %58, %54
br label %61
61: ; preds = %60
%62 = load i32, i32* %9
%63 = add nsw i32 %62, 1
store i32 %63, i32* %9
br label %14
64: ; preds = %14
%65 = load double, double* %10
ret double %65
}

LLVM IR (-O2):
define double @dget_max_error(double* nocapture %0, double* nocapture %1, i32 %2, i32 %3) {
%5 = icmp sgt i32 %2, 0
br i1 %5, label %6, label %31
6: ; preds = %4
%7 = tail call i32 @llvm.abs.i32(i32 %3, i1 true)
%8 = zext i32 %2 to i64
br label %9
9: ; preds = %6, %25
%10 = phi i64 [ 0, %6 ], [ %29, %25 ]
%11 = phi double [ -1.000000e+00, %6 ], [ %28, %25 ]
%12 = trunc i64 %10 to i32
%13 = mul i32 %7, %12
%14 = zext i32 %13 to i64
%15 = getelementptr inbounds double, double* %1, i64 %14
%16 = load double, double* %15
%17 = getelementptr inbounds double, double* %0, i64 %14
%18 = load double, double* %17
%19 = fsub double %16, %18
%20 = tail call double @llvm.fabs.f64(double %19)
%21 = fcmp une double %18, 0.000000e+00
br i1 %21, label %22, label %25
22: ; preds = %9
%23 = fdiv double %19, %18
%24 = tail call double @llvm.fabs.f64(double %23)
br label %25
25: ; preds = %22, %9
%26 = phi double [ %24, %22 ], [ %20, %9 ]
%27 = fcmp ogt double %26, %11
%28 = select i1 %27, double %26, double %11
%29 = add nuw nsw i64 %10, 1
%30 = icmp eq i64 %29, %8
br i1 %30, label %31, label %9
31: ; preds = %25, %4
%32 = phi double [ -1.000000e+00, %4 ], [ %28, %25 ]
ret double %32
}