#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*/ Matrix4Equal(double **, double **);
int /*<<< orphan*/ Matrix4Mult(double **, double **, double **);
int /*<<< orphan*/ MatrixExp6(double **, double **);
int /*<<< orphan*/ VecTose3(double *, double **);
void FKinSpace(double M[4][4], int JointNum, double *Slist, double *thetalist,
               double T[4][4]) {
  int i, j, k, l;
  double se3mat[4][4];
  double T2[4][4];
  double exp6[4][4];
  double V[6];
  Matrix4Equal(M, T);
  for (i = JointNum - 1; i >= 0; i--) {
    for (l = 0; l < 6; l++) {
      V[l] = Slist[l * JointNum + i];
    }
    VecTose3(V, se3mat);
    for (j = 0; j < 4; j++) {
      for (k = 0; k < 4; k++) {
        se3mat[j][k] = se3mat[j][k] * thetalist[i];
      }
    }
    MatrixExp6(se3mat, exp6);
    Matrix4Mult(exp6, T, T2);
    Matrix4Equal(T2, T);
  }
  return;
}


x86 assembly (clang, -O0):
<FKinSpace>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1f0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1050 <Matrix4Equal@plt>
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x2c(%rbp)
jl     12a1 <FKinSpace+0x161>
movl   $0x0,-0x38(%rbp)
cmpl   $0x6,-0x38(%rbp)
jge    11c0 <FKinSpace+0x80>
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%ecx
imul   -0xc(%rbp),%ecx
add    -0x2c(%rbp),%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movslq -0x38(%rbp),%rax
movsd  %xmm0,-0x1f0(%rbp,%rax,8)
ff ff
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    1185 <FKinSpace+0x45>
lea    -0x1f0(%rbp),%rdi
lea    -0xc0(%rbp),%rsi
call   1060 <VecTose3@plt>
movl   $0x0,-0x30(%rbp)
cmpl   $0x4,-0x30(%rbp)
jge    1259 <FKinSpace+0x119>
movl   $0x0,-0x34(%rbp)
cmpl   $0x4,-0x34(%rbp)
jge    1246 <FKinSpace+0x106>
movslq -0x30(%rbp),%rcx
lea    -0xc0(%rbp),%rax
shl    $0x5,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
movslq -0x30(%rbp),%rcx
lea    -0xc0(%rbp),%rax
shl    $0x5,%rcx
add    %rcx,%rax
movslq -0x34(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11eb <FKinSpace+0xab>
jmp    124b <FKinSpace+0x10b>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11da <FKinSpace+0x9a>
lea    -0xc0(%rbp),%rdi
lea    -0x1c0(%rbp),%rsi
call   1030 <MatrixExp6@plt>
lea    -0x1c0(%rbp),%rdi
mov    -0x28(%rbp),%rsi
lea    -0x140(%rbp),%rdx
call   1040 <Matrix4Mult@plt>
lea    -0x140(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1050 <Matrix4Equal@plt>
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x2c(%rbp)
jmp    1174 <FKinSpace+0x34>
add    $0x1f0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<FKinSpace>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x1c8,%rsp
mov    %r8,%r12
mov    %rcx,0x8(%rsp)
mov    %rdx,%rbx
mov    %esi,%ebp
mov    %r8,%rsi
call   1050 <Matrix4Equal@plt>
test   %ebp,%ebp
jle    12e3 <FKinSpace+0x1a3>
mov    %ebp,%r14d
lea    0x1(%r14),%r13
lea    0x0(,%r14,8),%r15
nopl   (%rax)
lea    (%rbx,%r13,8),%rax
movsd  -0x10(%rbx,%r13,8),%xmm0
movsd  %xmm0,0x10(%rsp)
lea    (%r15,%rax,1),%rcx
add    $0xfffffffffffffff0,%rcx
movsd  -0x10(%rax,%r14,8),%xmm0
movsd  %xmm0,0x18(%rsp)
movsd  (%rcx,%r14,8),%xmm0
add    %r15,%rcx
movsd  %xmm0,0x20(%rsp)
movsd  (%rcx,%r14,8),%xmm0
add    %r15,%rcx
movsd  %xmm0,0x28(%rsp)
movsd  (%rcx,%r14,8),%xmm0
add    %r15,%rcx
movsd  %xmm0,0x30(%rsp)
movsd  (%rcx,%r14,8),%xmm0
movsd  %xmm0,0x38(%rsp)
lea    0x10(%rsp),%rdi
mov    %r12,%rbp
lea    0x40(%rsp),%r12
mov    %r12,%rsi
call   1060 <VecTose3@plt>
mov    0x8(%rsp),%rax
movsd  -0x10(%rax,%r13,8),%xmm0
unpcklpd %xmm0,%xmm0
movapd 0x40(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0x40(%rsp)
movapd 0x50(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0x50(%rsp)
movapd 0x60(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0x60(%rsp)
movapd 0x70(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0x70(%rsp)
movapd 0x80(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0x80(%rsp)
movapd 0x90(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0x90(%rsp)
movapd 0xa0(%rsp),%xmm1
mulpd  %xmm0,%xmm1
movapd %xmm1,0xa0(%rsp)
mulpd  0xb0(%rsp),%xmm0
movapd %xmm0,0xb0(%rsp)
mov    %r12,%rdi
mov    %rbp,%r12
mov    %rbx,%rbp
lea    0xc0(%rsp),%rbx
mov    %rbx,%rsi
call   1030 <MatrixExp6@plt>
mov    %rbx,%rdi
mov    %rbp,%rbx
mov    %r12,%rsi
lea    0x140(%rsp),%rbp
mov    %rbp,%rdx
call   1040 <Matrix4Mult@plt>
mov    %rbp,%rdi
mov    %r12,%rsi
call   1050 <Matrix4Equal@plt>
add    $0xffffffffffffffff,%r13
cmp    $0x1,%r13
ja     1180 <FKinSpace+0x40>
add    $0x1c8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @FKinSpace([4 x double]* %0, i32 %1, double* nocapture %2, double* nocapture %3, [4 x double]* %4) {
%6 = alloca [4 x [4 x double]]
%7 = alloca [4 x [4 x double]]
%8 = alloca [4 x [4 x double]]
%9 = alloca [6 x double]
%10 = bitcast [4 x [4 x double]]* %6 to i8*
%11 = bitcast [4 x [4 x double]]* %7 to i8*
%12 = bitcast [4 x [4 x double]]* %8 to i8*
%13 = bitcast [6 x double]* %9 to i8*
%14 = bitcast [4 x double]* %0 to double**
%15 = bitcast [4 x double]* %4 to double**
%16 = tail call i32 @Matrix4Equal(double** %14, double** %15)
%17 = icmp sgt i32 %1, 0
br i1 %17, label %18, label %101
18: ; preds = %5
%19 = getelementptr inbounds [6 x double], [6 x double]* %9, i64 0, i64 0
%20 = bitcast [4 x [4 x double]]* %6 to double**
%21 = bitcast [4 x [4 x double]]* %8 to double**
%22 = bitcast [4 x [4 x double]]* %7 to double**
%23 = zext i32 %1 to i64
%24 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 3, i64 0
%25 = getelementptr inbounds [6 x double], [6 x double]* %9, i64 0, i64 1
%26 = shl nuw nsw i64 %23, 1
%27 = getelementptr inbounds [6 x double], [6 x double]* %9, i64 0, i64 2
%28 = mul nuw nsw i64 %23, 3
%29 = getelementptr inbounds [6 x double], [6 x double]* %9, i64 0, i64 3
%30 = shl nuw nsw i64 %23, 2
%31 = getelementptr inbounds [6 x double], [6 x double]* %9, i64 0, i64 4
%32 = mul nuw nsw i64 %23, 5
%33 = getelementptr inbounds [6 x double], [6 x double]* %9, i64 0, i64 5
%34 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 0, i64 2
%35 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 1, i64 0
%36 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 1, i64 2
%37 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 2, i64 0
%38 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 2, i64 2
%39 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %6, i64 0, i64 3, i64 2
%40 = bitcast [4 x [4 x double]]* %6 to <2 x double>*
%41 = bitcast [4 x [4 x double]]* %6 to <2 x double>*
%42 = bitcast double* %34 to <2 x double>*
%43 = bitcast double* %34 to <2 x double>*
%44 = bitcast double* %35 to <2 x double>*
%45 = bitcast double* %35 to <2 x double>*
%46 = bitcast double* %36 to <2 x double>*
%47 = bitcast double* %36 to <2 x double>*
%48 = bitcast double* %37 to <2 x double>*
%49 = bitcast double* %37 to <2 x double>*
%50 = bitcast double* %38 to <2 x double>*
%51 = bitcast double* %38 to <2 x double>*
%52 = bitcast double* %24 to <2 x double>*
%53 = bitcast double* %24 to <2 x double>*
%54 = bitcast double* %39 to <2 x double>*
%55 = bitcast double* %39 to <2 x double>*
br label %56
56: ; preds = %18, %56
%57 = phi i64 [ %23, %18 ], [ %58, %56 ]
%58 = add nsw i64 %57, -1
%59 = getelementptr inbounds double, double* %2, i64 %58
%60 = load double, double* %59
store double %60, double* %19
%61 = add nsw i64 %58, %23
%62 = getelementptr inbounds double, double* %2, i64 %61
%63 = load double, double* %62
store double %63, double* %25
%64 = add nsw i64 %26, %58
%65 = getelementptr inbounds double, double* %2, i64 %64
%66 = load double, double* %65
store double %66, double* %27
%67 = add nsw i64 %28, %58
%68 = getelementptr inbounds double, double* %2, i64 %67
%69 = load double, double* %68
store double %69, double* %29
%70 = add nsw i64 %30, %58
%71 = getelementptr inbounds double, double* %2, i64 %70
%72 = load double, double* %71
store double %72, double* %31
%73 = add nsw i64 %32, %58
%74 = getelementptr inbounds double, double* %2, i64 %73
%75 = load double, double* %74
store double %75, double* %33
%76 = call i32 @VecTose3(double* %19, double** %20)
%77 = getelementptr inbounds double, double* %3, i64 %58
%78 = load double, double* %77
%79 = load <2 x double>, <2 x double>* %40
%80 = insertelement <2 x double> poison, double %78, i64 0
%81 = shufflevector <2 x double> %80, <2 x double> poison, <2 x i32> zeroinitializer
%82 = fmul <2 x double> %79, %81
store <2 x double> %82, <2 x double>* %41
%83 = load <2 x double>, <2 x double>* %42
%84 = fmul <2 x double> %83, %81
store <2 x double> %84, <2 x double>* %43
%85 = load <2 x double>, <2 x double>* %44
%86 = fmul <2 x double> %85, %81
store <2 x double> %86, <2 x double>* %45
%87 = load <2 x double>, <2 x double>* %46
%88 = fmul <2 x double> %87, %81
store <2 x double> %88, <2 x double>* %47
%89 = load <2 x double>, <2 x double>* %48
%90 = fmul <2 x double> %89, %81
store <2 x double> %90, <2 x double>* %49
%91 = load <2 x double>, <2 x double>* %50
%92 = fmul <2 x double> %91, %81
store <2 x double> %92, <2 x double>* %51
%93 = load <2 x double>, <2 x double>* %52
%94 = fmul <2 x double> %93, %81
store <2 x double> %94, <2 x double>* %53
%95 = load <2 x double>, <2 x double>* %54
%96 = fmul <2 x double> %95, %81
store <2 x double> %96, <2 x double>* %55
%97 = call i32 @MatrixExp6(double** %20, double** %21)
%98 = call i32 @Matrix4Mult(double** %21, double** %15, double** %22)
%99 = call i32 @Matrix4Equal(double** %22, double** %15)
%100 = icmp ugt i64 %57, 1
br i1 %100, label %56, label %101
101: ; preds = %56, %5
ret void
}