#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*/ ltr_int_cross_product(double *, double *, double *);
int /*<<< orphan*/ ltr_int_mul_vec(double *, int, double *);
int /*<<< orphan*/ ltr_int_transpose_in_place(double **);
void ltr_int_invert_matrix(double in[3][3], double out[3][3]) {
  double det = in[0][0] * in[1][1] * in[2][2] - in[2][0] * in[1][1] * in[0][2] +
               in[1][0] * in[2][1] * in[0][2] - in[1][0] * in[0][1] * in[2][2] +
               in[2][0] * in[0][1] * in[1][2] - in[0][0] * in[2][1] * in[1][2];
  ltr_int_cross_product(in[1], in[2], out[0]);
  ltr_int_cross_product(in[2], in[0], out[1]);
  ltr_int_cross_product(in[0], in[1], out[2]);
  ltr_int_mul_vec(out[0], 1 / det, out[0]);
  ltr_int_mul_vec(out[1], 1 / det, out[1]);
  ltr_int_mul_vec(out[2], 1 / det, out[2]);
  ltr_int_transpose_in_place(out);
}


x86 assembly (clang, -O0):
<ltr_int_invert_matrix>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x8(%rbp),%rax
mulsd  0x20(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x20(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x10(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x38(%rax),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm0
mov    -0x8(%rbp),%rax
mulsd  0x8(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x8(%rax),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm2
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x8(%rbp),%rax
mulsd  0x38(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
add    $0x18,%rdi
mov    -0x8(%rbp),%rsi
add    $0x30,%rsi
mov    -0x10(%rbp),%rdx
call   1030 <ltr_int_cross_product@plt>
mov    -0x8(%rbp),%rdi
add    $0x30,%rdi
mov    -0x8(%rbp),%rsi
mov    -0x10(%rbp),%rdx
add    $0x18,%rdx
call   1030 <ltr_int_cross_product@plt>
mov    -0x8(%rbp),%rdi
mov    -0x8(%rbp),%rsi
add    $0x18,%rsi
mov    -0x10(%rbp),%rdx
add    $0x30,%rdx
call   1030 <ltr_int_cross_product@plt>
mov    -0x10(%rbp),%rdi
movsd  0xd57(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
cvttsd2si %xmm0,%esi
mov    -0x10(%rbp),%rdx
call   1050 <ltr_int_mul_vec@plt>
mov    -0x10(%rbp),%rdi
add    $0x18,%rdi
movsd  0xd35(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
cvttsd2si %xmm0,%esi
mov    -0x10(%rbp),%rdx
add    $0x18,%rdx
call   1050 <ltr_int_mul_vec@plt>
mov    -0x10(%rbp),%rdi
add    $0x30,%rdi
movsd  0xd0f(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
cvttsd2si %xmm0,%esi
mov    -0x10(%rbp),%rdx
add    $0x30,%rdx
call   1050 <ltr_int_mul_vec@plt>
mov    -0x10(%rbp),%rdi
call   1040 <ltr_int_transpose_in_place@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ltr_int_invert_matrix>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x10,%rsp
mov    %rsi,%r14
mov    %rdi,%rbx
lea    0x18(%rdi),%r15
movsd  0x20(%rdi),%xmm1
movsd  (%rdi),%xmm0
movsd  0x8(%rdi),%xmm2
movapd %xmm0,%xmm3
mulsd  %xmm1,%xmm3
lea    0x30(%rdi),%r12
movsd  0x40(%rdi),%xmm4
movsd  0x30(%rdi),%xmm7
movsd  0x10(%rdi),%xmm5
mulsd  %xmm7,%xmm1
mulsd  %xmm5,%xmm1
mulsd  %xmm4,%xmm3
subsd  %xmm1,%xmm3
movsd  0x18(%rdi),%xmm1
movsd  0x38(%rdi),%xmm6
mulsd  %xmm2,%xmm7
mulsd  %xmm1,%xmm2
mulsd  %xmm6,%xmm1
mulsd  %xmm5,%xmm1
addsd  %xmm3,%xmm1
mulsd  %xmm4,%xmm2
subsd  %xmm2,%xmm1
movsd  0x28(%rdi),%xmm2
mulsd  %xmm2,%xmm7
addsd  %xmm1,%xmm7
mulsd  %xmm6,%xmm0
mulsd  %xmm2,%xmm0
subsd  %xmm0,%xmm7
movsd  %xmm7,0x8(%rsp)
mov    %r15,%rdi
mov    %r12,%rsi
mov    %r14,%rdx
call   1030 <ltr_int_cross_product@plt>
lea    0x18(%r14),%r13
mov    %r12,%rdi
mov    %rbx,%rsi
mov    %r13,%rdx
call   1030 <ltr_int_cross_product@plt>
lea    0x30(%r14),%r12
mov    %rbx,%rdi
mov    %r15,%rsi
mov    %r12,%rdx
call   1030 <ltr_int_cross_product@plt>
movsd  0xe01(%rip),%xmm0
divsd  0x8(%rsp),%xmm0
cvttsd2si %xmm0,%ebx
mov    %r14,%rdi
mov    %ebx,%esi
mov    %r14,%rdx
call   1050 <ltr_int_mul_vec@plt>
mov    %r13,%rdi
mov    %ebx,%esi
mov    %r13,%rdx
call   1050 <ltr_int_mul_vec@plt>
mov    %r12,%rdi
mov    %ebx,%esi
mov    %r12,%rdx
call   1050 <ltr_int_mul_vec@plt>
mov    %r14,%rdi
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
jmp    1040 <ltr_int_transpose_in_place@plt>

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

LLVM IR (-O2):
define void @ltr_int_invert_matrix([3 x double]* %0, [3 x double]* %1) {
%3 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 0
%4 = load double, double* %3
%5 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 1
%6 = load double, double* %5
%7 = fmul double %4, %6
%8 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 2
%9 = load double, double* %8
%10 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 0
%11 = load double, double* %10
%12 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 2
%13 = load double, double* %12
%14 = fneg double %11
%15 = fmul double %6, %14
%16 = fmul double %15, %13
%17 = tail call double @llvm.fmuladd.f64(double %7, double %9, double %16)
%18 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 0
%19 = load double, double* %18
%20 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 1
%21 = load double, double* %20
%22 = fmul double %19, %21
%23 = tail call double @llvm.fmuladd.f64(double %22, double %13, double %17)
%24 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 1
%25 = load double, double* %24
%26 = fneg double %19
%27 = fmul double %25, %26
%28 = tail call double @llvm.fmuladd.f64(double %27, double %9, double %23)
%29 = fmul double %11, %25
%30 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 2
%31 = load double, double* %30
%32 = tail call double @llvm.fmuladd.f64(double %29, double %31, double %28)
%33 = fneg double %4
%34 = fmul double %21, %33
%35 = tail call double @llvm.fmuladd.f64(double %34, double %31, double %32)
%36 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 0, i64 0
%37 = tail call i32 @ltr_int_cross_product(double* %18, double* %10, double* %36)
%38 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 1, i64 0
%39 = tail call i32 @ltr_int_cross_product(double* %10, double* %3, double* %38)
%40 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 2, i64 0
%41 = tail call i32 @ltr_int_cross_product(double* %3, double* %18, double* %40)
%42 = fdiv double 1.000000e+00, %35
%43 = fptosi double %42 to i32
%44 = tail call i32 @ltr_int_mul_vec(double* %36, i32 %43, double* %36)
%45 = tail call i32 @ltr_int_mul_vec(double* %38, i32 %43, double* %38)
%46 = tail call i32 @ltr_int_mul_vec(double* %40, i32 %43, double* %40)
%47 = bitcast [3 x double]* %1 to double**
%48 = tail call i32 @ltr_int_transpose_in_place(double** %47)
ret void
}