#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*/ vector3d_add(float *, float *, float *);
int /*<<< orphan*/ vector3d_cross(float *, float *, float *);
float vector3d_dot(float *, float *);
int /*<<< orphan*/ vector3d_normalize(float *);
int /*<<< orphan*/ vector3d_scale(float, float *, float *);
void dcm_orthonormalize(float dcm[3][3]) {
  float err = vector3d_dot((float *)(dcm[0]), (float *)(dcm[1]));
  float delta[2][3];
  vector3d_scale(-err / 2, (float *)(dcm[1]), (float *)(delta[0]));
  vector3d_scale(-err / 2, (float *)(dcm[0]), (float *)(delta[1]));
  vector3d_add((float *)(dcm[0]), (float *)(delta[0]), (float *)(dcm[0]));
  vector3d_add((float *)(dcm[1]), (float *)(delta[1]), (float *)(dcm[1]));
  vector3d_cross((float *)(dcm[0]), (float *)(dcm[1]), (float *)(dcm[2]));
  vector3d_normalize((float *)(dcm[0]));
  vector3d_normalize((float *)(dcm[1]));
  vector3d_normalize((float *)(dcm[2]));
}


x86 assembly (clang, -O0):
<dcm_orthonormalize>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x8(%rbp),%rsi
add    $0xc,%rsi
call   1030 <vector3d_dot@plt>
movss  %xmm0,-0xc(%rbp)
movss  -0xc(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  0xe74(%rip),%xmm1
divss  %xmm1,%xmm0
mov    -0x8(%rbp),%rdi
add    $0xc,%rdi
lea    -0x30(%rbp),%rsi
call   1050 <vector3d_scale@plt>
movss  -0xc(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  0xe45(%rip),%xmm1
divss  %xmm1,%xmm0
mov    -0x8(%rbp),%rdi
lea    -0x30(%rbp),%rsi
add    $0xc,%rsi
call   1050 <vector3d_scale@plt>
mov    -0x8(%rbp),%rdi
lea    -0x30(%rbp),%rsi
mov    -0x8(%rbp),%rdx
call   1040 <vector3d_add@plt>
mov    -0x8(%rbp),%rdi
add    $0xc,%rdi
lea    -0x30(%rbp),%rsi
add    $0xc,%rsi
mov    -0x8(%rbp),%rdx
add    $0xc,%rdx
call   1040 <vector3d_add@plt>
mov    -0x8(%rbp),%rdi
mov    -0x8(%rbp),%rsi
add    $0xc,%rsi
mov    -0x8(%rbp),%rdx
add    $0x18,%rdx
call   1070 <vector3d_cross@plt>
mov    -0x8(%rbp),%rdi
call   1060 <vector3d_normalize@plt>
mov    -0x8(%rbp),%rdi
add    $0xc,%rdi
call   1060 <vector3d_normalize@plt>
mov    -0x8(%rbp),%rdi
add    $0x18,%rdi
call   1060 <vector3d_normalize@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dcm_orthonormalize>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rdi,%rbx
lea    0xc(%rdi),%r14
mov    %r14,%rsi
call   1030 <vector3d_dot@plt>
mulss  0xe8e(%rip),%xmm0
movss  %xmm0,0xc(%rsp)
lea    0x10(%rsp),%r15
mov    %r14,%rdi
mov    %r15,%rsi
call   1050 <vector3d_scale@plt>
lea    0x1c(%rsp),%r12
movss  0xc(%rsp),%xmm0
mov    %rbx,%rdi
mov    %r12,%rsi
call   1050 <vector3d_scale@plt>
mov    %rbx,%rdi
mov    %r15,%rsi
mov    %rbx,%rdx
call   1040 <vector3d_add@plt>
mov    %r14,%rdi
mov    %r12,%rsi
mov    %r14,%rdx
call   1040 <vector3d_add@plt>
lea    0x18(%rbx),%r15
mov    %rbx,%rdi
mov    %r14,%rsi
mov    %r15,%rdx
call   1070 <vector3d_cross@plt>
mov    %rbx,%rdi
call   1060 <vector3d_normalize@plt>
mov    %r14,%rdi
call   1060 <vector3d_normalize@plt>
mov    %r15,%rdi
call   1060 <vector3d_normalize@plt>
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @dcm_orthonormalize([3 x float]* %0) {
%2 = alloca [3 x float]*
%3 = alloca float
%4 = alloca [2 x [3 x float]]
store [3 x float]* %0, [3 x float]** %2
%5 = load [3 x float]*, [3 x float]** %2
%6 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0
%7 = getelementptr inbounds [3 x float], [3 x float]* %6, i64 0, i64 0
%8 = load [3 x float]*, [3 x float]** %2
%9 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 1
%10 = getelementptr inbounds [3 x float], [3 x float]* %9, i64 0, i64 0
%11 = call float @vector3d_dot(float* %7, float* %10)
store float %11, float* %3
%12 = load float, float* %3
%13 = fneg float %12
%14 = fdiv float %13, 2.000000e+00
%15 = load [3 x float]*, [3 x float]** %2
%16 = getelementptr inbounds [3 x float], [3 x float]* %15, i64 1
%17 = getelementptr inbounds [3 x float], [3 x float]* %16, i64 0, i64 0
%18 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %4, i64 0, i64 0
%19 = getelementptr inbounds [3 x float], [3 x float]* %18, i64 0, i64 0
%20 = call i32 @vector3d_scale(float %14, float* %17, float* %19)
%21 = load float, float* %3
%22 = fneg float %21
%23 = fdiv float %22, 2.000000e+00
%24 = load [3 x float]*, [3 x float]** %2
%25 = getelementptr inbounds [3 x float], [3 x float]* %24, i64 0
%26 = getelementptr inbounds [3 x float], [3 x float]* %25, i64 0, i64 0
%27 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %4, i64 0, i64 1
%28 = getelementptr inbounds [3 x float], [3 x float]* %27, i64 0, i64 0
%29 = call i32 @vector3d_scale(float %23, float* %26, float* %28)
%30 = load [3 x float]*, [3 x float]** %2
%31 = getelementptr inbounds [3 x float], [3 x float]* %30, i64 0
%32 = getelementptr inbounds [3 x float], [3 x float]* %31, i64 0, i64 0
%33 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %4, i64 0, i64 0
%34 = getelementptr inbounds [3 x float], [3 x float]* %33, i64 0, i64 0
%35 = load [3 x float]*, [3 x float]** %2
%36 = getelementptr inbounds [3 x float], [3 x float]* %35, i64 0
%37 = getelementptr inbounds [3 x float], [3 x float]* %36, i64 0, i64 0
%38 = call i32 @vector3d_add(float* %32, float* %34, float* %37)
%39 = load [3 x float]*, [3 x float]** %2
%40 = getelementptr inbounds [3 x float], [3 x float]* %39, i64 1
%41 = getelementptr inbounds [3 x float], [3 x float]* %40, i64 0, i64 0
%42 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %4, i64 0, i64 1
%43 = getelementptr inbounds [3 x float], [3 x float]* %42, i64 0, i64 0
%44 = load [3 x float]*, [3 x float]** %2
%45 = getelementptr inbounds [3 x float], [3 x float]* %44, i64 1
%46 = getelementptr inbounds [3 x float], [3 x float]* %45, i64 0, i64 0
%47 = call i32 @vector3d_add(float* %41, float* %43, float* %46)
%48 = load [3 x float]*, [3 x float]** %2
%49 = getelementptr inbounds [3 x float], [3 x float]* %48, i64 0
%50 = getelementptr inbounds [3 x float], [3 x float]* %49, i64 0, i64 0
%51 = load [3 x float]*, [3 x float]** %2
%52 = getelementptr inbounds [3 x float], [3 x float]* %51, i64 1
%53 = getelementptr inbounds [3 x float], [3 x float]* %52, i64 0, i64 0
%54 = load [3 x float]*, [3 x float]** %2
%55 = getelementptr inbounds [3 x float], [3 x float]* %54, i64 2
%56 = getelementptr inbounds [3 x float], [3 x float]* %55, i64 0, i64 0
%57 = call i32 @vector3d_cross(float* %50, float* %53, float* %56)
%58 = load [3 x float]*, [3 x float]** %2
%59 = getelementptr inbounds [3 x float], [3 x float]* %58, i64 0
%60 = getelementptr inbounds [3 x float], [3 x float]* %59, i64 0, i64 0
%61 = call i32 @vector3d_normalize(float* %60)
%62 = load [3 x float]*, [3 x float]** %2
%63 = getelementptr inbounds [3 x float], [3 x float]* %62, i64 1
%64 = getelementptr inbounds [3 x float], [3 x float]* %63, i64 0, i64 0
%65 = call i32 @vector3d_normalize(float* %64)
%66 = load [3 x float]*, [3 x float]** %2
%67 = getelementptr inbounds [3 x float], [3 x float]* %66, i64 2
%68 = getelementptr inbounds [3 x float], [3 x float]* %67, i64 0, i64 0
%69 = call i32 @vector3d_normalize(float* %68)
ret void
}

LLVM IR (-O2):
define void @dcm_orthonormalize([3 x float]* %0) {
%2 = alloca [2 x [3 x float]]
%3 = getelementptr inbounds [3 x float], [3 x float]* %0, i64 0, i64 0
%4 = getelementptr inbounds [3 x float], [3 x float]* %0, i64 1, i64 0
%5 = tail call float @vector3d_dot(float* %3, float* %4)
%6 = bitcast [2 x [3 x float]]* %2 to i8*
%7 = fmul float %5, -5.000000e-01
%8 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %2, i64 0, i64 0, i64 0
%9 = call i32 @vector3d_scale(float %7, float* %4, float* %8)
%10 = getelementptr inbounds [2 x [3 x float]], [2 x [3 x float]]* %2, i64 0, i64 1, i64 0
%11 = call i32 @vector3d_scale(float %7, float* %3, float* %10)
%12 = call i32 @vector3d_add(float* %3, float* %8, float* %3)
%13 = call i32 @vector3d_add(float* %4, float* %10, float* %4)
%14 = getelementptr inbounds [3 x float], [3 x float]* %0, i64 2, i64 0
%15 = call i32 @vector3d_cross(float* %3, float* %4, float* %14)
%16 = call i32 @vector3d_normalize(float* %3)
%17 = call i32 @vector3d_normalize(float* %4)
%18 = call i32 @vector3d_normalize(float* %14)
ret void
}