#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 acos(float);
double fabs(float);
int /*<<< orphan*/ quatadd(float *, float const *, float const *);
int /*<<< orphan*/ quatcopy(float *, float const *);
float quatinnerproduct(float *, float *);
int /*<<< orphan*/ quatnormalize(float *, float const *);
int /*<<< orphan*/ quatscale(float *, float const *, int);
int sin(int);
float sqrt(int);
void quatslerp(float *q, const float *qa, const float *qb, float t) {
  float an[4];
  float bn[4];
  quatnormalize(an, qa);
  quatnormalize(bn, qb);
  float cosTheta = quatinnerproduct(an, bn);
  float sinTheta;
  if (1 - (cosTheta * cosTheta) <= 0)
    sinTheta = 0;
  else
    sinTheta = sqrt(1 - (cosTheta * cosTheta));
  float Theta = acos(cosTheta);
  if (fabs(Theta) < 0.001)
    quatcopy(q, qa);
  else if (fabs(sinTheta) < 0.001) {
    quatadd(q, qa, qb);
    quatscale(q, q, 0.5);
  } else {
    float aside[4];
    float bside[4];
    quatscale(bside, qb, sin(t * Theta));
    quatscale(aside, qa, sin((1 - t) * Theta));
    quatadd(q, aside, bside);
    quatscale(q, q, 1. / sinTheta);
  }
}


