#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 relative_norm(double *N, double *D, int n) {
  double nN = 0.0, nD = 0.0;
  int i;
  for (i = 1; i <= n; i++)
    nN += (N[i] * N[i]);
  for (i = 1; i <= n; i++)
    nD += (D[i] * D[i]);
  return (sqrt(nN) / sqrt(nD));
}


x86 assembly (clang, -O0):
<relative_norm>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     1180 <relative_norm+0x70>
mov    -0x8(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x20(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    113a <relative_norm+0x2a>
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     11cd <relative_norm+0xbd>
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1187 <relative_norm+0x77>
movsd  -0x20(%rbp),%xmm0
call   1030 <sqrt@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  -0x28(%rbp),%xmm0
call   1030 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
divsd  %xmm1,%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<relative_norm>:
push   %rax
xorpd  %xmm1,%xmm1
xorpd  %xmm0,%xmm0
xorpd  %xmm4,%xmm4
test   %edx,%edx
jle    1266 <relative_norm+0x156>
mov    %edx,%r9d
lea    -0x1(%r9),%r8
mov    %r9d,%r10d
and    $0x3,%r10d
cmp    $0x3,%r8
jae    114c <relative_norm+0x3c>
xorpd  %xmm0,%xmm0
mov    $0x1,%ecx
test   %r10,%r10
jne    11aa <relative_norm+0x9a>
jmp    11c6 <relative_norm+0xb6>
mov    %r9d,%eax
and    $0xfffffffc,%eax
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
movsd  0x8(%rdi,%rcx,8),%xmm2
movsd  0x10(%rdi,%rcx,8),%xmm3
mulsd  %xmm2,%xmm2
addsd  %xmm0,%xmm2
mulsd  %xmm3,%xmm3
addsd  %xmm2,%xmm3
movsd  0x18(%rdi,%rcx,8),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm3,%xmm2
movsd  0x20(%rdi,%rcx,8),%xmm0
mulsd  %xmm0,%xmm0
addsd  %xmm2,%xmm0
add    $0x4,%rcx
cmp    %rcx,%rax
jne    1160 <relative_norm+0x50>
add    $0x1,%rcx
test   %r10,%r10
je     11c6 <relative_norm+0xb6>
lea    (%rdi,%rcx,8),%rax
xor    %ecx,%ecx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm2,%xmm0
add    $0x1,%rcx
cmp    %rcx,%r10
jne    11b0 <relative_norm+0xa0>
test   %edx,%edx
jle    11e9 <relative_norm+0xd9>
mov    %r9d,%eax
and    $0x3,%eax
cmp    $0x3,%r8
jae    11ef <relative_norm+0xdf>
xorpd  %xmm4,%xmm4
mov    $0x1,%ecx
test   %rax,%rax
jne    124a <relative_norm+0x13a>
jmp    1266 <relative_norm+0x156>
xorpd  %xmm4,%xmm4
jmp    1266 <relative_norm+0x156>
and    $0xfffffffc,%r9d
xorpd  %xmm4,%xmm4
xor    %ecx,%ecx
nopl   0x0(%rax)
movsd  0x8(%rsi,%rcx,8),%xmm2
movsd  0x10(%rsi,%rcx,8),%xmm3
mulsd  %xmm2,%xmm2
addsd  %xmm4,%xmm2
mulsd  %xmm3,%xmm3
addsd  %xmm2,%xmm3
movsd  0x18(%rsi,%rcx,8),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm3,%xmm2
movsd  0x20(%rsi,%rcx,8),%xmm4
mulsd  %xmm4,%xmm4
addsd  %xmm2,%xmm4
add    $0x4,%rcx
cmp    %rcx,%r9
jne    1200 <relative_norm+0xf0>
add    $0x1,%rcx
test   %rax,%rax
je     1266 <relative_norm+0x156>
lea    (%rsi,%rcx,8),%rcx
xor    %edx,%edx
movsd  (%rcx,%rdx,8),%xmm2
mulsd  %xmm2,%xmm2
addsd  %xmm2,%xmm4
add    $0x1,%rdx
cmp    %rdx,%rax
jne    1250 <relative_norm+0x140>
ucomisd %xmm1,%xmm0
jb     1275 <relative_norm+0x165>
xorps  %xmm1,%xmm1
sqrtsd %xmm0,%xmm1
jmp    1288 <relative_norm+0x178>
movsd  %xmm4,(%rsp)
call   1030 <sqrt@plt>
movsd  (%rsp),%xmm4
movapd %xmm0,%xmm1
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm4
jb     129b <relative_norm+0x18b>
xorps  %xmm0,%xmm0
sqrtsd %xmm4,%xmm0
jmp    12ae <relative_norm+0x19e>
movapd %xmm4,%xmm0
movsd  %xmm1,(%rsp)
call   1030 <sqrt@plt>
movsd  (%rsp),%xmm1
divsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
pop    %rax
ret

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

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