#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 */
float acosf(float);
float cosf(float);
float sinf(float);
float sqrt(float);
void quat_from_vec(float *q, float *v) {
  float ref_dir[] = {0, 1, 0};
  float t = acosf(
      ((v)[0] * (ref_dir)[0] + (v)[1] * (ref_dir)[1] + (v)[2] * (ref_dir)[2]));
  float s = sinf(t / 2);
  float a[3];
  {
    (a)[0] = (v)[1] * (ref_dir)[2] - (v)[2] * (ref_dir)[1];
    (a)[1] = (v)[2] * (ref_dir)[0] - (v)[0] * (ref_dir)[2];
    (a)[2] = (v)[0] * (ref_dir)[1] - (v)[1] * (ref_dir)[0];
  };
  q[0] = a[0] * s;
  q[1] = a[1] * s;
  q[2] = a[2] * s;
  q[3] = cosf(t / 2);
  float mag = 1.f / sqrt(((q)[0] * (q)[0] + (q)[1] * (q)[1] + (q)[2] * (q)[2] +
                          (q)[3] * (q)[3]));
  {
    (q)[0] = (q)[0] * (mag);
    (q)[1] = (q)[1] * (mag);
    (q)[2] = (q)[2] * (mag);
    (q)[3] = (q)[3] * (mag);
  };
}