x86 assembly (clang, -O0):
<quatslerp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movss  %xmm0,-0x1c(%rbp)
lea    -0x30(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1070 <quatnormalize@plt>
lea    -0x40(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1070 <quatnormalize@plt>
lea    -0x30(%rbp),%rdi
lea    -0x40(%rbp),%rsi
call   1040 <quatinnerproduct@plt>
movss  %xmm0,-0x44(%rbp)
movss  -0x44(%rbp),%xmm1
movss  -0x44(%rbp),%xmm0
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm0,%xmm1
movss  0xe05(%rip),%xmm0
addss  %xmm0,%xmm1
xorps  %xmm0,%xmm0
ucomiss %xmm1,%xmm0
jb     1218 <quatslerp+0x88>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x48(%rbp)
jmp    124d <quatslerp+0xbd>
movss  -0x44(%rbp),%xmm0
movss  -0x44(%rbp),%xmm1
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm1,%xmm0
movss  0xdc5(%rip),%xmm1
addss  %xmm1,%xmm0
cvttss2si %xmm0,%edi
call   10b0 <sqrt@plt>
movss  %xmm0,-0x48(%rbp)
movss  -0x44(%rbp),%xmm0
call   1050 <acos@plt>
movss  %xmm0,-0x4c(%rbp)
movss  -0x4c(%rbp),%xmm0
call   1060 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xd97(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    128d <quatslerp+0xfd>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1090 <quatcopy@plt>
jmp    1385 <quatslerp+0x1f5>
movss  -0x48(%rbp),%xmm0
call   1060 <fabs@plt>
movaps %xmm0,%xmm1
movsd  0xd66(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    12d1 <quatslerp+0x141>
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1030 <quatadd@plt>
mov    -0x8(%rbp),%rdi
mov    -0x8(%rbp),%rsi
xor    %edx,%edx
call   10a0 <quatscale@plt>
jmp    1380 <quatslerp+0x1f0>
lea    -0x70(%rbp),%rax
mov    %rax,-0x90(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x88(%rbp)
movss  -0x1c(%rbp),%xmm0
mulss  -0x4c(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1080 <sin@plt>
mov    -0x90(%rbp),%rdi
mov    -0x88(%rbp),%rsi
mov    %eax,%edx
call   10a0 <quatscale@plt>
lea    -0x60(%rbp),%rax
mov    %rax,-0x80(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x78(%rbp)
movss  0xcd9(%rip),%xmm0
subss  -0x1c(%rbp),%xmm0
mulss  -0x4c(%rbp),%xmm0
cvttss2si %xmm0,%edi
call   1080 <sin@plt>
mov    -0x80(%rbp),%rdi
mov    -0x78(%rbp),%rsi
mov    %eax,%edx
call   10a0 <quatscale@plt>
mov    -0x8(%rbp),%rdi
lea    -0x60(%rbp),%rsi
lea    -0x70(%rbp),%rdx
call   1030 <quatadd@plt>
mov    -0x8(%rbp),%rdi
mov    -0x8(%rbp),%rsi
movss  -0x48(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xc9d(%rip),%xmm0
divsd  %xmm1,%xmm0
cvttsd2si %xmm0,%edx
call   10a0 <quatscale@plt>
jmp    1385 <quatslerp+0x1f5>
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<quatslerp>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x50,%rsp
movss  %xmm0,0xc(%rsp)
mov    %rdx,%r15
mov    %rsi,%r12
mov    %rdi,%r14
lea    0x40(%rsp),%r13
mov    %r13,%rdi
call   1070 <quatnormalize@plt>
lea    0x30(%rsp),%rbx
mov    %rbx,%rdi
mov    %r15,%rsi
call   1070 <quatnormalize@plt>
mov    %r13,%rdi
mov    %rbx,%rsi
call   1040 <quatinnerproduct@plt>
movaps %xmm0,%xmm3
movaps %xmm0,%xmm1
mulss  %xmm0,%xmm1
movss  0xe1a(%rip),%xmm2
subss  %xmm1,%xmm2
xorps  %xmm0,%xmm0
ucomiss %xmm2,%xmm0
jae    1207 <quatslerp+0x77>
cvttss2si %xmm2,%edi
movss  %xmm3,0x4(%rsp)
call   10b0 <sqrt@plt>
movss  0x4(%rsp),%xmm3
movss  %xmm0,0x4(%rsp)
movaps %xmm3,%xmm0
call   1050 <acos@plt>
movss  %xmm0,0x8(%rsp)
call   1060 <fabs@plt>
movsd  0xde0(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    123e <quatslerp+0xae>
mov    %r14,%rdi
mov    %r12,%rsi
call   1090 <quatcopy@plt>
jmp    12fb <quatslerp+0x16b>
movss  0x4(%rsp),%xmm0
call   1060 <fabs@plt>
movsd  0xdb7(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    1272 <quatslerp+0xe2>
mov    %r14,%rdi
mov    %r12,%rsi
mov    %r15,%rdx
call   1030 <quatadd@plt>
mov    %r14,%rdi
mov    %r14,%rsi
xor    %edx,%edx
jmp    12f6 <quatslerp+0x166>
movss  0x8(%rsp),%xmm0
mulss  0xc(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1080 <sin@plt>
lea    0x10(%rsp),%r13
mov    %r13,%rdi
mov    %r15,%rsi
mov    %eax,%edx
call   10a0 <quatscale@plt>
movss  0xd5f(%rip),%xmm0
subss  0xc(%rsp),%xmm0
mulss  0x8(%rsp),%xmm0
cvttss2si %xmm0,%edi
call   1080 <sin@plt>
lea    0x20(%rsp),%rbx
mov    %rbx,%rdi
mov    %r12,%rsi
mov    %eax,%edx
call   10a0 <quatscale@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    %r13,%rdx
call   1030 <quatadd@plt>
movss  0x4(%rsp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xd28(%rip),%xmm1
divsd  %xmm0,%xmm1
cvttsd2si %xmm1,%edx
mov    %r14,%rdi
mov    %r14,%rsi
call   10a0 <quatscale@plt>
add    $0x50,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @quatslerp(float* %0, float* %1, float* %2, float %3) {
%5 = alloca float*
%6 = alloca float*
%7 = alloca float*
%8 = alloca float
%9 = alloca [4 x float]
%10 = alloca [4 x float]
%11 = alloca float
%12 = alloca float
%13 = alloca float
%14 = alloca [4 x float]
%15 = alloca [4 x float]
store float* %0, float** %5
store float* %1, float** %6
store float* %2, float** %7
store float %3, float* %8
%16 = getelementptr inbounds [4 x float], [4 x float]* %9, i64 0, i64 0
%17 = load float*, float** %6
%18 = call i32 @quatnormalize(float* %16, float* %17)
%19 = getelementptr inbounds [4 x float], [4 x float]* %10, i64 0, i64 0
%20 = load float*, float** %7
%21 = call i32 @quatnormalize(float* %19, float* %20)
%22 = getelementptr inbounds [4 x float], [4 x float]* %9, i64 0, i64 0
%23 = getelementptr inbounds [4 x float], [4 x float]* %10, i64 0, i64 0
%24 = call float @quatinnerproduct(float* %22, float* %23)
store float %24, float* %11
%25 = load float, float* %11
%26 = load float, float* %11
%27 = fneg float %25
%28 = call float @llvm.fmuladd.f32(float %27, float %26, float 1.000000e+00)
%29 = fcmp ole float %28, 0.000000e+00
br i1 %29, label %30, label %31
30: ; preds = %4
store float 0.000000e+00, float* %12
br label %38
31: ; preds = %4
%32 = load float, float* %11
%33 = load float, float* %11
%34 = fneg float %32
%35 = call float @llvm.fmuladd.f32(float %34, float %33, float 1.000000e+00)
%36 = fptosi float %35 to i32
%37 = call float @sqrt(i32 %36)
store float %37, float* %12
br label %38
38: ; preds = %31, %30
%39 = load float, float* %11
%40 = call float @acos(float %39)
store float %40, float* %13
%41 = load float, float* %13
%42 = call double @fabs(float %41)
%43 = fcmp olt double %42, 1.000000e-03
br i1 %43, label %44, label %48
44: ; preds = %38
%45 = load float*, float** %5
%46 = load float*, float** %6
%47 = call i32 @quatcopy(float* %45, float* %46)
br label %90
48: ; preds = %38
%49 = load float, float* %12
%50 = call double @fabs(float %49)
%51 = fcmp olt double %50, 1.000000e-03
br i1 %51, label %52, label %60
52: ; preds = %48
%53 = load float*, float** %5
%54 = load float*, float** %6
%55 = load float*, float** %7
%56 = call i32 @quatadd(float* %53, float* %54, float* %55)
%57 = load float*, float** %5
%58 = load float*, float** %5
%59 = call i32 @quatscale(float* %57, float* %58, i32 0)
br label %89
60: ; preds = %48
%61 = getelementptr inbounds [4 x float], [4 x float]* %15, i64 0, i64 0
%62 = load float*, float** %7
%63 = load float, float* %8
%64 = load float, float* %13
%65 = fmul float %63, %64
%66 = fptosi float %65 to i32
%67 = call i32 @sin(i32 %66)
%68 = call i32 @quatscale(float* %61, float* %62, i32 %67)
%69 = getelementptr inbounds [4 x float], [4 x float]* %14, i64 0, i64 0
%70 = load float*, float** %6
%71 = load float, float* %8
%72 = fsub float 1.000000e+00, %71
%73 = load float, float* %13
%74 = fmul float %72, %73
%75 = fptosi float %74 to i32
%76 = call i32 @sin(i32 %75)
%77 = call i32 @quatscale(float* %69, float* %70, i32 %76)
%78 = load float*, float** %5
%79 = getelementptr inbounds [4 x float], [4 x float]* %14, i64 0, i64 0
%80 = getelementptr inbounds [4 x float], [4 x float]* %15, i64 0, i64 0
%81 = call i32 @quatadd(float* %78, float* %79, float* %80)
%82 = load float*, float** %5
%83 = load float*, float** %5
%84 = load float, float* %12
%85 = fpext float %84 to double
%86 = fdiv double 1.000000e+00, %85
%87 = fptosi double %86 to i32
%88 = call i32 @quatscale(float* %82, float* %83, i32 %87)
br label %89
89: ; preds = %60, %52
br label %90
90: ; preds = %89, %44
ret void
}

LLVM IR (-O2):
define void @quatslerp(float* %0, float* %1, float* %2, float %3) {
%5 = alloca [4 x float]
%6 = alloca [4 x float]
%7 = alloca [4 x float]
%8 = alloca [4 x float]
%9 = bitcast [4 x float]* %5 to i8*
%10 = bitcast [4 x float]* %6 to i8*
%11 = getelementptr inbounds [4 x float], [4 x float]* %5, i64 0, i64 0
%12 = call i32 @quatnormalize(float* %11, float* %1)
%13 = getelementptr inbounds [4 x float], [4 x float]* %6, i64 0, i64 0
%14 = call i32 @quatnormalize(float* %13, float* %2)
%15 = call float @quatinnerproduct(float* %11, float* %13)
%16 = fneg float %15
%17 = call float @llvm.fmuladd.f32(float %16, float %15, float 1.000000e+00)
%18 = fcmp ugt float %17, 0.000000e+00
br i1 %18, label %19, label %22
19: ; preds = %4
%20 = fptosi float %17 to i32
%21 = call float @sqrt(i32 %20)
br label %22
22: ; preds = %4, %19
%23 = phi float [ %21, %19 ], [ 0.000000e+00, %4 ]
%24 = call float @acos(float %15)
%25 = call double @fabs(float %24)
%26 = fcmp olt double %25, 1.000000e-03
br i1 %26, label %27, label %29
27: ; preds = %22
%28 = call i32 @quatcopy(float* %0, float* %1)
br label %54
29: ; preds = %22
%30 = call double @fabs(float %23)
%31 = fcmp olt double %30, 1.000000e-03
br i1 %31, label %32, label %35
32: ; preds = %29
%33 = call i32 @quatadd(float* %0, float* %1, float* %2)
%34 = call i32 @quatscale(float* %0, float* %0, i32 0)
br label %54
35: ; preds = %29
%36 = bitcast [4 x float]* %7 to i8*
%37 = bitcast [4 x float]* %8 to i8*
%38 = getelementptr inbounds [4 x float], [4 x float]* %8, i64 0, i64 0
%39 = fmul float %24, %3
%40 = fptosi float %39 to i32
%41 = call i32 @sin(i32 %40)
%42 = call i32 @quatscale(float* %38, float* %2, i32 %41)
%43 = getelementptr inbounds [4 x float], [4 x float]* %7, i64 0, i64 0
%44 = fsub float 1.000000e+00, %3
%45 = fmul float %44, %24
%46 = fptosi float %45 to i32
%47 = call i32 @sin(i32 %46)
%48 = call i32 @quatscale(float* %43, float* %1, i32 %47)
%49 = call i32 @quatadd(float* %0, float* %43, float* %38)
%50 = fpext float %23 to double
%51 = fdiv double 1.000000e+00, %50
%52 = fptosi double %51 to i32
%53 = call i32 @quatscale(float* %0, float* %0, i32 %52)
br label %54
54: ; preds = %32, %35, %27
ret void
}