#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*/ Matrix3Mult(double **, double **, double **);
int /*<<< orphan*/ Matrix3MultValue(double **, double, double **);
int /*<<< orphan*/ Matrix3MultVec(double **, double *, double *);
int /*<<< orphan*/ MatrixExp3(double **, double **);
int /*<<< orphan*/ TransToRp(double **, double **, double *);
double Vec3Norm2(double *);
double cos(double);
double sin(double);
int /*<<< orphan*/ so3ToVec(double **, double *);
void MatrixExp6(double se3Mat[4][4], double T[4][4]) {
  int i;
  int j;
  double so3mat[3][3];
  double omgmat[3][3];
  double temp[3][3];
  double Gtheta[3][3];
  double p[3];
  double v[3];
  double omgtheta[3];
  double omghat[3];
  double theta;
  double MatI3[3][3] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
  TransToRp(se3Mat, so3mat, p);
  so3ToVec(so3mat, omgtheta);
  if (Vec3Norm2(omgtheta) < 1.0E-6) {
    for (i = 0; i < 3; i++) {
      for (j = 0; j < 3; j++) {
        T[i][j] = MatI3[i][j];
      }
    }
    T[0][3] = se3Mat[0][3];
    T[1][3] = se3Mat[1][3];
    T[2][3] = se3Mat[2][3];
    T[3][0] = 0.0;
    T[3][1] = 0.0;
    T[3][2] = 0.0;
    T[3][3] = 1.0;
  } else {
    AxisAng3(omgtheta, omghat, &theta);
    MatrixExp3(so3mat, temp);
    for (i = 0; i < 3; i++) {
      for (j = 0; j < 3; j++) {
        T[i][j] = temp[i][j];
      }
    }
    Matrix3MultValue(so3mat, 1.0 / theta, omgmat);
    Matrix3Mult(omgmat, omgmat, temp);
    for (i = 0; i < 3; i++) {
      for (j = 0; j < 3; j++) {
        Gtheta[i][j] = MatI3[i][j] * theta + (1.0 - cos(theta)) * omgmat[i][j] +
                       (theta - sin(theta)) * temp[i][j];
      }
    }
    v[0] = p[0] / theta;
    v[1] = p[1] / theta;
    v[2] = p[2] / theta;
    Matrix3MultVec(Gtheta, v, p);
    T[0][3] = p[0];
    T[1][3] = p[1];
    T[2][3] = p[2];
    T[3][0] = 0.0;
    T[3][1] = 0.0;
    T[3][2] = 0.0;
    T[3][3] = 1.0;
  }
  return;
}


