#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 */
double sqrt(double);
double calc_sol_residual_norm(int Dim, const double *G, const double *V1,
                              const double *V2, const double *G_prev,
                              const double *V1_prev, const double *V2_prev) {
  int m;
  double norm = 0.;
  double tmp_1, tmp_2, tmp_3;
  for (m = 0; m < Dim; m++) {
    tmp_1 = G[m] - G_prev[m];
    tmp_2 = V1[m] - V1_prev[m];
    tmp_3 = V2[m] - V2_prev[m];
    norm += tmp_1 * tmp_1 + tmp_2 * tmp_2 + tmp_3 * tmp_3;
  }
  return sqrt(norm / (3 * Dim));
}


x86 assembly (clang, -O0):
<calc_sol_residual_norm>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    0x10(%rbp),%rax
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11f1 <calc_sol_residual_norm+0xe1>
mov    -0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x34(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x34(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    0x10(%rbp),%rax
movslq -0x34(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x48(%rbp),%xmm1
movsd  -0x48(%rbp),%xmm2
movsd  -0x50(%rbp),%xmm0
mulsd  -0x50(%rbp),%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
movsd  -0x58(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1142 <calc_sol_residual_norm+0x32>
movsd  -0x40(%rbp),%xmm0
imul   $0x3,-0x4(%rbp),%eax
cvtsi2sd %eax,%xmm1
divsd  %xmm1,%xmm0
call   1030 <sqrt@plt>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<calc_sol_residual_norm>:
xorpd  %xmm1,%xmm1
xorpd  %xmm0,%xmm0
test   %edi,%edi
jle    1172 <calc_sol_residual_norm+0x62>
mov    0x8(%rsp),%r10
mov    %edi,%r11d
xorpd  %xmm0,%xmm0
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movsd  (%rsi,%rax,8),%xmm2
subsd  (%r8,%rax,8),%xmm2
movsd  (%rdx,%rax,8),%xmm3
subsd  (%r9,%rax,8),%xmm3
movsd  (%rcx,%rax,8),%xmm4
subsd  (%r10,%rax,8),%xmm4
mulsd  %xmm3,%xmm3
mulsd  %xmm2,%xmm2
addsd  %xmm3,%xmm2
mulsd  %xmm4,%xmm4
addsd  %xmm2,%xmm4
addsd  %xmm4,%xmm0
add    $0x1,%rax
cmp    %rax,%r11
jne    1130 <calc_sol_residual_norm+0x20>
lea    (%rdi,%rdi,2),%eax
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
divsd  %xmm2,%xmm0
ucomisd %xmm1,%xmm0
jb     118b <calc_sol_residual_norm+0x7b>
sqrtsd %xmm0,%xmm0
ret
jmp    1030 <sqrt@plt>

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

LLVM IR (-O2):
define double @calc_sol_residual_norm(i32 %0, double* nocapture %1, double* nocapture %2, double* nocapture %3, double* nocapture %4, double* nocapture %5, double* nocapture %6) {
%8 = icmp sgt i32 %0, 0
br i1 %8, label %9, label %35
9: ; preds = %7
%10 = zext i32 %0 to i64
br label %11
11: ; preds = %9, %11
%12 = phi i64 [ 0, %9 ], [ %33, %11 ]
%13 = phi double [ 0.000000e+00, %9 ], [ %32, %11 ]
%14 = getelementptr inbounds double, double* %1, i64 %12
%15 = load double, double* %14
%16 = getelementptr inbounds double, double* %4, i64 %12
%17 = load double, double* %16
%18 = fsub double %15, %17
%19 = getelementptr inbounds double, double* %2, i64 %12
%20 = load double, double* %19
%21 = getelementptr inbounds double, double* %5, i64 %12
%22 = load double, double* %21
%23 = fsub double %20, %22
%24 = getelementptr inbounds double, double* %3, i64 %12
%25 = load double, double* %24
%26 = getelementptr inbounds double, double* %6, i64 %12
%27 = load double, double* %26
%28 = fsub double %25, %27
%29 = fmul double %23, %23
%30 = tail call double @llvm.fmuladd.f64(double %18, double %18, double %29)
%31 = tail call double @llvm.fmuladd.f64(double %28, double %28, double %30)
%32 = fadd double %13, %31
%33 = add nuw nsw i64 %12, 1
%34 = icmp eq i64 %33, %10
br i1 %34, label %35, label %11
35: ; preds = %11, %7
%36 = phi double [ 0.000000e+00, %7 ], [ %32, %11 ]
%37 = mul nsw i32 %0, 3
%38 = sitofp i32 %37 to double
%39 = fdiv double %36, %38
%40 = tail call double @sqrt(double %39)
ret double %40
}