#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 powf(int, int);
void gfks_rotate_vector_by_quaternion(float vec[3], float x, float y, float z,
                                      float w) {
  float xy2 = x * y * 2;
  float xz2 = x * z * 2;
  float xw2 = x * w * 2;
  float yw2 = y * w * 2;
  float yz2 = y * z * 2;
  float zw2 = z * w * 2;
  float _2x2 = powf(2 * x, 2);
  float _2y2 = powf(2 * y, 2);
  float _2z2 = powf(2 * z, 2);
  float Q[16];
  Q[0] = 1.0f - _2y2 - _2z2;
  Q[1] = xy2 + zw2;
  Q[2] = xz2 - yw2;
  Q[3] = xy2 - zw2;
  Q[4] = 1.0f - _2x2 - _2z2;
  Q[5] = yz2 + xw2;
  Q[6] = xz2 + yw2;
  Q[7] = yz2 - xw2;
  Q[8] = 1.0f - _2x2 - _2y2;
  float result[3];
  result[0] = (vec[0] * Q[0]) + (vec[1] * Q[3]) + (vec[2] * Q[6]);
  result[1] = (vec[0] * Q[1]) + (vec[1] * Q[4]) + (vec[2] * Q[7]);
  result[2] = (vec[0] * Q[2]) + (vec[1] * Q[5]) + (vec[2] * Q[8]);
  vec[0] = result[0];
  vec[1] = result[1];
  vec[2] = result[2];
}