x86 assembly (clang, -O0):
<quat_from_vec>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    0xeb1(%rip),%rax
mov    %rax,-0x1c(%rbp)
mov    0xeaf(%rip),%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm1
movss  -0x1c(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mulss  -0x18(%rbp),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x14(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
call   1050 <acosf@plt>
movss  %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm0
movss  0xe50(%rip),%xmm1
divss  %xmm1,%xmm0
call   1030 <sinf@plt>
movss  %xmm0,-0x24(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  -0x14(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm1
mulss  -0x18(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x1c(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm1
mulss  -0x14(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movss  -0x18(%rbp),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mulss  -0x1c(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x30(%rbp),%xmm0
mulss  -0x24(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x2c(%rbp),%xmm0
mulss  -0x24(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x28(%rbp),%xmm0
mulss  -0x24(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
movss  -0x20(%rbp),%xmm0
movss  0xd5d(%rip),%xmm1
divss  %xmm1,%xmm0
call   1040 <cosf@plt>
mov    -0x8(%rbp),%rax
movss  %xmm0,0xc(%rax)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulss  0x4(%rax),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm1
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movss  0xc(%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  0xc(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
call   1060 <sqrt@plt>
movaps %xmm0,%xmm1
movss  0xcd9(%rip),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,-0x34(%rbp)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
mulss  -0x34(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm0
mulss  -0x34(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm0
mulss  -0x34(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
mov    -0x8(%rbp),%rax
movss  0xc(%rax),%xmm0
mulss  -0x34(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0xc(%rax)
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<quat_from_vec>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%rbx
xorps  %xmm2,%xmm2
movss  (%rsi),%xmm1
mulss  %xmm2,%xmm1
addss  0x4(%rsi),%xmm1
mov    %rdi,%r14
movss  0x8(%rsi),%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
call   1050 <acosf@plt>
mulss  0xe8c(%rip),%xmm0
movss  %xmm0,0x4(%rsp)
call   1030 <sinf@plt>
movss  (%rbx),%xmm1
movss  0x8(%rbx),%xmm2
movss  0x4(%rbx),%xmm3
xorps  %xmm5,%xmm5
mulss  %xmm5,%xmm3
movss  0xe68(%rip),%xmm4
mulss  %xmm1,%xmm4
subss  %xmm3,%xmm1
subss  %xmm2,%xmm3
mulss  %xmm5,%xmm2
addss  %xmm4,%xmm2
mulss  %xmm0,%xmm3
movss  %xmm3,(%r14)
mulss  %xmm0,%xmm2
movss  %xmm2,0x4(%r14)
mulss  %xmm0,%xmm1
movss  %xmm1,0x8(%r14)
movss  0x4(%rsp),%xmm0
call   1040 <cosf@plt>
movss  %xmm0,0xc(%r14)
movss  (%r14),%xmm1
movss  0x4(%r14),%xmm2
mulss  %xmm2,%xmm2
mulss  %xmm1,%xmm1
addss  %xmm2,%xmm1
movss  0x8(%r14),%xmm2
mulss  %xmm2,%xmm2
addss  %xmm1,%xmm2
mulss  %xmm0,%xmm0
addss  %xmm2,%xmm0
ucomiss 0xdfa(%rip),%xmm0
jb     121a <quat_from_vec+0xda>
sqrtss %xmm0,%xmm0
jmp    121f <quat_from_vec+0xdf>
call   1060 <sqrt@plt>
movss  0xde1(%rip),%xmm1
divss  %xmm0,%xmm1
movups (%r14),%xmm0
shufps $0x0,%xmm1,%xmm1
mulps  %xmm0,%xmm1
movups %xmm1,(%r14)
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
@__const.quat_from_vec.ref_dir = [3 x float] [float 0.000000e+00, float 1.000000e+00, float 0.000000e+00]
define void @quat_from_vec(float* %0, float* %1) {
%3 = alloca float*
%4 = alloca float*
%5 = alloca [3 x float]
%6 = alloca float
%7 = alloca float
%8 = alloca [3 x float]
%9 = alloca float
store float* %0, float** %3
store float* %1, float** %4
%10 = bitcast [3 x float]* %5 to i8*
%11 = load float*, float** %4
%12 = getelementptr inbounds float, float* %11, i64 0
%13 = load float, float* %12
%14 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 0
%15 = load float, float* %14
%16 = load float*, float** %4
%17 = getelementptr inbounds float, float* %16, i64 1
%18 = load float, float* %17
%19 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 1
%20 = load float, float* %19
%21 = fmul float %18, %20
%22 = call float @llvm.fmuladd.f32(float %13, float %15, float %21)
%23 = load float*, float** %4
%24 = getelementptr inbounds float, float* %23, i64 2
%25 = load float, float* %24
%26 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 2
%27 = load float, float* %26
%28 = call float @llvm.fmuladd.f32(float %25, float %27, float %22)
%29 = call float @acosf(float %28)
store float %29, float* %6
%30 = load float, float* %6
%31 = fdiv float %30, 2.000000e+00
%32 = call float @sinf(float %31)
store float %32, float* %7
%33 = load float*, float** %4
%34 = getelementptr inbounds float, float* %33, i64 1
%35 = load float, float* %34
%36 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 2
%37 = load float, float* %36
%38 = load float*, float** %4
%39 = getelementptr inbounds float, float* %38, i64 2
%40 = load float, float* %39
%41 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 1
%42 = load float, float* %41
%43 = fmul float %40, %42
%44 = fneg float %43
%45 = call float @llvm.fmuladd.f32(float %35, float %37, float %44)
%46 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 0, i64 0
store float %45, float* %46
%47 = load float*, float** %4
%48 = getelementptr inbounds float, float* %47, i64 2
%49 = load float, float* %48
%50 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 0
%51 = load float, float* %50
%52 = load float*, float** %4
%53 = getelementptr inbounds float, float* %52, i64 0
%54 = load float, float* %53
%55 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 2
%56 = load float, float* %55
%57 = fmul float %54, %56
%58 = fneg float %57
%59 = call float @llvm.fmuladd.f32(float %49, float %51, float %58)
%60 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 0, i64 1
store float %59, float* %60
%61 = load float*, float** %4
%62 = getelementptr inbounds float, float* %61, i64 0
%63 = load float, float* %62
%64 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 1
%65 = load float, float* %64
%66 = load float*, float** %4
%67 = getelementptr inbounds float, float* %66, i64 1
%68 = load float, float* %67
%69 = getelementptr inbounds [3 x float], [3 x float]* %5, i64 0, i64 0
%70 = load float, float* %69
%71 = fmul float %68, %70
%72 = fneg float %71
%73 = call float @llvm.fmuladd.f32(float %63, float %65, float %72)
%74 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 0, i64 2
store float %73, float* %74
%75 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 0, i64 0
%76 = load float, float* %75
%77 = load float, float* %7
%78 = fmul float %76, %77
%79 = load float*, float** %3
%80 = getelementptr inbounds float, float* %79, i64 0
store float %78, float* %80
%81 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 0, i64 1
%82 = load float, float* %81
%83 = load float, float* %7
%84 = fmul float %82, %83
%85 = load float*, float** %3
%86 = getelementptr inbounds float, float* %85, i64 1
store float %84, float* %86
%87 = getelementptr inbounds [3 x float], [3 x float]* %8, i64 0, i64 2
%88 = load float, float* %87
%89 = load float, float* %7
%90 = fmul float %88, %89
%91 = load float*, float** %3
%92 = getelementptr inbounds float, float* %91, i64 2
store float %90, float* %92
%93 = load float, float* %6
%94 = fdiv float %93, 2.000000e+00
%95 = call float @cosf(float %94)
%96 = load float*, float** %3
%97 = getelementptr inbounds float, float* %96, i64 3
store float %95, float* %97
%98 = load float*, float** %3
%99 = getelementptr inbounds float, float* %98, i64 0
%100 = load float, float* %99
%101 = load float*, float** %3
%102 = getelementptr inbounds float, float* %101, i64 0
%103 = load float, float* %102
%104 = load float*, float** %3
%105 = getelementptr inbounds float, float* %104, i64 1
%106 = load float, float* %105
%107 = load float*, float** %3
%108 = getelementptr inbounds float, float* %107, i64 1
%109 = load float, float* %108
%110 = fmul float %106, %109
%111 = call float @llvm.fmuladd.f32(float %100, float %103, float %110)
%112 = load float*, float** %3
%113 = getelementptr inbounds float, float* %112, i64 2
%114 = load float, float* %113
%115 = load float*, float** %3
%116 = getelementptr inbounds float, float* %115, i64 2
%117 = load float, float* %116
%118 = call float @llvm.fmuladd.f32(float %114, float %117, float %111)
%119 = load float*, float** %3
%120 = getelementptr inbounds float, float* %119, i64 3
%121 = load float, float* %120
%122 = load float*, float** %3
%123 = getelementptr inbounds float, float* %122, i64 3
%124 = load float, float* %123
%125 = call float @llvm.fmuladd.f32(float %121, float %124, float %118)
%126 = call float @sqrt(float %125)
%127 = fdiv float 1.000000e+00, %126
store float %127, float* %9
%128 = load float*, float** %3
%129 = getelementptr inbounds float, float* %128, i64 0
%130 = load float, float* %129
%131 = load float, float* %9
%132 = fmul float %130, %131
%133 = load float*, float** %3
%134 = getelementptr inbounds float, float* %133, i64 0
store float %132, float* %134
%135 = load float*, float** %3
%136 = getelementptr inbounds float, float* %135, i64 1
%137 = load float, float* %136
%138 = load float, float* %9
%139 = fmul float %137, %138
%140 = load float*, float** %3
%141 = getelementptr inbounds float, float* %140, i64 1
store float %139, float* %141
%142 = load float*, float** %3
%143 = getelementptr inbounds float, float* %142, i64 2
%144 = load float, float* %143
%145 = load float, float* %9
%146 = fmul float %144, %145
%147 = load float*, float** %3
%148 = getelementptr inbounds float, float* %147, i64 2
store float %146, float* %148
%149 = load float*, float** %3
%150 = getelementptr inbounds float, float* %149, i64 3
%151 = load float, float* %150
%152 = load float, float* %9
%153 = fmul float %151, %152
%154 = load float*, float** %3
%155 = getelementptr inbounds float, float* %154, i64 3
store float %153, float* %155
ret void
}

LLVM IR (-O2):
define void @quat_from_vec(float* nocapture %0, float* nocapture %1) {
%3 = load float, float* %1
%4 = getelementptr inbounds float, float* %1, i64 1
%5 = load float, float* %4
%6 = tail call float @llvm.fmuladd.f32(float %3, float 0.000000e+00, float %5)
%7 = getelementptr inbounds float, float* %1, i64 2
%8 = load float, float* %7
%9 = tail call float @llvm.fmuladd.f32(float %8, float 0.000000e+00, float %6)
%10 = tail call float @acosf(float %9)
%11 = fmul float %10, 5.000000e-01
%12 = tail call float @sinf(float %11)
%13 = load float, float* %4
%14 = load float, float* %7
%15 = fneg float %14
%16 = tail call float @llvm.fmuladd.f32(float %13, float 0.000000e+00, float %15)
%17 = load float, float* %1
%18 = fmul float %17, -0.000000e+00
%19 = tail call float @llvm.fmuladd.f32(float %14, float 0.000000e+00, float %18)
%20 = fmul float %13, 0.000000e+00
%21 = fsub float %17, %20
%22 = fmul float %12, %16
store float %22, float* %0
%23 = fmul float %12, %19
%24 = getelementptr inbounds float, float* %0, i64 1
store float %23, float* %24
%25 = fmul float %12, %21
%26 = getelementptr inbounds float, float* %0, i64 2
store float %25, float* %26
%27 = tail call float @cosf(float %11)
%28 = getelementptr inbounds float, float* %0, i64 3
store float %27, float* %28
%29 = load float, float* %0
%30 = load float, float* %24
%31 = fmul float %30, %30
%32 = tail call float @llvm.fmuladd.f32(float %29, float %29, float %31)
%33 = load float, float* %26
%34 = tail call float @llvm.fmuladd.f32(float %33, float %33, float %32)
%35 = tail call float @llvm.fmuladd.f32(float %27, float %27, float %34)
%36 = tail call float @sqrt(float %35)
%37 = fdiv float 1.000000e+00, %36
%38 = bitcast float* %0 to <4 x float>*
%39 = load <4 x float>, <4 x float>* %38
%40 = insertelement <4 x float> poison, float %37, i64 0
%41 = shufflevector <4 x float> %40, <4 x float> poison, <4 x i32> zeroinitializer
%42 = fmul <4 x float> %39, %41
%43 = bitcast float* %0 to <4 x float>*
store <4 x float> %42, <4 x float>* %43
ret void
}