#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*/ AxisAng3(double *, double *, double *);
int /*<<< orphan*/ Matrix3Equal(double **, double **);
int /*<<< orphan*/ Matrix3Mult(double **, double **, double **);
int /*<<< orphan*/ Matrix3MultValue(double **, double, double **);
int cos(double);
double sin(double);
int /*<<< orphan*/ so3ToVec(double **, double *);
void MatrixExp3(double so3Mat[3][3], double R[3][3]) {
  double omgtheta[3];
  double omghat[3] = {0};
  double theta = 0;
  int ret = 0;
  int i;
  int j;
  double MatI3[3][3] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
  so3ToVec(so3Mat, omgtheta);
  AxisAng3(omgtheta, omghat, &theta);
  if (theta < 1.0E-6) {
    Matrix3Equal(MatI3, R);
    return;
  } else {
    double omgmat[3][3];
    double temp[3][3];
    Matrix3MultValue(so3Mat, 1.0 / theta, omgmat);
    Matrix3Mult(omgmat, omgmat, temp);
    for (i = 0; i < 3; i++) {
      for (j = 0; j < 3; j++) {
        R[i][j] = MatI3[i][j] + sin(theta) * so3Mat[i][j] / theta +
                  (1 - cos(theta)) * temp[i][j];
      }
    }
  }
  return;
}


