#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 fabs(double);
double vec3_mag(double *);
void vec3_norm(double *a) {
  double __mag = vec3_mag(a);
  if (fabs(__mag) < 0.001) {
    a[0] = __mag;
    a[1] = __mag;
    a[2] = __mag;
    return;
  }
  a[0] /= __mag;
  a[1] /= __mag;
  a[2] /= __mag;
  return;
}


x86 assembly (clang, -O0):
<vec3_norm>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <vec3_mag@plt>
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm1
movaps 0xeda(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  0xebe(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    117a <vec3_norm+0x6a>
movsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,0x10(%rax)
jmp    11bd <vec3_norm+0xad>
movsd  -0x10(%rbp),%xmm1
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rax)
movsd  -0x10(%rbp),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,0x10(%rax)
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vec3_norm>:
push   %rbx
mov    %rdi,%rbx
call   1030 <vec3_mag@plt>
movapd 0xedf(%rip),%xmm1
andpd  %xmm0,%xmm1
movsd  0xee3(%rip),%xmm2
ucomisd %xmm1,%xmm2
jbe    1143 <vec3_norm+0x33>
movsd  %xmm0,(%rbx)
movsd  %xmm0,0x8(%rbx)
movsd  %xmm0,0x10(%rbx)
pop    %rbx
ret
movupd (%rbx),%xmm1
movapd %xmm0,%xmm2
unpcklpd %xmm0,%xmm2
divpd  %xmm2,%xmm1
movupd %xmm1,(%rbx)
movsd  0x10(%rbx),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x10(%rbx)
pop    %rbx
ret

LLVM IR (-O0):
define void @vec3_norm(double* %0) {
%2 = alloca double*
%3 = alloca double
store double* %0, double** %2
%4 = load double*, double** %2
%5 = call double @vec3_mag(double* %4)
store double %5, double* %3
%6 = load double, double* %3
%7 = call double @llvm.fabs.f64(double %6)
%8 = fcmp olt double %7, 1.000000e-03
br i1 %8, label %9, label %19
9: ; preds = %1
%10 = load double, double* %3
%11 = load double*, double** %2
%12 = getelementptr inbounds double, double* %11, i64 0
store double %10, double* %12
%13 = load double, double* %3
%14 = load double*, double** %2
%15 = getelementptr inbounds double, double* %14, i64 1
store double %13, double* %15
%16 = load double, double* %3
%17 = load double*, double** %2
%18 = getelementptr inbounds double, double* %17, i64 2
store double %16, double* %18
br label %35
19: ; preds = %1
%20 = load double, double* %3
%21 = load double*, double** %2
%22 = getelementptr inbounds double, double* %21, i64 0
%23 = load double, double* %22
%24 = fdiv double %23, %20
store double %24, double* %22
%25 = load double, double* %3
%26 = load double*, double** %2
%27 = getelementptr inbounds double, double* %26, i64 1
%28 = load double, double* %27
%29 = fdiv double %28, %25
store double %29, double* %27
%30 = load double, double* %3
%31 = load double*, double** %2
%32 = getelementptr inbounds double, double* %31, i64 2
%33 = load double, double* %32
%34 = fdiv double %33, %30
store double %34, double* %32
br label %35
35: ; preds = %19, %9
ret void
}

LLVM IR (-O2):
define void @vec3_norm(double* %0) {
%2 = tail call double @vec3_mag(double* %0)
%3 = tail call double @llvm.fabs.f64(double %2)
%4 = fcmp olt double %3, 1.000000e-03
br i1 %4, label %5, label %8
5: ; preds = %1
store double %2, double* %0
%6 = getelementptr inbounds double, double* %0, i64 1
store double %2, double* %6
%7 = getelementptr inbounds double, double* %0, i64 2
store double %2, double* %7
br label %18
8: ; preds = %1
%9 = bitcast double* %0 to <2 x double>*
%10 = load <2 x double>, <2 x double>* %9
%11 = insertelement <2 x double> poison, double %2, i64 0
%12 = shufflevector <2 x double> %11, <2 x double> poison, <2 x i32> zeroinitializer
%13 = fdiv <2 x double> %10, %12
%14 = bitcast double* %0 to <2 x double>*
store <2 x double> %13, <2 x double>* %14
%15 = getelementptr inbounds double, double* %0, i64 2
%16 = load double, double* %15
%17 = fdiv double %16, %2
store double %17, double* %15
br label %18
18: ; preds = %8, %5
ret void
}