void glmRotateVectorByNormalizedQuaternionf(float result[3], const float v[3],
                                            const float q[4]) {
  float temp1 = v[2] * q[0] + v[1] * q[1] - v[0] * q[2];
  float temp2 = v[1] * q[0] - v[2] * q[1] + v[0] * q[3];
  float temp3 = v[0] * q[0] + v[2] * q[2] - v[1] * q[3];
  float temp4 = -v[0] * q[1] - v[1] * q[2] - v[2] * q[3];
  result[0] = q[2] * temp1 - q[3] * temp2 + q[0] * temp3 - q[1] * temp4;
  result[1] = -q[1] * temp1 + q[0] * temp2 + q[3] * temp3 - q[2] * temp4;
  result[2] = q[0] * temp1 + q[1] * temp2 - q[2] * temp3 - q[3] * temp4;
}


x86 assembly (clang, -O0):
<glmRotateVectorByNormalizedQuaternionf>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0xc(%rax),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm1
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x8(%rax),%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0xc(%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x8(%rax),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  0xc(%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x1c(%rbp),%xmm2
mov    -0x18(%rbp),%rax
movss  0xc(%rax),%xmm1
mulss  -0x20(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm1
movss  -0x24(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm0
movss  -0x28(%rbp),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  -0x1c(%rbp),%xmm2
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm1
mulss  -0x20(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movss  0xc(%rax),%xmm1
movss  -0x24(%rbp),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm0
movss  -0x28(%rbp),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x4(%rax)
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
movss  -0x1c(%rbp),%xmm2
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm1
mulss  -0x20(%rbp),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm1
movss  -0x24(%rbp),%xmm2
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x18(%rbp),%rax
movss  0xc(%rax),%xmm0
movss  -0x28(%rbp),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,0x8(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<glmRotateVectorByNormalizedQuaternionf>:
movss  0x8(%rsi),%xmm9
movss  (%rsi),%xmm0
movss  0x4(%rsi),%xmm10
movss  (%rdx),%xmm4
movss  0x4(%rdx),%xmm8
movaps %xmm10,%xmm2
mulss  %xmm8,%xmm2
movaps %xmm9,%xmm1
mulss  %xmm4,%xmm1
addss  %xmm2,%xmm1
movss  0x8(%rdx),%xmm7
movaps 0xec5(%rip),%xmm2
xorps  %xmm0,%xmm2
movaps %xmm0,%xmm3
mulss  %xmm7,%xmm3
subss  %xmm3,%xmm1
movaps %xmm8,%xmm3
mulss  %xmm9,%xmm3
movaps %xmm10,%xmm5
mulss  %xmm4,%xmm5
subss  %xmm3,%xmm5
movss  0xc(%rdx),%xmm6
movaps %xmm0,%xmm3
mulss  %xmm6,%xmm3
addss  %xmm5,%xmm3
movaps %xmm9,%xmm5
mulss  %xmm7,%xmm5
mulss  %xmm4,%xmm0
addss  %xmm5,%xmm0
movaps %xmm7,%xmm5
mulss  %xmm10,%xmm5
mulss  %xmm6,%xmm10
subss  %xmm10,%xmm0
mulss  %xmm8,%xmm2
subss  %xmm5,%xmm2
mulss  %xmm6,%xmm9
subss  %xmm9,%xmm2
mulss  %xmm3,%xmm6
mulss  %xmm1,%xmm7
subss  %xmm6,%xmm7
mulss  %xmm0,%xmm4
addss  %xmm7,%xmm4
mulss  %xmm2,%xmm8
subss  %xmm8,%xmm4
movss  %xmm4,(%rdi)
movss  (%rdx),%xmm4
mulss  %xmm3,%xmm4
movss  0x4(%rdx),%xmm5
mulss  %xmm1,%xmm5
subss  %xmm5,%xmm4
movss  0xc(%rdx),%xmm5
mulss  %xmm0,%xmm5
addss  %xmm4,%xmm5
movss  0x8(%rdx),%xmm4
mulss  %xmm2,%xmm4
subss  %xmm4,%xmm5
movss  %xmm5,0x4(%rdi)
mulss  0x4(%rdx),%xmm3
mulss  (%rdx),%xmm1
addss  %xmm3,%xmm1
mulss  0x8(%rdx),%xmm0
subss  %xmm0,%xmm1
mulss  0xc(%rdx),%xmm2
subss  %xmm2,%xmm1
movss  %xmm1,0x8(%rdi)
ret

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

LLVM IR (-O2):
define void @glmRotateVectorByNormalizedQuaternionf(float* nocapture writeonly %0, float* nocapture %1, float* nocapture %2) {
%4 = getelementptr inbounds float, float* %1, i64 2
%5 = load float, float* %4
%6 = load float, float* %2
%7 = getelementptr inbounds float, float* %1, i64 1
%8 = load float, float* %7
%9 = getelementptr inbounds float, float* %2, i64 1
%10 = load float, float* %9
%11 = fmul float %8, %10
%12 = tail call float @llvm.fmuladd.f32(float %5, float %6, float %11)
%13 = load float, float* %1
%14 = getelementptr inbounds float, float* %2, i64 2
%15 = load float, float* %14
%16 = fneg float %13
%17 = tail call float @llvm.fmuladd.f32(float %16, float %15, float %12)
%18 = fneg float %5
%19 = fmul float %10, %18
%20 = tail call float @llvm.fmuladd.f32(float %8, float %6, float %19)
%21 = getelementptr inbounds float, float* %2, i64 3
%22 = load float, float* %21
%23 = tail call float @llvm.fmuladd.f32(float %13, float %22, float %20)
%24 = fmul float %5, %15
%25 = tail call float @llvm.fmuladd.f32(float %13, float %6, float %24)
%26 = fneg float %8
%27 = tail call float @llvm.fmuladd.f32(float %26, float %22, float %25)
%28 = fmul float %15, %26
%29 = tail call float @llvm.fmuladd.f32(float %16, float %10, float %28)
%30 = tail call float @llvm.fmuladd.f32(float %18, float %22, float %29)
%31 = fneg float %22
%32 = fmul float %23, %31
%33 = tail call float @llvm.fmuladd.f32(float %15, float %17, float %32)
%34 = tail call float @llvm.fmuladd.f32(float %6, float %27, float %33)
%35 = fneg float %10
%36 = tail call float @llvm.fmuladd.f32(float %35, float %30, float %34)
store float %36, float* %0
%37 = load float, float* %9
%38 = fneg float %37
%39 = load float, float* %2
%40 = fmul float %23, %39
%41 = tail call float @llvm.fmuladd.f32(float %38, float %17, float %40)
%42 = load float, float* %21
%43 = tail call float @llvm.fmuladd.f32(float %42, float %27, float %41)
%44 = load float, float* %14
%45 = fneg float %44
%46 = tail call float @llvm.fmuladd.f32(float %45, float %30, float %43)
%47 = getelementptr inbounds float, float* %0, i64 1
store float %46, float* %47
%48 = load float, float* %2
%49 = load float, float* %9
%50 = fmul float %23, %49
%51 = tail call float @llvm.fmuladd.f32(float %48, float %17, float %50)
%52 = load float, float* %14
%53 = fneg float %52
%54 = tail call float @llvm.fmuladd.f32(float %53, float %27, float %51)
%55 = load float, float* %21
%56 = fneg float %55
%57 = tail call float @llvm.fmuladd.f32(float %56, float %30, float %54)
%58 = getelementptr inbounds float, float* %0, i64 2
store float %57, float* %58
ret void
}