x86 assembly (clang, -O0):
<MatrixExp6>:
push   %rbp
mov    %rsp,%rbp
sub    $0x240,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    -0x220(%rbp),%rdi
xor    %esi,%esi
mov    $0x48,%edx
call   1070 <memset@plt>
movsd  0xe2a(%rip),%xmm0
movsd  %xmm0,-0x220(%rbp)
ff
movsd  0xe1a(%rip),%xmm0
movsd  %xmm0,-0x200(%rbp)
ff
movsd  0xe0a(%rip),%xmm0
movsd  %xmm0,-0x1e0(%rbp)
ff
mov    -0x8(%rbp),%rdi
lea    -0x60(%rbp),%rsi
lea    -0x170(%rbp),%rdx
call   1030 <TransToRp@plt>
lea    -0x60(%rbp),%rdi
lea    -0x1b0(%rbp),%rsi
call   1060 <so3ToVec@plt>
lea    -0x1b0(%rbp),%rdi
call   1040 <Vec3Norm2@plt>
movaps %xmm0,%xmm1
movsd  0xdbf(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1331 <MatrixExp6+0x181>
movl   $0x0,-0x14(%rbp)
cmpl   $0x3,-0x14(%rbp)
jge    12c1 <MatrixExp6+0x111>
movl   $0x0,-0x18(%rbp)
cmpl   $0x3,-0x18(%rbp)
jge    12ae <MatrixExp6+0xfe>
movslq -0x14(%rbp),%rcx
lea    -0x220(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1263 <MatrixExp6+0xb3>
jmp    12b3 <MatrixExp6+0x103>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1252 <MatrixExp6+0xa2>
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x18(%rax)
mov    -0x8(%rbp),%rax
movsd  0x38(%rax),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
mov    -0x8(%rbp),%rax
movsd  0x58(%rax),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x58(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x60(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x68(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x70(%rax)
mov    -0x10(%rbp),%rax
movsd  0xce1(%rip),%xmm0
movsd  %xmm0,0x78(%rax)
jmp    1614 <MatrixExp6+0x464>
lea    -0x1b0(%rbp),%rdi
lea    -0x1d0(%rbp),%rsi
lea    -0x1d8(%rbp),%rdx
call   10a0 <AxisAng3@plt>
lea    -0x60(%rbp),%rdi
lea    -0x100(%rbp),%rsi
call   10b0 <MatrixExp3@plt>
movl   $0x0,-0x14(%rbp)
cmpl   $0x3,-0x14(%rbp)
jge    13d1 <MatrixExp6+0x221>
movl   $0x0,-0x18(%rbp)
cmpl   $0x3,-0x18(%rbp)
jge    13be <MatrixExp6+0x20e>
movslq -0x14(%rbp),%rcx
lea    -0x100(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1373 <MatrixExp6+0x1c3>
jmp    13c3 <MatrixExp6+0x213>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1362 <MatrixExp6+0x1b2>
lea    -0x60(%rbp),%rdi
movsd  0xc2b(%rip),%xmm0
divsd  -0x1d8(%rbp),%xmm0
ff
lea    -0xb0(%rbp),%rsi
call   10d0 <Matrix3MultValue@plt>
lea    -0xb0(%rbp),%rdi
lea    -0xb0(%rbp),%rsi
lea    -0x100(%rbp),%rdx
call   1080 <Matrix3Mult@plt>
movl   $0x0,-0x14(%rbp)
cmpl   $0x3,-0x14(%rbp)
jge    154a <MatrixExp6+0x39a>
movl   $0x0,-0x18(%rbp)
cmpl   $0x3,-0x18(%rbp)
jge    1537 <MatrixExp6+0x387>
movslq -0x14(%rbp),%rcx
lea    -0x220(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x238(%rbp)
ff
movsd  -0x1d8(%rbp),%xmm0
ff
movsd  %xmm0,-0x240(%rbp)
ff
movsd  -0x1d8(%rbp),%xmm0
ff
call   10c0 <cos@plt>
movsd  -0x240(%rbp),%xmm2
ff
movaps %xmm0,%xmm3
movsd  -0x238(%rbp),%xmm0
ff
movsd  0xb80(%rip),%xmm1
subsd  %xmm3,%xmm1
movslq -0x14(%rbp),%rcx
lea    -0xb0(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x230(%rbp)
ff
movsd  -0x1d8(%rbp),%xmm0
ff
movsd  %xmm0,-0x228(%rbp)
ff
movsd  -0x1d8(%rbp),%xmm0
ff
call   1090 <sin@plt>
movsd  -0x230(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  -0x228(%rbp),%xmm0
ff
subsd  %xmm2,%xmm0
movslq -0x14(%rbp),%rcx
lea    -0x100(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movslq -0x14(%rbp),%rcx
lea    -0x150(%rbp),%rax
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1423 <MatrixExp6+0x273>
jmp    153c <MatrixExp6+0x38c>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1412 <MatrixExp6+0x262>
movsd  -0x170(%rbp),%xmm0
ff
divsd  -0x1d8(%rbp),%xmm0
ff
movsd  %xmm0,-0x190(%rbp)
ff
movsd  -0x168(%rbp),%xmm0
ff
divsd  -0x1d8(%rbp),%xmm0
ff
movsd  %xmm0,-0x188(%rbp)
ff
movsd  -0x160(%rbp),%xmm0
ff
divsd  -0x1d8(%rbp),%xmm0
ff
movsd  %xmm0,-0x180(%rbp)
ff
lea    -0x150(%rbp),%rdi
lea    -0x190(%rbp),%rsi
lea    -0x170(%rbp),%rdx
call   1050 <Matrix3MultVec@plt>
movsd  -0x170(%rbp),%xmm0
ff
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x18(%rax)
movsd  -0x168(%rbp),%xmm0
ff
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
movsd  -0x160(%rbp),%xmm0
ff
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x58(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x60(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x68(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x70(%rax)
mov    -0x10(%rbp),%rax
movsd  0x9f9(%rip),%xmm0
movsd  %xmm0,0x78(%rax)
add    $0x240,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<MatrixExp6>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x228,%rsp
mov    %rsi,%rbp
mov    %rdi,%r14
xorpd  %xmm0,%xmm0
movapd %xmm0,0x40(%rsp)
movapd %xmm0,0x60(%rsp)
movapd %xmm0,0x70(%rsp)
movapd %xmm0,0x50(%rsp)
movabs $0x3ff0000000000000,%r13
mov    %r13,0x40(%rsp)
mov    %r13,0x60(%rsp)
mov    %r13,0x80(%rsp)
lea    0x1e0(%rsp),%r15
lea    0x20(%rsp),%rdx
mov    %r15,%rsi
call   1030 <TransToRp@plt>
lea    0x100(%rsp),%r12
mov    %r15,%rdi
mov    %r12,%rsi
call   1060 <so3ToVec@plt>
mov    %r12,%rdi
call   1040 <Vec3Norm2@plt>
movsd  0xdd9(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    1287 <MatrixExp6+0xe7>
mov    0x50(%rsp),%rax
mov    %rax,0x10(%rbp)
movaps 0x40(%rsp),%xmm0
movups %xmm0,0x0(%rbp)
mov    0x68(%rsp),%rax
mov    %rax,0x30(%rbp)
movups 0x58(%rsp),%xmm0
movups %xmm0,0x20(%rbp)
movaps 0x70(%rsp),%xmm0
movups %xmm0,0x40(%rbp)
mov    0x80(%rsp),%rax
mov    %rax,0x50(%rbp)
movsd  0x18(%r14),%xmm0
movsd  %xmm0,0x18(%rbp)
movsd  0x38(%r14),%xmm0
movsd  %xmm0,0x38(%rbp)
movsd  0x58(%r14),%xmm0
jmp    151e <MatrixExp6+0x37e>
lea    0x100(%rsp),%rdi
lea    0x1c0(%rsp),%rsi
lea    0x10(%rsp),%rdx
call   1090 <AxisAng3@plt>
lea    0x1e0(%rsp),%r14
lea    0x90(%rsp),%r15
mov    %r14,%rdi
mov    %r15,%rsi
call   10a0 <MatrixExp3@plt>
mov    0xa0(%rsp),%rax
mov    %rax,0x10(%rbp)
movaps 0x90(%rsp),%xmm0
movups %xmm0,0x0(%rbp)
mov    0xb8(%rsp),%rax
mov    %rax,0x30(%rbp)
movups 0xa8(%rsp),%xmm0
movups %xmm0,0x20(%rbp)
movaps 0xc0(%rsp),%xmm0
movups %xmm0,0x40(%rbp)
mov    0xd0(%rsp),%rax
mov    %rax,0x50(%rbp)
movsd  0xcfc(%rip),%xmm0
divsd  0x10(%rsp),%xmm0
lea    0x170(%rsp),%r12
mov    %r14,%rdi
mov    %r12,%rsi
call   10c0 <Matrix3MultValue@plt>
mov    %r12,%rdi
mov    %r12,%rsi
mov    %r15,%rdx
call   1070 <Matrix3Mult@plt>
xor    %ebx,%ebx
movsd  0xccb(%rip),%xmm0
movsd  %xmm0,0x8(%rsp)
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x18(%rsp)
call   10b0 <cos@plt>
movsd  0xc9f(%rip),%xmm1
subsd  %xmm0,%xmm1
mulsd  0x170(%rsp,%rbx,1),%xmm1
movsd  0x8(%rsp),%xmm0
mulsd  0x18(%rsp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x18(%rsp)
call   1080 <sin@plt>
movsd  0x18(%rsp),%xmm1
subsd  %xmm0,%xmm1
mulsd  0x90(%rsp,%rbx,1),%xmm1
addsd  0x8(%rsp),%xmm1
movsd  %xmm1,0x120(%rsp,%rbx,1)
movsd  0x10(%rsp),%xmm0
movsd  0x48(%rsp,%rbx,1),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
call   10b0 <cos@plt>
movsd  0xc26(%rip),%xmm1
subsd  %xmm0,%xmm1
mulsd  0x178(%rsp,%rbx,1),%xmm1
addsd  0x8(%rsp),%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x18(%rsp)
call   1080 <sin@plt>
movsd  0x18(%rsp),%xmm1
subsd  %xmm0,%xmm1
mulsd  0x98(%rsp,%rbx,1),%xmm1
addsd  0x8(%rsp),%xmm1
movsd  %xmm1,0x128(%rsp,%rbx,1)
movsd  0x10(%rsp),%xmm0
movsd  0x50(%rsp,%rbx,1),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
call   10b0 <cos@plt>
movsd  0xbb7(%rip),%xmm1
subsd  %xmm0,%xmm1
mulsd  0x180(%rsp,%rbx,1),%xmm1
addsd  0x8(%rsp),%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
movsd  %xmm0,0x18(%rsp)
call   1080 <sin@plt>
movsd  0x18(%rsp),%xmm1
subsd  %xmm0,%xmm1
mulsd  0xa0(%rsp,%rbx,1),%xmm1
addsd  0x8(%rsp),%xmm1
movsd  %xmm1,0x130(%rsp,%rbx,1)
cmp    $0x30,%rbx
je     14b8 <MatrixExp6+0x318>
movsd  0x58(%rsp,%rbx,1),%xmm0
movsd  %xmm0,0x8(%rsp)
add    $0x18,%rbx
jmp    1350 <MatrixExp6+0x1b0>
movsd  0x10(%rsp),%xmm0
movapd 0x20(%rsp),%xmm1
movsd  0x30(%rsp),%xmm2
divsd  %xmm0,%xmm2
unpcklpd %xmm0,%xmm0
divpd  %xmm0,%xmm1
movapd %xmm1,0xe0(%rsp)
movsd  %xmm2,0xf0(%rsp)
lea    0x120(%rsp),%rdi
lea    0xe0(%rsp),%rsi
lea    0x20(%rsp),%rdx
call   1050 <Matrix3MultVec@plt>
movsd  0x20(%rsp),%xmm0
movsd  %xmm0,0x18(%rbp)
movsd  0x28(%rsp),%xmm0
movsd  %xmm0,0x38(%rbp)
movsd  0x30(%rsp),%xmm0
movsd  %xmm0,0x58(%rbp)
xorps  %xmm0,%xmm0
movups %xmm0,0x60(%rbp)
movq   $0x0,0x70(%rbp)
mov    %r13,0x78(%rbp)
add    $0x228,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @MatrixExp6([4 x double]* %0, [4 x double]* %1) {
%3 = alloca [4 x double]*
%4 = alloca [4 x double]*
%5 = alloca i32
%6 = alloca i32
%7 = alloca [3 x [3 x double]]
%8 = alloca [3 x [3 x double]]
%9 = alloca [3 x [3 x double]]
%10 = alloca [3 x [3 x double]]
%11 = alloca [3 x double]
%12 = alloca [3 x double]
%13 = alloca [3 x double]
%14 = alloca [3 x double]
%15 = alloca double
%16 = alloca [3 x [3 x double]]
store [4 x double]* %0, [4 x double]** %3
store [4 x double]* %1, [4 x double]** %4
%17 = bitcast [3 x [3 x double]]* %16 to i8*
%18 = bitcast i8* %17 to [3 x [3 x double]]*
%19 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %18, i32 0, i32 0
%20 = getelementptr inbounds [3 x double], [3 x double]* %19, i32 0, i32 0
store double 1.000000e+00, double* %20
%21 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %18, i32 0, i32 1
%22 = getelementptr inbounds [3 x double], [3 x double]* %21, i32 0, i32 1
store double 1.000000e+00, double* %22
%23 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %18, i32 0, i32 2
%24 = getelementptr inbounds [3 x double], [3 x double]* %23, i32 0, i32 2
store double 1.000000e+00, double* %24
%25 = load [4 x double]*, [4 x double]** %3
%26 = bitcast [4 x double]* %25 to double**
%27 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %7, i64 0, i64 0
%28 = bitcast [3 x double]* %27 to double**
%29 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%30 = call i32 @TransToRp(double** %26, double** %28, double* %29)
%31 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %7, i64 0, i64 0
%32 = bitcast [3 x double]* %31 to double**
%33 = getelementptr inbounds [3 x double], [3 x double]* %13, i64 0, i64 0
%34 = call i32 @so3ToVec(double** %32, double* %33)
%35 = getelementptr inbounds [3 x double], [3 x double]* %13, i64 0, i64 0
%36 = call double @Vec3Norm2(double* %35)
%37 = fcmp olt double %36, 0x3EB0C6F7A0B5ED8D
br i1 %37, label %38, label %102
38: ; preds = %2
store i32 0, i32* %5
br label %39
39: ; preds = %65, %38
%40 = load i32, i32* %5
%41 = icmp slt i32 %40, 3
br i1 %41, label %42, label %68
42: ; preds = %39
store i32 0, i32* %6
br label %43
43: ; preds = %61, %42
%44 = load i32, i32* %6
%45 = icmp slt i32 %44, 3
br i1 %45, label %46, label %64
46: ; preds = %43
%47 = load i32, i32* %5
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %16, i64 0, i64 %48
%50 = load i32, i32* %6
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds [3 x double], [3 x double]* %49, i64 0, i64 %51
%53 = load double, double* %52
%54 = load [4 x double]*, [4 x double]** %4
%55 = load i32, i32* %5
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds [4 x double], [4 x double]* %54, i64 %56
%58 = load i32, i32* %6
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds [4 x double], [4 x double]* %57, i64 0, i64 %59
store double %53, double* %60
br label %61
61: ; preds = %46
%62 = load i32, i32* %6
%63 = add nsw i32 %62, 1
store i32 %63, i32* %6
br label %43
64: ; preds = %43
br label %65
65: ; preds = %64
%66 = load i32, i32* %5
%67 = add nsw i32 %66, 1
store i32 %67, i32* %5
br label %39
68: ; preds = %39
%69 = load [4 x double]*, [4 x double]** %3
%70 = getelementptr inbounds [4 x double], [4 x double]* %69, i64 0
%71 = getelementptr inbounds [4 x double], [4 x double]* %70, i64 0, i64 3
%72 = load double, double* %71
%73 = load [4 x double]*, [4 x double]** %4
%74 = getelementptr inbounds [4 x double], [4 x double]* %73, i64 0
%75 = getelementptr inbounds [4 x double], [4 x double]* %74, i64 0, i64 3
store double %72, double* %75
%76 = load [4 x double]*, [4 x double]** %3
%77 = getelementptr inbounds [4 x double], [4 x double]* %76, i64 1
%78 = getelementptr inbounds [4 x double], [4 x double]* %77, i64 0, i64 3
%79 = load double, double* %78
%80 = load [4 x double]*, [4 x double]** %4
%81 = getelementptr inbounds [4 x double], [4 x double]* %80, i64 1
%82 = getelementptr inbounds [4 x double], [4 x double]* %81, i64 0, i64 3
store double %79, double* %82
%83 = load [4 x double]*, [4 x double]** %3
%84 = getelementptr inbounds [4 x double], [4 x double]* %83, i64 2
%85 = getelementptr inbounds [4 x double], [4 x double]* %84, i64 0, i64 3
%86 = load double, double* %85
%87 = load [4 x double]*, [4 x double]** %4
%88 = getelementptr inbounds [4 x double], [4 x double]* %87, i64 2
%89 = getelementptr inbounds [4 x double], [4 x double]* %88, i64 0, i64 3
store double %86, double* %89
%90 = load [4 x double]*, [4 x double]** %4
%91 = getelementptr inbounds [4 x double], [4 x double]* %90, i64 3
%92 = getelementptr inbounds [4 x double], [4 x double]* %91, i64 0, i64 0
store double 0.000000e+00, double* %92
%93 = load [4 x double]*, [4 x double]** %4
%94 = getelementptr inbounds [4 x double], [4 x double]* %93, i64 3
%95 = getelementptr inbounds [4 x double], [4 x double]* %94, i64 0, i64 1
store double 0.000000e+00, double* %95
%96 = load [4 x double]*, [4 x double]** %4
%97 = getelementptr inbounds [4 x double], [4 x double]* %96, i64 3
%98 = getelementptr inbounds [4 x double], [4 x double]* %97, i64 0, i64 2
store double 0.000000e+00, double* %98
%99 = load [4 x double]*, [4 x double]** %4
%100 = getelementptr inbounds [4 x double], [4 x double]* %99, i64 3
%101 = getelementptr inbounds [4 x double], [4 x double]* %100, i64 0, i64 3
store double 1.000000e+00, double* %101
br label %256
102: ; preds = %2
%103 = getelementptr inbounds [3 x double], [3 x double]* %13, i64 0, i64 0
%104 = getelementptr inbounds [3 x double], [3 x double]* %14, i64 0, i64 0
%105 = call i32 @AxisAng3(double* %103, double* %104, double* %15)
%106 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %7, i64 0, i64 0
%107 = bitcast [3 x double]* %106 to double**
%108 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %9, i64 0, i64 0
%109 = bitcast [3 x double]* %108 to double**
%110 = call i32 @MatrixExp3(double** %107, double** %109)
store i32 0, i32* %5
br label %111
111: ; preds = %137, %102
%112 = load i32, i32* %5
%113 = icmp slt i32 %112, 3
br i1 %113, label %114, label %140
114: ; preds = %111
store i32 0, i32* %6
br label %115
115: ; preds = %133, %114
%116 = load i32, i32* %6
%117 = icmp slt i32 %116, 3
br i1 %117, label %118, label %136
118: ; preds = %115
%119 = load i32, i32* %5
%120 = sext i32 %119 to i64
%121 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %9, i64 0, i64 %120
%122 = load i32, i32* %6
%123 = sext i32 %122 to i64
%124 = getelementptr inbounds [3 x double], [3 x double]* %121, i64 0, i64 %123
%125 = load double, double* %124
%126 = load [4 x double]*, [4 x double]** %4
%127 = load i32, i32* %5
%128 = sext i32 %127 to i64
%129 = getelementptr inbounds [4 x double], [4 x double]* %126, i64 %128
%130 = load i32, i32* %6
%131 = sext i32 %130 to i64
%132 = getelementptr inbounds [4 x double], [4 x double]* %129, i64 0, i64 %131
store double %125, double* %132
br label %133
133: ; preds = %118
%134 = load i32, i32* %6
%135 = add nsw i32 %134, 1
store i32 %135, i32* %6
br label %115
136: ; preds = %115
br label %137
137: ; preds = %136
%138 = load i32, i32* %5
%139 = add nsw i32 %138, 1
store i32 %139, i32* %5
br label %111
140: ; preds = %111
%141 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %7, i64 0, i64 0
%142 = bitcast [3 x double]* %141 to double**
%143 = load double, double* %15
%144 = fdiv double 1.000000e+00, %143
%145 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 0
%146 = bitcast [3 x double]* %145 to double**
%147 = call i32 @Matrix3MultValue(double** %142, double %144, double** %146)
%148 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 0
%149 = bitcast [3 x double]* %148 to double**
%150 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 0
%151 = bitcast [3 x double]* %150 to double**
%152 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %9, i64 0, i64 0
%153 = bitcast [3 x double]* %152 to double**
%154 = call i32 @Matrix3Mult(double** %149, double** %151, double** %153)
store i32 0, i32* %5
br label %155
155: ; preds = %205, %140
%156 = load i32, i32* %5
%157 = icmp slt i32 %156, 3
br i1 %157, label %158, label %208
158: ; preds = %155
store i32 0, i32* %6
br label %159
159: ; preds = %201, %158
%160 = load i32, i32* %6
%161 = icmp slt i32 %160, 3
br i1 %161, label %162, label %204
162: ; preds = %159
%163 = load i32, i32* %5
%164 = sext i32 %163 to i64
%165 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %16, i64 0, i64 %164
%166 = load i32, i32* %6
%167 = sext i32 %166 to i64
%168 = getelementptr inbounds [3 x double], [3 x double]* %165, i64 0, i64 %167
%169 = load double, double* %168
%170 = load double, double* %15
%171 = load double, double* %15
%172 = call double @cos(double %171)
%173 = fsub double 1.000000e+00, %172
%174 = load i32, i32* %5
%175 = sext i32 %174 to i64
%176 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %8, i64 0, i64 %175
%177 = load i32, i32* %6
%178 = sext i32 %177 to i64
%179 = getelementptr inbounds [3 x double], [3 x double]* %176, i64 0, i64 %178
%180 = load double, double* %179
%181 = fmul double %173, %180
%182 = call double @llvm.fmuladd.f64(double %169, double %170, double %181)
%183 = load double, double* %15
%184 = load double, double* %15
%185 = call double @sin(double %184)
%186 = fsub double %183, %185
%187 = load i32, i32* %5
%188 = sext i32 %187 to i64
%189 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %9, i64 0, i64 %188
%190 = load i32, i32* %6
%191 = sext i32 %190 to i64
%192 = getelementptr inbounds [3 x double], [3 x double]* %189, i64 0, i64 %191
%193 = load double, double* %192
%194 = call double @llvm.fmuladd.f64(double %186, double %193, double %182)
%195 = load i32, i32* %5
%196 = sext i32 %195 to i64
%197 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %10, i64 0, i64 %196
%198 = load i32, i32* %6
%199 = sext i32 %198 to i64
%200 = getelementptr inbounds [3 x double], [3 x double]* %197, i64 0, i64 %199
store double %194, double* %200
br label %201
201: ; preds = %162
%202 = load i32, i32* %6
%203 = add nsw i32 %202, 1
store i32 %203, i32* %6
br label %159
204: ; preds = %159
br label %205
205: ; preds = %204
%206 = load i32, i32* %5
%207 = add nsw i32 %206, 1
store i32 %207, i32* %5
br label %155
208: ; preds = %155
%209 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%210 = load double, double* %209
%211 = load double, double* %15
%212 = fdiv double %210, %211
%213 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
store double %212, double* %213
%214 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 1
%215 = load double, double* %214
%216 = load double, double* %15
%217 = fdiv double %215, %216
%218 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
store double %217, double* %218
%219 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 2
%220 = load double, double* %219
%221 = load double, double* %15
%222 = fdiv double %220, %221
%223 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 2
store double %222, double* %223
%224 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %10, i64 0, i64 0
%225 = bitcast [3 x double]* %224 to double**
%226 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%227 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%228 = call i32 @Matrix3MultVec(double** %225, double* %226, double* %227)
%229 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%230 = load double, double* %229
%231 = load [4 x double]*, [4 x double]** %4
%232 = getelementptr inbounds [4 x double], [4 x double]* %231, i64 0
%233 = getelementptr inbounds [4 x double], [4 x double]* %232, i64 0, i64 3
store double %230, double* %233
%234 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 1
%235 = load double, double* %234
%236 = load [4 x double]*, [4 x double]** %4
%237 = getelementptr inbounds [4 x double], [4 x double]* %236, i64 1
%238 = getelementptr inbounds [4 x double], [4 x double]* %237, i64 0, i64 3
store double %235, double* %238
%239 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 2
%240 = load double, double* %239
%241 = load [4 x double]*, [4 x double]** %4
%242 = getelementptr inbounds [4 x double], [4 x double]* %241, i64 2
%243 = getelementptr inbounds [4 x double], [4 x double]* %242, i64 0, i64 3
store double %240, double* %243
%244 = load [4 x double]*, [4 x double]** %4
%245 = getelementptr inbounds [4 x double], [4 x double]* %244, i64 3
%246 = getelementptr inbounds [4 x double], [4 x double]* %245, i64 0, i64 0
store double 0.000000e+00, double* %246
%247 = load [4 x double]*, [4 x double]** %4
%248 = getelementptr inbounds [4 x double], [4 x double]* %247, i64 3
%249 = getelementptr inbounds [4 x double], [4 x double]* %248, i64 0, i64 1
store double 0.000000e+00, double* %249
%250 = load [4 x double]*, [4 x double]** %4
%251 = getelementptr inbounds [4 x double], [4 x double]* %250, i64 3
%252 = getelementptr inbounds [4 x double], [4 x double]* %251, i64 0, i64 2
store double 0.000000e+00, double* %252
%253 = load [4 x double]*, [4 x double]** %4
%254 = getelementptr inbounds [4 x double], [4 x double]* %253, i64 3
%255 = getelementptr inbounds [4 x double], [4 x double]* %254, i64 0, i64 3
store double 1.000000e+00, double* %255
br label %256
256: ; preds = %208, %68
ret void
}

LLVM IR (-O2):
define void @MatrixExp6([4 x double]* %0, [4 x double]* nocapture writeonly %1) {
%3 = alloca [3 x [3 x double]]
%4 = alloca [3 x [3 x double]]
%5 = alloca [3 x [3 x double]]
%6 = alloca [3 x [3 x double]]
%7 = alloca [3 x double]
%8 = alloca [3 x double]
%9 = alloca [3 x double]
%10 = alloca [3 x double]
%11 = alloca double
%12 = alloca [3 x [3 x double]]
%13 = bitcast [3 x [3 x double]]* %3 to i8*
%14 = bitcast [3 x [3 x double]]* %4 to i8*
%15 = bitcast [3 x [3 x double]]* %5 to i8*
%16 = bitcast [3 x [3 x double]]* %6 to i8*
%17 = bitcast [3 x double]* %7 to i8*
%18 = bitcast [3 x double]* %8 to i8*
%19 = bitcast [3 x double]* %9 to i8*
%20 = bitcast [3 x double]* %10 to i8*
%21 = bitcast double* %11 to i8*
%22 = bitcast [3 x [3 x double]]* %12 to i8*
%23 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 0, i64 0
store double 1.000000e+00, double* %23
%24 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 1, i64 1
store double 1.000000e+00, double* %24
%25 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 2, i64 2
store double 1.000000e+00, double* %25
%26 = bitcast [4 x double]* %0 to double**
%27 = bitcast [3 x [3 x double]]* %3 to double**
%28 = getelementptr inbounds [3 x double], [3 x double]* %7, i64 0, i64 0
%29 = call i32 @TransToRp(double** %26, double** %27, double* %28)
%30 = getelementptr inbounds [3 x double], [3 x double]* %9, i64 0, i64 0
%31 = call i32 @so3ToVec(double** %27, double* %30)
%32 = call double @Vec3Norm2(double* %30)
%33 = fcmp olt double %32, 0x3EB0C6F7A0B5ED8D
br i1 %33, label %34, label %53
34: ; preds = %2
%35 = bitcast [4 x double]* %1 to i8*
%36 = bitcast [3 x [3 x double]]* %12 to i8*
%37 = getelementptr [4 x double], [4 x double]* %1, i64 1, i64 0
%38 = bitcast double* %37 to i8*
%39 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 1, i64 0
%40 = bitcast double* %39 to i8*
%41 = getelementptr [4 x double], [4 x double]* %1, i64 2, i64 0
%42 = bitcast double* %41 to i8*
%43 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 2, i64 0
%44 = bitcast double* %43 to i8*
%45 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 0, i64 3
%46 = load double, double* %45
%47 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 0, i64 3
store double %46, double* %47
%48 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 1, i64 3
%49 = load double, double* %48
%50 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 1, i64 3
store double %49, double* %50
%51 = getelementptr inbounds [4 x double], [4 x double]* %0, i64 2, i64 3
%52 = load double, double* %51
br label %148
53: ; preds = %2
%54 = getelementptr inbounds [3 x double], [3 x double]* %10, i64 0, i64 0
%55 = call i32 @AxisAng3(double* %30, double* %54, double* %11)
%56 = bitcast [3 x [3 x double]]* %5 to double**
%57 = call i32 @MatrixExp3(double** %27, double** %56)
%58 = bitcast [4 x double]* %1 to i8*
%59 = bitcast [3 x [3 x double]]* %5 to i8*
%60 = getelementptr [4 x double], [4 x double]* %1, i64 1, i64 0
%61 = bitcast double* %60 to i8*
%62 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 1, i64 0
%63 = bitcast double* %62 to i8*
%64 = getelementptr [4 x double], [4 x double]* %1, i64 2, i64 0
%65 = bitcast double* %64 to i8*
%66 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 2, i64 0
%67 = bitcast double* %66 to i8*
%68 = load double, double* %11
%69 = fdiv double 1.000000e+00, %68
%70 = bitcast [3 x [3 x double]]* %4 to double**
%71 = call i32 @Matrix3MultValue(double** %27, double %69, double** %70)
%72 = call i32 @Matrix3Mult(double** %70, double** %70, double** %56)
br label %73
73: ; preds = %124, %53
%74 = phi double [ 1.000000e+00, %53 ], [ %126, %124 ]
%75 = phi i64 [ 0, %53 ], [ %122, %124 ]
%76 = load double, double* %11
%77 = call double @cos(double %76)
%78 = fsub double 1.000000e+00, %77
%79 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 %75, i64 0
%80 = load double, double* %79
%81 = fmul double %78, %80
%82 = call double @llvm.fmuladd.f64(double %74, double %76, double %81)
%83 = load double, double* %11
%84 = call double @sin(double %83)
%85 = fsub double %83, %84
%86 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 %75, i64 0
%87 = load double, double* %86
%88 = call double @llvm.fmuladd.f64(double %85, double %87, double %82)
%89 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 %75, i64 0
store double %88, double* %89
%90 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 %75, i64 1
%91 = load double, double* %90
%92 = load double, double* %11
%93 = call double @cos(double %92)
%94 = fsub double 1.000000e+00, %93
%95 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 %75, i64 1
%96 = load double, double* %95
%97 = fmul double %94, %96
%98 = call double @llvm.fmuladd.f64(double %91, double %92, double %97)
%99 = load double, double* %11
%100 = call double @sin(double %99)
%101 = fsub double %99, %100
%102 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 %75, i64 1
%103 = load double, double* %102
%104 = call double @llvm.fmuladd.f64(double %101, double %103, double %98)
%105 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 %75, i64 1
store double %104, double* %105
%106 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 %75, i64 2
%107 = load double, double* %106
%108 = load double, double* %11
%109 = call double @cos(double %108)
%110 = fsub double 1.000000e+00, %109
%111 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 %75, i64 2
%112 = load double, double* %111
%113 = fmul double %110, %112
%114 = call double @llvm.fmuladd.f64(double %107, double %108, double %113)
%115 = load double, double* %11
%116 = call double @sin(double %115)
%117 = fsub double %115, %116
%118 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 %75, i64 2
%119 = load double, double* %118
%120 = call double @llvm.fmuladd.f64(double %117, double %119, double %114)
%121 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %6, i64 0, i64 %75, i64 2
store double %120, double* %121
%122 = add nuw nsw i64 %75, 1
%123 = icmp eq i64 %122, 3
br i1 %123, label %127, label %124
124: ; preds = %73
%125 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %12, i64 0, i64 %122, i64 0
%126 = load double, double* %125
br label %73
127: ; preds = %73
%128 = load double, double* %11
%129 = getelementptr inbounds [3 x double], [3 x double]* %8, i64 0, i64 0
%130 = getelementptr inbounds [3 x double], [3 x double]* %7, i64 0, i64 1
%131 = bitcast [3 x double]* %7 to <2 x double>*
%132 = load <2 x double>, <2 x double>* %131
%133 = insertelement <2 x double> poison, double %128, i64 0
%134 = shufflevector <2 x double> %133, <2 x double> poison, <2 x i32> zeroinitializer
%135 = fdiv <2 x double> %132, %134
%136 = bitcast [3 x double]* %8 to <2 x double>*
store <2 x double> %135, <2 x double>* %136
%137 = getelementptr inbounds [3 x double], [3 x double]* %7, i64 0, i64 2
%138 = load double, double* %137
%139 = fdiv double %138, %128
%140 = getelementptr inbounds [3 x double], [3 x double]* %8, i64 0, i64 2
store double %139, double* %140
%141 = bitcast [3 x [3 x double]]* %6 to double**
%142 = call i32 @Matrix3MultVec(double** %141, double* %129, double* %28)
%143 = load double, double* %28
%144 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 0, i64 3
store double %143, double* %144
%145 = load double, double* %130
%146 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 1, i64 3
store double %145, double* %146
%147 = load double, double* %137
br label %148
148: ; preds = %127, %34
%149 = phi double [ %147, %127 ], [ %52, %34 ]
%150 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 2, i64 3
store double %149, double* %150
%151 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 3, i64 0
%152 = getelementptr inbounds [4 x double], [4 x double]* %1, i64 3, i64 3
%153 = bitcast double* %151 to i8*
store double 1.000000e+00, double* %152
ret void
}