void homo_op_split(double R[3][3], double d[3], double H[3][4]) {
  int i, j;
  for (j = 0; j < 3; j++)
    for (i = 0; i < 3; i++)
      R[j][i] = H[j][i];
  for (i = 0; i < 3; i++)
    d[i] = H[i][3];
}


x86 assembly (clang, -O0):
<homo_op_split>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x20(%rbp)
cmpl   $0x3,-0x20(%rbp)
jge    1183 <homo_op_split+0x83>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x3,-0x1c(%rbp)
jge    1170 <homo_op_split+0x70>
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
imul   $0x18,%rcx,%rcx
add    %rcx,%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1128 <homo_op_split+0x28>
jmp    1175 <homo_op_split+0x75>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1117 <homo_op_split+0x17>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x3,-0x1c(%rbp)
jge    11c3 <homo_op_split+0xc3>
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
shl    $0x5,%rcx
add    %rcx,%rax
movsd  0x18(%rax),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    118a <homo_op_split+0x8a>
pop    %rbp
ret

x86 assembly (clang, -O2):
<homo_op_split>:
movsd  (%rdx),%xmm0
movsd  %xmm0,(%rdi)
movsd  0x8(%rdx),%xmm0
movsd  %xmm0,0x8(%rdi)
movsd  0x10(%rdx),%xmm0
movsd  %xmm0,0x10(%rdi)
movsd  0x20(%rdx),%xmm0
movsd  %xmm0,0x18(%rdi)
movsd  0x28(%rdx),%xmm0
movsd  %xmm0,0x20(%rdi)
movsd  0x30(%rdx),%xmm0
movsd  %xmm0,0x28(%rdi)
movsd  0x40(%rdx),%xmm0
movsd  %xmm0,0x30(%rdi)
movsd  0x48(%rdx),%xmm0
movsd  %xmm0,0x38(%rdi)
movsd  0x50(%rdx),%xmm0
movsd  %xmm0,0x40(%rdi)
movsd  0x18(%rdx),%xmm0
movsd  %xmm0,(%rsi)
movsd  0x38(%rdx),%xmm0
movsd  %xmm0,0x8(%rsi)
movsd  0x58(%rdx),%xmm0
movsd  %xmm0,0x10(%rsi)
ret

LLVM IR (-O0):
define void @homo_op_split([3 x double]* %0, double* %1, [4 x double]* %2) {
%4 = alloca [3 x double]*
%5 = alloca double*
%6 = alloca [4 x double]*
%7 = alloca i32
%8 = alloca i32
store [3 x double]* %0, [3 x double]** %4
store double* %1, double** %5
store [4 x double]* %2, [4 x double]** %6
store i32 0, i32* %8
br label %9
9: ; preds = %36, %3
%10 = load i32, i32* %8
%11 = icmp slt i32 %10, 3
br i1 %11, label %12, label %39
12: ; preds = %9
store i32 0, i32* %7
br label %13
13: ; preds = %32, %12
%14 = load i32, i32* %7
%15 = icmp slt i32 %14, 3
br i1 %15, label %16, label %35
16: ; preds = %13
%17 = load [4 x double]*, [4 x double]** %6
%18 = load i32, i32* %8
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds [4 x double], [4 x double]* %17, i64 %19
%21 = load i32, i32* %7
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [4 x double], [4 x double]* %20, i64 0, i64 %22
%24 = load double, double* %23
%25 = load [3 x double]*, [3 x double]** %4
%26 = load i32, i32* %8
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds [3 x double], [3 x double]* %25, i64 %27
%29 = load i32, i32* %7
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds [3 x double], [3 x double]* %28, i64 0, i64 %30
store double %24, double* %31
br label %32
32: ; preds = %16
%33 = load i32, i32* %7
%34 = add nsw i32 %33, 1
store i32 %34, i32* %7
br label %13
35: ; preds = %13
br label %36
36: ; preds = %35
%37 = load i32, i32* %8
%38 = add nsw i32 %37, 1
store i32 %38, i32* %8
br label %9
39: ; preds = %9
store i32 0, i32* %7
br label %40
40: ; preds = %54, %39
%41 = load i32, i32* %7
%42 = icmp slt i32 %41, 3
br i1 %42, label %43, label %57
43: ; preds = %40
%44 = load [4 x double]*, [4 x double]** %6
%45 = load i32, i32* %7
%46 = sext i32 %45 to i64
%47 = getelementptr inbounds [4 x double], [4 x double]* %44, i64 %46
%48 = getelementptr inbounds [4 x double], [4 x double]* %47, i64 0, i64 3
%49 = load double, double* %48
%50 = load double*, double** %5
%51 = load i32, i32* %7
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds double, double* %50, i64 %52
store double %49, double* %53
br label %54
54: ; preds = %43
%55 = load i32, i32* %7
%56 = add nsw i32 %55, 1
store i32 %56, i32* %7
br label %40
57: ; preds = %40
ret void
}

LLVM IR (-O2):
define void @homo_op_split([3 x double]* nocapture writeonly %0, double* nocapture writeonly %1, [4 x double]* nocapture %2) {
%4 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 0, i64 0
%5 = load double, double* %4
%6 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 0
store double %5, double* %6
%7 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 0, i64 1
%8 = load double, double* %7
%9 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 1
store double %8, double* %9
%10 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 0, i64 2
%11 = load double, double* %10
%12 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 2
store double %11, double* %12
%13 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 1, i64 0
%14 = load double, double* %13
%15 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 0
store double %14, double* %15
%16 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 1, i64 1
%17 = load double, double* %16
%18 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 1
store double %17, double* %18
%19 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 1, i64 2
%20 = load double, double* %19
%21 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 2
store double %20, double* %21
%22 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 2, i64 0
%23 = load double, double* %22
%24 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 0
store double %23, double* %24
%25 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 2, i64 1
%26 = load double, double* %25
%27 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 1
store double %26, double* %27
%28 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 2, i64 2
%29 = load double, double* %28
%30 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 2
store double %29, double* %30
%31 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 0, i64 3
%32 = load double, double* %31
store double %32, double* %1
%33 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 1, i64 3
%34 = load double, double* %33
%35 = getelementptr inbounds double, double* %1, i64 1
store double %34, double* %35
%36 = getelementptr inbounds [4 x double], [4 x double]* %2, i64 2, i64 3
%37 = load double, double* %36
%38 = getelementptr inbounds double, double* %1, i64 2
store double %37, double* %38
ret void
}