#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 /*<<< orphan*/ calculate_residuals(double **, double **, double **, int,
                                       int, double, double);
double fabs(double);
double max_residual_norm(double **RES, double **P, double **RHS, int nx, int ny,
                         double dx, double dy) {
  int i, j;
  double val;
  double max = -1.0e9;
  calculate_residuals(RES, P, RHS, nx, ny, dx, dy);
  for (i = 1; i <= nx; i++) {
    for (j = 1; j <= ny; j++) {
      val = fabs(RES[i][j]);
      if (val > max)
        max = val;
    }
  }
  return max;
}


x86 assembly (clang, -O0):
<max_residual_norm>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
movsd  %xmm0,-0x28(%rbp)
movsd  %xmm1,-0x30(%rbp)
movsd  0xec3(%rip),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    -0x1c(%rbp),%ecx
mov    -0x20(%rbp),%r8d
movsd  -0x28(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm1
call   1030 <calculate_residuals@plt>
movl   $0x1,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jg     11ef <max_residual_norm+0xdf>
movl   $0x1,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x20(%rbp),%eax
jg     11dc <max_residual_norm+0xcc>
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movaps 0xe6a(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
ucomisd -0x48(%rbp),%xmm0
jbe    11c9 <max_residual_norm+0xb9>
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    11ce <max_residual_norm+0xbe>
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    117e <max_residual_norm+0x6e>
jmp    11e1 <max_residual_norm+0xd1>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    116b <max_residual_norm+0x5b>
movsd  -0x48(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<max_residual_norm>:
push   %r15
push   %r14
push   %rbx
mov    %r8d,%r14d
mov    %ecx,%ebx
mov    %rdi,%r15
call   1030 <calculate_residuals@plt>
test   %ebx,%ebx
jle    121f <max_residual_norm+0x10f>
lea    0x1(%r14),%r8d
add    $0x1,%ebx
lea    -0x1(%r8),%rcx
add    $0xfffffffffffffffe,%r8
mov    %ecx,%edx
and    $0x3,%edx
and    $0xfffffffffffffffc,%rcx
movsd  0xeb6(%rip),%xmm3
mov    $0x1,%esi
movapd 0xeb9(%rip),%xmm1
movapd 0xeb1(%rip),%xmm2
jmp    1185 <max_residual_norm+0x75>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movapd %xmm3,%xmm0
add    $0x1,%rsi
movapd %xmm0,%xmm3
cmp    %rbx,%rsi
je     1227 <max_residual_norm+0x117>
test   %r14d,%r14d
jle    1170 <max_residual_norm+0x60>
mov    (%r15,%rsi,8),%rdi
mov    $0x1,%eax
cmp    $0x3,%r8
jb     11e5 <max_residual_norm+0xd5>
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
movsd  0x8(%rdi,%rax,8),%xmm0
movsd  0x10(%rdi,%rax,8),%xmm4
movsd  0x18(%rdi,%rax,8),%xmm5
andpd  %xmm2,%xmm0
maxsd  %xmm3,%xmm0
movsd  0x20(%rdi,%rax,8),%xmm3
andpd  %xmm2,%xmm4
maxsd  %xmm0,%xmm4
andpd  %xmm2,%xmm5
maxsd  %xmm4,%xmm5
andpd  %xmm2,%xmm3
maxsd  %xmm5,%xmm3
add    $0x4,%rax
cmp    %rax,%rcx
jne    11a0 <max_residual_norm+0x90>
add    $0x1,%rax
movapd %xmm3,%xmm0
test   %rdx,%rdx
je     1174 <max_residual_norm+0x64>
lea    (%rdi,%rax,8),%rax
xor    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movsd  (%rax,%rdi,8),%xmm0
andpd  %xmm1,%xmm0
maxsd  %xmm3,%xmm0
add    $0x1,%rdi
movapd %xmm0,%xmm3
cmp    %rdi,%rdx
jne    1200 <max_residual_norm+0xf0>
jmp    1174 <max_residual_norm+0x64>
movsd  0xdd9(%rip),%xmm0
pop    %rbx
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
define double @max_residual_norm(double** %0, double** %1, double** %2, i32 %3, i32 %4, double %5, double %6) {
%8 = tail call i32 @calculate_residuals(double** %0, double** %1, double** %2, i32 %3, i32 %4, double %5, double %6)
%9 = icmp slt i32 %3, 1
br i1 %9, label %78, label %10
10: ; preds = %7
%11 = icmp slt i32 %4, 1
%12 = add i32 %4, 1
%13 = add nuw i32 %3, 1
%14 = zext i32 %13 to i64
%15 = zext i32 %12 to i64
%16 = add nsw i64 %15, -1
%17 = add nsw i64 %15, -2
%18 = and i64 %16, 3
%19 = icmp ult i64 %17, 3
%20 = and i64 %16, -4
%21 = icmp eq i64 %18, 0
br label %22
22: ; preds = %10, %74
%23 = phi i64 [ 1, %10 ], [ %76, %74 ]
%24 = phi double [ -1.000000e+09, %10 ], [ %75, %74 ]
br i1 %11, label %74, label %25
25: ; preds = %22
%26 = getelementptr inbounds double*, double** %0, i64 %23
%27 = load double*, double** %26
br i1 %19, label %58, label %28
28: ; preds = %25, %28
%29 = phi i64 [ %55, %28 ], [ 1, %25 ]
%30 = phi double [ %54, %28 ], [ %24, %25 ]
%31 = phi i64 [ %56, %28 ], [ 0, %25 ]
%32 = getelementptr inbounds double, double* %27, i64 %29
%33 = load double, double* %32
%34 = tail call double @llvm.fabs.f64(double %33)
%35 = fcmp ogt double %34, %30
%36 = select i1 %35, double %34, double %30
%37 = add nuw nsw i64 %29, 1
%38 = getelementptr inbounds double, double* %27, i64 %37
%39 = load double, double* %38
%40 = tail call double @llvm.fabs.f64(double %39)
%41 = fcmp ogt double %40, %36
%42 = select i1 %41, double %40, double %36
%43 = add nuw nsw i64 %29, 2
%44 = getelementptr inbounds double, double* %27, i64 %43
%45 = load double, double* %44
%46 = tail call double @llvm.fabs.f64(double %45)
%47 = fcmp ogt double %46, %42
%48 = select i1 %47, double %46, double %42
%49 = add nuw nsw i64 %29, 3
%50 = getelementptr inbounds double, double* %27, i64 %49
%51 = load double, double* %50
%52 = tail call double @llvm.fabs.f64(double %51)
%53 = fcmp ogt double %52, %48
%54 = select i1 %53, double %52, double %48
%55 = add nuw nsw i64 %29, 4
%56 = add i64 %31, 4
%57 = icmp eq i64 %56, %20
br i1 %57, label %58, label %28
58: ; preds = %28, %25
%59 = phi double [ undef, %25 ], [ %54, %28 ]
%60 = phi i64 [ 1, %25 ], [ %55, %28 ]
%61 = phi double [ %24, %25 ], [ %54, %28 ]
br i1 %21, label %74, label %62
62: ; preds = %58, %62
%63 = phi i64 [ %71, %62 ], [ %60, %58 ]
%64 = phi double [ %70, %62 ], [ %61, %58 ]
%65 = phi i64 [ %72, %62 ], [ 0, %58 ]
%66 = getelementptr inbounds double, double* %27, i64 %63
%67 = load double, double* %66
%68 = tail call double @llvm.fabs.f64(double %67)
%69 = fcmp ogt double %68, %64
%70 = select i1 %69, double %68, double %64
%71 = add nuw nsw i64 %63, 1
%72 = add i64 %65, 1
%73 = icmp eq i64 %72, %18
br i1 %73, label %74, label %62
74: ; preds = %58, %62, %22
%75 = phi double [ %24, %22 ], [ %59, %58 ], [ %70, %62 ]
%76 = add nuw nsw i64 %23, 1
%77 = icmp eq i64 %76, %14
br i1 %77, label %78, label %22
78: ; preds = %74, %7
%79 = phi double [ -1.000000e+09, %7 ], [ %75, %74 ]
ret double %79
}