x86 assembly (clang, -O0):
<gfks_rotate_vector_by_quaternion>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %rdi,-0x8(%rbp)
movss  %xmm0,-0xc(%rbp)
movss  %xmm1,-0x10(%rbp)
movss  %xmm2,-0x14(%rbp)
movss  %xmm3,-0x18(%rbp)
movss  -0xc(%rbp),%xmm0
mulss  -0x10(%rbp),%xmm0
movss  0xebf(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0xc(%rbp),%xmm0
mulss  -0x14(%rbp),%xmm0
movss  0xea4(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0xc(%rbp),%xmm0
mulss  -0x18(%rbp),%xmm0
movss  0xe89(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0x10(%rbp),%xmm0
mulss  -0x18(%rbp),%xmm0
movss  0xe6e(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x10(%rbp),%xmm0
mulss  -0x14(%rbp),%xmm0
movss  0xe53(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x14(%rbp),%xmm0
mulss  -0x18(%rbp),%xmm0
movss  0xe38(%rip),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x30(%rbp)
movss  0xe27(%rip),%xmm0
mulss  -0xc(%rbp),%xmm0
cvttss2si %xmm0,%edi
mov    $0x2,%esi
call   1030 <powf@plt>
movss  %xmm0,-0x34(%rbp)
movss  0xe07(%rip),%xmm0
mulss  -0x10(%rbp),%xmm0
cvttss2si %xmm0,%edi
mov    $0x2,%esi
call   1030 <powf@plt>
movss  %xmm0,-0x38(%rbp)
movss  0xde7(%rip),%xmm0
mulss  -0x14(%rbp),%xmm0
cvttss2si %xmm0,%edi
mov    $0x2,%esi
call   1030 <powf@plt>
movss  %xmm0,-0x3c(%rbp)
movss  0xdc3(%rip),%xmm0
subss  -0x38(%rbp),%xmm0
subss  -0x3c(%rbp),%xmm0
movss  %xmm0,-0x80(%rbp)
movss  -0x1c(%rbp),%xmm0
addss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x7c(%rbp)
movss  -0x20(%rbp),%xmm0
subss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x78(%rbp)
movss  -0x1c(%rbp),%xmm0
subss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x74(%rbp)
movss  0xd7f(%rip),%xmm0
subss  -0x34(%rbp),%xmm0
subss  -0x3c(%rbp),%xmm0
movss  %xmm0,-0x70(%rbp)
movss  -0x2c(%rbp),%xmm0
addss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x6c(%rbp)
movss  -0x20(%rbp),%xmm0
addss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x68(%rbp)
movss  -0x2c(%rbp),%xmm0
subss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x64(%rbp)
movss  0xd3b(%rip),%xmm0
subss  -0x34(%rbp),%xmm0
subss  -0x38(%rbp),%xmm0
movss  %xmm0,-0x60(%rbp)
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm1
movss  -0x80(%rbp),%xmm2
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm0
mulss  -0x74(%rbp),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x68(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x8c(%rbp)
ff
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm1
movss  -0x7c(%rbp),%xmm2
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm0
mulss  -0x70(%rbp),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x64(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x88(%rbp)
ff
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm1
movss  -0x78(%rbp),%xmm2
mov    -0x8(%rbp),%rax
movss  0x4(%rax),%xmm0
mulss  -0x6c(%rbp),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x60(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x84(%rbp)
ff
movss  -0x8c(%rbp),%xmm0
ff
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x88(%rbp),%xmm0
ff
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x84(%rbp),%xmm0
ff
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gfks_rotate_vector_by_quaternion>:
push   %rbx
sub    $0x30,%rsp
movss  %xmm2,0x10(%rsp)
movss  %xmm1,0xc(%rsp)
mov    %rdi,%rbx
movaps %xmm0,%xmm4
mulss  %xmm1,%xmm4
addss  %xmm4,%xmm4
movss  %xmm4,0x28(%rsp)
movaps %xmm0,%xmm4
mulss  %xmm2,%xmm4
addss  %xmm4,%xmm4
movss  %xmm4,0x24(%rsp)
movaps %xmm0,%xmm4
mulss  %xmm3,%xmm4
addss  %xmm4,%xmm4
movss  %xmm4,0x2c(%rsp)
movaps %xmm1,%xmm4
mulss  %xmm3,%xmm4
addss  %xmm4,%xmm4
movss  %xmm4,0x1c(%rsp)
movaps %xmm1,%xmm4
mulss  %xmm2,%xmm4
addss  %xmm4,%xmm4
movss  %xmm4,0x20(%rsp)
mulss  %xmm2,%xmm3
addss  %xmm3,%xmm3
movss  %xmm3,0x18(%rsp)
addss  %xmm0,%xmm0
cvttss2si %xmm0,%edi
mov    $0x2,%esi
call   1030 <powf@plt>
movss  %xmm0,0x14(%rsp)
movss  0xc(%rsp),%xmm0
addss  %xmm0,%xmm0
cvttss2si %xmm0,%edi
mov    $0x2,%esi
call   1030 <powf@plt>
movss  %xmm0,0xc(%rsp)
movss  0x10(%rsp),%xmm0
addss  %xmm0,%xmm0
cvttss2si %xmm0,%edi
mov    $0x2,%esi
call   1030 <powf@plt>
movss  0xe23(%rip),%xmm1
movaps %xmm1,%xmm4
movss  0xc(%rsp),%xmm9
subss  %xmm9,%xmm4
subss  %xmm0,%xmm4
movss  0x28(%rsp),%xmm5
movaps %xmm5,%xmm3
movss  0x18(%rsp),%xmm6
addss  %xmm6,%xmm3
movss  0x24(%rsp),%xmm8
movaps %xmm8,%xmm2
movss  0x1c(%rsp),%xmm7
subss  %xmm7,%xmm2
subss  %xmm6,%xmm5
movaps %xmm5,%xmm10
subss  0x14(%rsp),%xmm1
movaps %xmm1,%xmm5
subss  %xmm0,%xmm5
movss  0x20(%rsp),%xmm0
movaps %xmm0,%xmm12
movss  0x2c(%rsp),%xmm6
addss  %xmm6,%xmm12
addss  %xmm8,%xmm7
subss  %xmm6,%xmm0
movaps %xmm0,%xmm11
subss  %xmm9,%xmm1
movss  (%rbx),%xmm8
movss  0x4(%rbx),%xmm9
mulss  %xmm9,%xmm10
mulss  %xmm8,%xmm4
addss  %xmm10,%xmm4
movss  0x8(%rbx),%xmm0
mulss  %xmm0,%xmm7
addss  %xmm4,%xmm7
mulss  %xmm9,%xmm5
mulss  %xmm8,%xmm3
addss  %xmm5,%xmm3
movaps %xmm11,%xmm4
mulss  %xmm0,%xmm4
addss  %xmm3,%xmm4
mulss  %xmm9,%xmm12
mulss  %xmm8,%xmm2
addss  %xmm12,%xmm2
mulss  %xmm0,%xmm1
addss  %xmm2,%xmm1
movss  %xmm7,(%rbx)
movss  %xmm4,0x4(%rbx)
movss  %xmm1,0x8(%rbx)
add    $0x30,%rsp
pop    %rbx
ret

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

LLVM IR (-O2):
define void @gfks_rotate_vector_by_quaternion(float* nocapture %0, float %1, float %2, float %3, float %4) {
%6 = fmul float %1, %2
%7 = fmul float %6, 2.000000e+00
%8 = fmul float %1, %3
%9 = fmul float %8, 2.000000e+00
%10 = fmul float %1, %4
%11 = fmul float %10, 2.000000e+00
%12 = fmul float %2, %4
%13 = fmul float %12, 2.000000e+00
%14 = fmul float %2, %3
%15 = fmul float %14, 2.000000e+00
%16 = fmul float %3, %4
%17 = fmul float %16, 2.000000e+00
%18 = fmul float %1, 2.000000e+00
%19 = fptosi float %18 to i32
%20 = tail call float @powf(i32 %19, i32 2)
%21 = fmul float %2, 2.000000e+00
%22 = fptosi float %21 to i32
%23 = tail call float @powf(i32 %22, i32 2)
%24 = fmul float %3, 2.000000e+00
%25 = fptosi float %24 to i32
%26 = tail call float @powf(i32 %25, i32 2)
%27 = fsub float 1.000000e+00, %23
%28 = fsub float %27, %26
%29 = fadd float %7, %17
%30 = fsub float %9, %13
%31 = fsub float %7, %17
%32 = fsub float 1.000000e+00, %20
%33 = fsub float %32, %26
%34 = fadd float %15, %11
%35 = fadd float %9, %13
%36 = fsub float %15, %11
%37 = fsub float %32, %23
%38 = load float, float* %0
%39 = getelementptr inbounds float, float* %0, i64 1
%40 = load float, float* %39
%41 = fmul float %31, %40
%42 = tail call float @llvm.fmuladd.f32(float %38, float %28, float %41)
%43 = getelementptr inbounds float, float* %0, i64 2
%44 = load float, float* %43
%45 = tail call float @llvm.fmuladd.f32(float %44, float %35, float %42)
%46 = fmul float %33, %40
%47 = tail call float @llvm.fmuladd.f32(float %38, float %29, float %46)
%48 = tail call float @llvm.fmuladd.f32(float %44, float %36, float %47)
%49 = fmul float %34, %40
%50 = tail call float @llvm.fmuladd.f32(float %38, float %30, float %49)
%51 = tail call float @llvm.fmuladd.f32(float %44, float %37, float %50)
store float %45, float* %0
store float %48, float* %39
store float %51, float* %43
ret void
}