x86 assembly (clang, -O0):
<MatrixExp3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x160,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    -0x50(%rbp),%rdi
xor    %esi,%esi
mov    $0x18,%edx
call   1040 <memset@plt>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
movl   $0x0,-0x5c(%rbp)
lea    -0xb0(%rbp),%rdi
xor    %esi,%esi
mov    $0x48,%edx
call   1040 <memset@plt>
movsd  0xe3b(%rip),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
movsd  0xe2b(%rip),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  0xe1b(%rip),%xmm0
movsd  %xmm0,-0x70(%rbp)
mov    -0x8(%rbp),%rdi
lea    -0x30(%rbp),%rsi
call   1030 <so3ToVec@plt>
lea    -0x30(%rbp),%rdi
lea    -0x50(%rbp),%rsi
lea    -0x58(%rbp),%rdx
call   1080 <AxisAng3@plt>
movsd  0xde8(%rip),%xmm0
ucomisd -0x58(%rbp),%xmm0
jbe    1238 <MatrixExp3+0xb8>
lea    -0xb0(%rbp),%rdi
mov    -0x10(%rbp),%rsi
call   1050 <Matrix3Equal@plt>
jmp    1377 <MatrixExp3+0x1f7>
mov    -0x8(%rbp),%rdi
movsd  0xdc4(%rip),%xmm0
divsd  -0x58(%rbp),%xmm0
lea    -0x100(%rbp),%rsi
call   10a0 <Matrix3MultValue@plt>
lea    -0x100(%rbp),%rdi
lea    -0x100(%rbp),%rsi
lea    -0x150(%rbp),%rdx
call   1060 <Matrix3Mult@plt>
movl   $0x0,-0x60(%rbp)
cmpl   $0x3,-0x60(%rbp)
jge    136d <MatrixExp3+0x1ed>
movl   $0x0,-0x64(%rbp)
cmpl   $0x3,-0x64(%rbp)
jge    135a <MatrixExp3+0x1da>
movslq -0x60(%rbp),%rcx
lea    -0xb0(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x160(%rbp)
ff
movsd  -0x58(%rbp),%xmm0
call   1070 <sin@plt>
movaps %xmm0,%xmm1
movsd  -0x160(%rbp),%xmm0
ff
mov    -0x8(%rbp),%rax
movslq -0x60(%rbp),%rcx
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x64(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
divsd  -0x58(%rbp),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x158(%rbp)
ff
movsd  -0x58(%rbp),%xmm0
call   1090 <cos@plt>
movsd  -0x158(%rbp),%xmm1
ff
mov    %eax,%ecx
mov    $0x1,%eax
sub    %ecx,%eax
cvtsi2sd %eax,%xmm0
movslq -0x60(%rbp),%rcx
lea    -0x150(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x64(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movslq -0x60(%rbp),%rcx
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x64(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    1287 <MatrixExp3+0x107>
jmp    135f <MatrixExp3+0x1df>
mov    -0x60(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x60(%rbp)
jmp    1276 <MatrixExp3+0xf6>
jmp    1372 <MatrixExp3+0x1f2>
jmp    1377 <MatrixExp3+0x1f7>
add    $0x160,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<MatrixExp3>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x138,%rsp
mov    %rsi,%r14
mov    %rdi,%r12
xorps  %xmm0,%xmm0
movaps %xmm0,0x60(%rsp)
movq   $0x0,0x70(%rsp)
movq   $0x0,0x8(%rsp)
movaps %xmm0,0x10(%rsp)
movaps %xmm0,0x30(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x20(%rsp)
movabs $0x3ff0000000000000,%rax
mov    %rax,0x10(%rsp)
mov    %rax,0x30(%rsp)
mov    %rax,0x50(%rsp)
lea    0xd0(%rsp),%r15
mov    %r15,%rsi
call   1030 <so3ToVec@plt>
lea    0x60(%rsp),%rsi
lea    0x8(%rsp),%rdx
mov    %r15,%rdi
call   1070 <AxisAng3@plt>
movsd  0x8(%rsp),%xmm1
movsd  0xe05(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    121d <MatrixExp3+0xad>
lea    0x10(%rsp),%rdi
mov    %r14,%rsi
call   1040 <Matrix3Equal@plt>
add    $0x138,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret
movsd  0xde3(%rip),%xmm0
movsd  %xmm0,(%rsp)
divsd  %xmm1,%xmm0
lea    0xf0(%rsp),%r15
mov    %r12,%rdi
mov    %r15,%rsi
call   1090 <Matrix3MultValue@plt>
lea    0x80(%rsp),%rdx
mov    %r15,%rdi
mov    %r15,%rsi
call   1050 <Matrix3Mult@plt>
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
movsd  0x8(%rsp),%xmm0
call   1060 <sin@plt>
movapd %xmm0,%xmm1
mulsd  (%r12,%rbx,1),%xmm1
movsd  0x8(%rsp),%xmm0
divsd  %xmm0,%xmm1
addsd  (%rsp),%xmm1
movsd  %xmm1,(%rsp)
call   1080 <cos@plt>
mov    $0x1,%ecx
sub    %eax,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
mulsd  0x80(%rsp,%rbx,1),%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,(%r14,%rbx,1)
movsd  0x18(%rsp,%rbx,1),%xmm0
movsd  %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
call   1060 <sin@plt>
movapd %xmm0,%xmm1
mulsd  0x8(%r12,%rbx,1),%xmm1
movsd  0x8(%rsp),%xmm0
divsd  %xmm0,%xmm1
addsd  (%rsp),%xmm1
movsd  %xmm1,(%rsp)
call   1080 <cos@plt>
mov    $0x1,%ecx
sub    %eax,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
mulsd  0x88(%rsp,%rbx,1),%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,0x8(%r14,%rbx,1)
movsd  0x20(%rsp,%rbx,1),%xmm0
movsd  %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
call   1060 <sin@plt>
movapd %xmm0,%xmm1
mulsd  0x10(%r12,%rbx,1),%xmm1
movsd  0x8(%rsp),%xmm0
divsd  %xmm0,%xmm1
addsd  (%rsp),%xmm1
movsd  %xmm1,(%rsp)
call   1080 <cos@plt>
mov    $0x1,%ecx
sub    %eax,%ecx
xorps  %xmm0,%xmm0
cvtsi2sd %ecx,%xmm0
mulsd  0x90(%rsp,%rbx,1),%xmm0
addsd  (%rsp),%xmm0
movsd  %xmm0,0x10(%r14,%rbx,1)
cmp    $0x30,%rbx
je     120e <MatrixExp3+0x9e>
movsd  0x28(%rsp,%rbx,1),%xmm0
movsd  %xmm0,(%rsp)
add    $0x18,%rbx
jmp    1260 <MatrixExp3+0xf0>

LLVM IR (-O0):
define void @MatrixExp3([3 x double]* %0, [3 x double]* %1) {
%3 = alloca [3 x double]*
%4 = alloca [3 x double]*
%5 = alloca [3 x double]
%6 = alloca [3 x double]
%7 = alloca double
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca [3 x [3 x double]]
%12 = alloca [3 x [3 x double]]
%13 = alloca [3 x [3 x double]]
store [3 x double]* %0, [3 x double]** %3
store [3 x double]* %1, [3 x double]** %4
%14 = bitcast [3 x double]* %6 to i8*
store double 0.000000e+00, double* %7
store i32 0, i32* %8
%15 = bitcast [3 x [3 x double]]* %11 to i8*
%16 = bitcast i8* %15 to [3 x [3 x double]]*
%17 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %16, i32 0, i32 0
%18 = getelementptr inbounds [3 x double], [3 x double]* %17, i32 0, i32 0
store double 1.000000e+00, double* %18
%19 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %16, i32 0, i32 1
%20 = getelementptr inbounds [3 x double], [3 x double]* %19, i32 0, i32 1
store double 1.000000e+00, double* %20
%21 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %16, i32 0, i32 2
%22 = getelementptr inbounds [3 x double], [3 x double]* %21, i32 0, i32 2
store double 1.000000e+00, double* %22
%23 = load [3 x double]*, [3 x double]** %3
%24 = bitcast [3 x double]* %23 to double**
%25 = getelementptr inbounds [3 x double], [3 x double]* %5, i64 0, i64 0
%26 = call i32 @so3ToVec(double** %24, double* %25)
%27 = getelementptr inbounds [3 x double], [3 x double]* %5, i64 0, i64 0
%28 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 0
%29 = call i32 @AxisAng3(double* %27, double* %28, double* %7)
%30 = load double, double* %7
%31 = fcmp olt double %30, 0x3EB0C6F7A0B5ED8D
br i1 %31, label %32, label %38
32: ; preds = %2
%33 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %11, i64 0, i64 0
%34 = bitcast [3 x double]* %33 to double**
%35 = load [3 x double]*, [3 x double]** %4
%36 = bitcast [3 x double]* %35 to double**
%37 = call i32 @Matrix3Equal(double** %34, double** %36)
br label %110
38: ; preds = %2
%39 = load [3 x double]*, [3 x double]** %3
%40 = bitcast [3 x double]* %39 to double**
%41 = load double, double* %7
%42 = fdiv double 1.000000e+00, %41
%43 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 0
%44 = bitcast [3 x double]* %43 to double**
%45 = call i32 @Matrix3MultValue(double** %40, double %42, double** %44)
%46 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 0
%47 = bitcast [3 x double]* %46 to double**
%48 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 0
%49 = bitcast [3 x double]* %48 to double**
%50 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %13, i64 0, i64 0
%51 = bitcast [3 x double]* %50 to double**
%52 = call i32 @Matrix3Mult(double** %47, double** %49, double** %51)
store i32 0, i32* %9
br label %53
53: ; preds = %105, %38
%54 = load i32, i32* %9
%55 = icmp slt i32 %54, 3
br i1 %55, label %56, label %108
56: ; preds = %53
store i32 0, i32* %10
br label %57
57: ; preds = %101, %56
%58 = load i32, i32* %10
%59 = icmp slt i32 %58, 3
br i1 %59, label %60, label %104
60: ; preds = %57
%61 = load i32, i32* %9
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %11, i64 0, i64 %62
%64 = load i32, i32* %10
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds [3 x double], [3 x double]* %63, i64 0, i64 %65
%67 = load double, double* %66
%68 = load double, double* %7
%69 = call double @sin(double %68)
%70 = load [3 x double]*, [3 x double]** %3
%71 = load i32, i32* %9
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds [3 x double], [3 x double]* %70, i64 %72
%74 = load i32, i32* %10
%75 = sext i32 %74 to i64
%76 = getelementptr inbounds [3 x double], [3 x double]* %73, i64 0, i64 %75
%77 = load double, double* %76
%78 = fmul double %69, %77
%79 = load double, double* %7
%80 = fdiv double %78, %79
%81 = fadd double %67, %80
%82 = load double, double* %7
%83 = call i32 @cos(double %82)
%84 = sub nsw i32 1, %83
%85 = sitofp i32 %84 to double
%86 = load i32, i32* %9
%87 = sext i32 %86 to i64
%88 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %13, i64 0, i64 %87
%89 = load i32, i32* %10
%90 = sext i32 %89 to i64
%91 = getelementptr inbounds [3 x double], [3 x double]* %88, i64 0, i64 %90
%92 = load double, double* %91
%93 = call double @llvm.fmuladd.f64(double %85, double %92, double %81)
%94 = load [3 x double]*, [3 x double]** %4
%95 = load i32, i32* %9
%96 = sext i32 %95 to i64
%97 = getelementptr inbounds [3 x double], [3 x double]* %94, i64 %96
%98 = load i32, i32* %10
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds [3 x double], [3 x double]* %97, i64 0, i64 %99
store double %93, double* %100
br label %101
101: ; preds = %60
%102 = load i32, i32* %10
%103 = add nsw i32 %102, 1
store i32 %103, i32* %10
br label %57
104: ; preds = %57
br label %105
105: ; preds = %104
%106 = load i32, i32* %9
%107 = add nsw i32 %106, 1
store i32 %107, i32* %9
br label %53
108: ; preds = %53
br label %109
109: ; preds = %108
br label %110
110: ; preds = %109, %32
ret void
}

LLVM IR (-O2):
define void @MatrixExp3([3 x double]* %0, [3 x double]* %1) {
%3 = alloca [3 x double]
%4 = alloca [3 x double]
%5 = alloca double
%6 = alloca [3 x [3 x double]]
%7 = alloca [3 x [3 x double]]
%8 = alloca [3 x [3 x double]]
%9 = bitcast [3 x double]* %3 to i8*
%10 = bitcast [3 x double]* %4 to i8*
%11 = bitcast double* %5 to i8*
store double 0.000000e+00, double* %5
%12 = bitcast [3 x [3 x double]]* %6 to i8*
%13 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 0, i64 0
store double 1.000000e+00, double* %13
%14 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 1, i64 1
store double 1.000000e+00, double* %14
%15 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 2, i64 2
store double 1.000000e+00, double* %15
%16 = bitcast [3 x double]* %0 to double**
%17 = getelementptr inbounds [3 x double], [3 x double]* %3, i64 0, i64 0
%18 = call i32 @so3ToVec(double** %16, double* %17)
%19 = getelementptr inbounds [3 x double], [3 x double]* %4, i64 0, i64 0
%20 = call i32 @AxisAng3(double* %17, double* %19, double* %5)
%21 = load double, double* %5
%22 = fcmp olt double %21, 0x3EB0C6F7A0B5ED8D
br i1 %22, label %23, label %27
23: ; preds = %2
%24 = bitcast [3 x [3 x double]]* %6 to double**
%25 = bitcast [3 x double]* %1 to double**
%26 = call i32 @Matrix3Equal(double** %24, double** %25)
br label %93
27: ; preds = %2
%28 = bitcast [3 x [3 x double]]* %7 to i8*
%29 = bitcast [3 x [3 x double]]* %8 to i8*
%30 = fdiv double 1.000000e+00, %21
%31 = bitcast [3 x [3 x double]]* %7 to double**
%32 = call i32 @Matrix3MultValue(double** %16, double %30, double** %31)
%33 = bitcast [3 x [3 x double]]* %8 to double**
%34 = call i32 @Matrix3Mult(double** %31, double** %31, double** %33)
br label %35
35: ; preds = %89, %27
%36 = phi double [ 1.000000e+00, %27 ], [ %91, %89 ]
%37 = phi i64 [ 0, %27 ], [ %87, %89 ]
%38 = load double, double* %5
%39 = call double @sin(double %38)
%40 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 %37, i64 0
%41 = load double, double* %40
%42 = fmul double %39, %41
%43 = load double, double* %5
%44 = fdiv double %42, %43
%45 = fadd double %36, %44
%46 = call i32 @cos(double %43)
%47 = sub nsw i32 1, %46
%48 = sitofp i32 %47 to double
%49 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 %37, i64 0
%50 = load double, double* %49
%51 = call double @llvm.fmuladd.f64(double %48, double %50, double %45)
%52 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 %37, i64 0
store double %51, double* %52
%53 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 %37, i64 1
%54 = load double, double* %53
%55 = load double, double* %5
%56 = call double @sin(double %55)
%57 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 %37, i64 1
%58 = load double, double* %57
%59 = fmul double %56, %58
%60 = load double, double* %5
%61 = fdiv double %59, %60
%62 = fadd double %54, %61
%63 = call i32 @cos(double %60)
%64 = sub nsw i32 1, %63
%65 = sitofp i32 %64 to double
%66 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 %37, i64 1
%67 = load double, double* %66
%68 = call double @llvm.fmuladd.f64(double %65, double %67, double %62)
%69 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 %37, i64 1
store double %68, double* %69
%70 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 %37, i64 2
%71 = load double, double* %70
%72 = load double, double* %5
%73 = call double @sin(double %72)
%74 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 %37, i64 2
%75 = load double, double* %74
%76 = fmul double %73, %75
%77 = load double, double* %5
%78 = fdiv double %76, %77
%79 = fadd double %71, %78
%80 = call i32 @cos(double %77)
%81 = sub nsw i32 1, %80
%82 = sitofp i32 %81 to double
%83 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 %37, i64 2
%84 = load double, double* %83
%85 = call double @llvm.fmuladd.f64(double %82, double %84, double %79)
%86 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 %37, i64 2
store double %85, double* %86
%87 = add nuw nsw i64 %37, 1
%88 = icmp eq i64 %87, 3
br i1 %88, label %92, label %89
89: ; preds = %35
%90 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 %87, i64 0
%91 = load double, double* %90
br label %35
92: ; preds = %35
br label %93
93: ; preds = %92, %23
ret void
}