#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 FKinBody(double M[4][4], int JointNum, double *Blist, 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 = 0; i < JointNum; i++) {
    for (l = 0; l < 6; l++) {
      V[l] = Blist[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(T, exp6, T2);
    Matrix4Equal(T2, T);
  }
  return;
}


x86 assembly (clang, -O0):
<FKinBody>:
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>
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    12a1 <FKinBody+0x161>
movl   $0x0,-0x38(%rbp)
cmpl   $0x6,-0x38(%rbp)
jge    11c0 <FKinBody+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 <FKinBody+0x45>
lea    -0x1f0(%rbp),%rdi
lea    -0xc0(%rbp),%rsi
call   1060 <VecTose3@plt>
movl   $0x0,-0x30(%rbp)
cmpl   $0x4,-0x30(%rbp)
jge    1259 <FKinBody+0x119>
movl   $0x0,-0x34(%rbp)
cmpl   $0x4,-0x34(%rbp)
jge    1246 <FKinBody+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 <FKinBody+0xab>
jmp    124b <FKinBody+0x10b>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11da <FKinBody+0x9a>
lea    -0xc0(%rbp),%rdi
lea    -0x1c0(%rbp),%rsi
call   1030 <MatrixExp6@plt>
mov    -0x28(%rbp),%rdi
lea    -0x1c0(%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    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1172 <FKinBody+0x32>
add    $0x1f0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<FKinBody>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x1c8,%rsp
mov    %r8,%r13
mov    %rcx,0x8(%rsp)
mov    %rdx,%r15
mov    %esi,%ebp
mov    %r8,%rsi
call   1050 <Matrix4Equal@plt>
test   %ebp,%ebp
jle    12d1 <FKinBody+0x191>
mov    %ebp,%r14d
lea    0x0(,%r14,8),%rax
mov    %rax,(%rsp)
xor    %ebp,%ebp
nop
lea    (%r15,%rbp,8),%rax
movsd  (%r15,%rbp,8),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  (%rax,%r14,8),%xmm0
mov    (%rsp),%rcx
add    %rcx,%rax
movsd  %xmm0,0x18(%rsp)
movsd  (%rax,%r14,8),%xmm0
add    %rcx,%rax
movsd  %xmm0,0x20(%rsp)
movsd  (%rax,%r14,8),%xmm0
add    %rcx,%rax
movsd  %xmm0,0x28(%rsp)
movsd  (%rax,%r14,8),%xmm0
add    %rcx,%rax
movsd  %xmm0,0x30(%rsp)
movsd  (%rax,%r14,8),%xmm0
movsd  %xmm0,0x38(%rsp)
lea    0x10(%rsp),%rdi
lea    0x40(%rsp),%r12
mov    %r12,%rsi
call   1060 <VecTose3@plt>
mov    0x8(%rsp),%rax
movsd  (%rax,%rbp,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
lea    0xc0(%rsp),%rbx
mov    %rbx,%rsi
call   1030 <MatrixExp6@plt>
mov    %r13,%rdi
mov    %rbx,%rsi
lea    0x140(%rsp),%rbx
mov    %rbx,%rdx
call   1040 <Matrix4Mult@plt>
mov    %rbx,%rdi
mov    %r13,%rsi
call   1050 <Matrix4Equal@plt>
add    $0x1,%rbp
cmp    %rbp,%r14
jne    1180 <FKinBody+0x40>
add    $0x1c8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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