void matrix3x3_inverse(const double m[restrict 3][3],
                       double out[restrict 3][3]) {
  const double det = m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
                     m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) +
                     m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
  const double invdet = det ? 1.0 / det : 0;
  out[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]) * invdet;
  out[1][0] = (m[2][0] * m[1][2] - m[1][0] * m[2][2]) * invdet;
  out[2][0] = (m[1][0] * m[2][1] - m[2][0] * m[1][1]) * invdet;
  out[0][1] = (m[2][1] * m[0][2] - m[0][1] * m[2][2]) * invdet;
  out[1][1] = (m[0][0] * m[2][2] - m[2][0] * m[0][2]) * invdet;
  out[2][1] = (m[0][1] * m[2][0] - m[0][0] * m[2][1]) * invdet;
  out[0][2] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]) * invdet;
  out[1][2] = (m[0][2] * m[1][0] - m[0][0] * m[1][2]) * invdet;
  out[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]) * invdet;
}


x86 assembly (clang, -O0):
<matrix3x3_inverse>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x20(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm3
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm0
mov    -0x8(%rbp),%rax
mulsd  0x38(%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm3,%xmm2
addsd  %xmm0,%xmm2
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm3
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm5
mov    -0x8(%rbp),%rax
movsd  0x38(%rax),%xmm4
mov    -0x8(%rbp),%rax
mulsd  0x10(%rax),%xmm4
movq   %xmm4,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm4
mulsd  %xmm5,%xmm3
addsd  %xmm4,%xmm3
mulsd  %xmm3,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm1
addsd  %xmm0,%xmm1
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm4
mov    -0x8(%rbp),%rax
movsd  0x20(%rax),%xmm3
mov    -0x8(%rbp),%rax
mulsd  0x10(%rax),%xmm3
movq   %xmm3,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm3
mulsd  %xmm4,%xmm2
addsd  %xmm3,%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    123c <matrix3x3_inverse+0x13c>
jp     123c <matrix3x3_inverse+0x13c>
jmp    1253 <matrix3x3_inverse+0x153>
movsd  0xdbc(%rip),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    1260 <matrix3x3_inverse+0x160>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    1260 <matrix3x3_inverse+0x160>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x20(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x38(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x40(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x18(%rax)
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x38(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x20(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x30(%rax)
mov    -0x8(%rbp),%rax
movsd  0x38(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x40(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x8(%rax)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x40(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x30(%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
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x20(%rax)
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x30(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x38(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x28(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x20(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x10(%rax)
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x18(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x28(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x28(%rax)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x20(%rax),%xmm2
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm1
mov    -0x8(%rbp),%rax
mulsd  0x18(%rax),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mulsd  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x40(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<matrix3x3_inverse>:
movsd  (%rdi),%xmm15
movsd  0x8(%rdi),%xmm14
movsd  0x20(%rdi),%xmm8
movsd  0x28(%rdi),%xmm9
movupd 0x38(%rdi),%xmm4
movupd 0x10(%rdi),%xmm2
movapd %xmm2,%xmm1
mulsd  %xmm4,%xmm1
movapd %xmm4,%xmm3
unpckhpd %xmm4,%xmm3
movapd %xmm14,%xmm5
mulsd  %xmm3,%xmm5
subsd  %xmm1,%xmm5
movapd 0xeb9(%rip),%xmm13
movapd %xmm2,%xmm10
xorpd  %xmm13,%xmm10
pshufd $0xee,%xmm10,%xmm6
mulsd  %xmm5,%xmm6
movapd %xmm9,%xmm5
unpcklpd %xmm14,%xmm5
xorpd  %xmm5,%xmm13
mulpd  %xmm4,%xmm5
movapd %xmm8,%xmm1
unpcklpd %xmm4,%xmm1
movapd %xmm4,%xmm7
shufpd $0x1,%xmm2,%xmm7
mulpd  %xmm1,%xmm7
subpd  %xmm5,%xmm7
movapd %xmm15,%xmm0
mulsd  %xmm7,%xmm0
addsd  %xmm6,%xmm0
movsd  0x30(%rdi),%xmm12
movapd %xmm2,%xmm6
mulsd  %xmm8,%xmm6
movapd %xmm14,%xmm5
mulsd  %xmm9,%xmm5
subsd  %xmm6,%xmm5
mulsd  %xmm12,%xmm5
addsd  %xmm0,%xmm5
xorpd  %xmm11,%xmm11
ucomisd %xmm11,%xmm5
jne    11c9 <matrix3x3_inverse+0xc9>
jnp    11d7 <matrix3x3_inverse+0xd7>
movsd  0xe3e(%rip),%xmm11
divsd  %xmm5,%xmm11
movapd %xmm12,%xmm6
unpcklpd %xmm15,%xmm6
movapd %xmm11,%xmm5
unpcklpd %xmm11,%xmm5
mulpd  %xmm5,%xmm7
movupd %xmm7,(%rsi)
mulpd  %xmm6,%xmm1
movapd %xmm2,%xmm0
shufpd $0x1,%xmm14,%xmm0
movapd %xmm4,%xmm7
unpcklpd %xmm12,%xmm7
mulpd  %xmm0,%xmm7
subpd  %xmm1,%xmm7
mulpd  %xmm5,%xmm7
movupd %xmm7,0x30(%rsi)
movsd  %xmm8,%xmm4
mulpd  %xmm10,%xmm4
unpcklpd %xmm12,%xmm14
movapd %xmm9,%xmm0
unpcklpd %xmm9,%xmm0
mulpd  %xmm14,%xmm0
addpd  %xmm4,%xmm0
mulpd  %xmm5,%xmm0
movupd %xmm0,0x10(%rsi)
movapd %xmm2,%xmm0
unpcklpd %xmm9,%xmm0
mulpd  %xmm6,%xmm0
movapd %xmm15,%xmm1
unpcklpd %xmm2,%xmm1
shufpd $0x2,%xmm2,%xmm3
mulpd  %xmm1,%xmm3
subpd  %xmm0,%xmm3
mulpd  %xmm5,%xmm3
movupd %xmm3,0x20(%rsi)
mulpd  %xmm2,%xmm13
unpckhpd %xmm13,%xmm13
mulsd  %xmm8,%xmm15
addsd  %xmm13,%xmm15
mulsd  %xmm11,%xmm15
movsd  %xmm15,0x40(%rsi)
ret

LLVM IR (-O0):
define void @matrix3x3_inverse([3 x double]* noalias %0, [3 x double]* noalias %1) {
%3 = alloca [3 x double]*
%4 = alloca [3 x double]*
%5 = alloca double
%6 = alloca double
store [3 x double]* %0, [3 x double]** %3
store [3 x double]* %1, [3 x double]** %4
%7 = load [3 x double]*, [3 x double]** %3
%8 = getelementptr inbounds [3 x double], [3 x double]* %7, i64 0
%9 = getelementptr inbounds [3 x double], [3 x double]* %8, i64 0, i64 0
%10 = load double, double* %9
%11 = load [3 x double]*, [3 x double]** %3
%12 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 1
%13 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 1
%14 = load double, double* %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 1
%21 = getelementptr inbounds [3 x double], [3 x double]* %20, i64 0, i64 2
%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 2
%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 = fneg double %27
%29 = call double @llvm.fmuladd.f64(double %14, double %18, double %28)
%30 = load [3 x double]*, [3 x double]** %3
%31 = getelementptr inbounds [3 x double], [3 x double]* %30, i64 1
%32 = getelementptr inbounds [3 x double], [3 x double]* %31, i64 0, i64 0
%33 = load double, double* %32
%34 = load [3 x double]*, [3 x double]** %3
%35 = getelementptr inbounds [3 x double], [3 x double]* %34, i64 0
%36 = getelementptr inbounds [3 x double], [3 x double]* %35, i64 0, i64 1
%37 = load double, double* %36
%38 = load [3 x double]*, [3 x double]** %3
%39 = getelementptr inbounds [3 x double], [3 x double]* %38, i64 2
%40 = getelementptr inbounds [3 x double], [3 x double]* %39, i64 0, i64 2
%41 = load double, double* %40
%42 = load [3 x double]*, [3 x double]** %3
%43 = getelementptr inbounds [3 x double], [3 x double]* %42, i64 2
%44 = getelementptr inbounds [3 x double], [3 x double]* %43, i64 0, i64 1
%45 = load double, double* %44
%46 = load [3 x double]*, [3 x double]** %3
%47 = getelementptr inbounds [3 x double], [3 x double]* %46, i64 0
%48 = getelementptr inbounds [3 x double], [3 x double]* %47, i64 0, i64 2
%49 = load double, double* %48
%50 = fmul double %45, %49
%51 = fneg double %50
%52 = call double @llvm.fmuladd.f64(double %37, double %41, double %51)
%53 = fmul double %33, %52
%54 = fneg double %53
%55 = call double @llvm.fmuladd.f64(double %10, double %29, double %54)
%56 = load [3 x double]*, [3 x double]** %3
%57 = getelementptr inbounds [3 x double], [3 x double]* %56, i64 2
%58 = getelementptr inbounds [3 x double], [3 x double]* %57, i64 0, i64 0
%59 = load double, double* %58
%60 = load [3 x double]*, [3 x double]** %3
%61 = getelementptr inbounds [3 x double], [3 x double]* %60, i64 0
%62 = getelementptr inbounds [3 x double], [3 x double]* %61, i64 0, i64 1
%63 = load double, double* %62
%64 = load [3 x double]*, [3 x double]** %3
%65 = getelementptr inbounds [3 x double], [3 x double]* %64, i64 1
%66 = getelementptr inbounds [3 x double], [3 x double]* %65, i64 0, i64 2
%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 1
%70 = getelementptr inbounds [3 x double], [3 x double]* %69, i64 0, i64 1
%71 = load double, double* %70
%72 = load [3 x double]*, [3 x double]** %3
%73 = getelementptr inbounds [3 x double], [3 x double]* %72, i64 0
%74 = getelementptr inbounds [3 x double], [3 x double]* %73, i64 0, i64 2
%75 = load double, double* %74
%76 = fmul double %71, %75
%77 = fneg double %76
%78 = call double @llvm.fmuladd.f64(double %63, double %67, double %77)
%79 = call double @llvm.fmuladd.f64(double %59, double %78, double %55)
store double %79, double* %5
%80 = load double, double* %5
%81 = fcmp une double %80, 0.000000e+00
br i1 %81, label %82, label %85
82: ; preds = %2
%83 = load double, double* %5
%84 = fdiv double 1.000000e+00, %83
br label %86
85: ; preds = %2
br label %86
86: ; preds = %85, %82
%87 = phi double [ %84, %82 ], [ 0.000000e+00, %85 ]
store double %87, double* %6
%88 = load [3 x double]*, [3 x double]** %3
%89 = getelementptr inbounds [3 x double], [3 x double]* %88, i64 1
%90 = getelementptr inbounds [3 x double], [3 x double]* %89, i64 0, i64 1
%91 = load double, double* %90
%92 = load [3 x double]*, [3 x double]** %3
%93 = getelementptr inbounds [3 x double], [3 x double]* %92, i64 2
%94 = getelementptr inbounds [3 x double], [3 x double]* %93, i64 0, i64 2
%95 = load double, double* %94
%96 = load [3 x double]*, [3 x double]** %3
%97 = getelementptr inbounds [3 x double], [3 x double]* %96, i64 1
%98 = getelementptr inbounds [3 x double], [3 x double]* %97, i64 0, i64 2
%99 = load double, double* %98
%100 = load [3 x double]*, [3 x double]** %3
%101 = getelementptr inbounds [3 x double], [3 x double]* %100, i64 2
%102 = getelementptr inbounds [3 x double], [3 x double]* %101, i64 0, i64 1
%103 = load double, double* %102
%104 = fmul double %99, %103
%105 = fneg double %104
%106 = call double @llvm.fmuladd.f64(double %91, double %95, double %105)
%107 = load double, double* %6
%108 = fmul double %106, %107
%109 = load [3 x double]*, [3 x double]** %4
%110 = getelementptr inbounds [3 x double], [3 x double]* %109, i64 0
%111 = getelementptr inbounds [3 x double], [3 x double]* %110, i64 0, i64 0
store double %108, double* %111
%112 = load [3 x double]*, [3 x double]** %3
%113 = getelementptr inbounds [3 x double], [3 x double]* %112, i64 2
%114 = getelementptr inbounds [3 x double], [3 x double]* %113, i64 0, i64 0
%115 = load double, double* %114
%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 2
%119 = load double, double* %118
%120 = load [3 x double]*, [3 x double]** %3
%121 = getelementptr inbounds [3 x double], [3 x double]* %120, i64 1
%122 = getelementptr inbounds [3 x double], [3 x double]* %121, i64 0, i64 0
%123 = load double, double* %122
%124 = load [3 x double]*, [3 x double]** %3
%125 = getelementptr inbounds [3 x double], [3 x double]* %124, i64 2
%126 = getelementptr inbounds [3 x double], [3 x double]* %125, i64 0, i64 2
%127 = load double, double* %126
%128 = fmul double %123, %127
%129 = fneg double %128
%130 = call double @llvm.fmuladd.f64(double %115, double %119, double %129)
%131 = load double, double* %6
%132 = fmul double %130, %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
store double %132, double* %135
%136 = load [3 x double]*, [3 x double]** %3
%137 = getelementptr inbounds [3 x double], [3 x double]* %136, i64 1
%138 = getelementptr inbounds [3 x double], [3 x double]* %137, i64 0, i64 0
%139 = load double, double* %138
%140 = load [3 x double]*, [3 x double]** %3
%141 = getelementptr inbounds [3 x double], [3 x double]* %140, i64 2
%142 = getelementptr inbounds [3 x double], [3 x double]* %141, i64 0, i64 1
%143 = load double, double* %142
%144 = load [3 x double]*, [3 x double]** %3
%145 = getelementptr inbounds [3 x double], [3 x double]* %144, i64 2
%146 = getelementptr inbounds [3 x double], [3 x double]* %145, i64 0, i64 0
%147 = load double, double* %146
%148 = load [3 x double]*, [3 x double]** %3
%149 = getelementptr inbounds [3 x double], [3 x double]* %148, i64 1
%150 = getelementptr inbounds [3 x double], [3 x double]* %149, i64 0, i64 1
%151 = load double, double* %150
%152 = fmul double %147, %151
%153 = fneg double %152
%154 = call double @llvm.fmuladd.f64(double %139, double %143, double %153)
%155 = load double, double* %6
%156 = fmul double %154, %155
%157 = load [3 x double]*, [3 x double]** %4
%158 = getelementptr inbounds [3 x double], [3 x double]* %157, i64 2
%159 = getelementptr inbounds [3 x double], [3 x double]* %158, i64 0, i64 0
store double %156, double* %159
%160 = load [3 x double]*, [3 x double]** %3
%161 = getelementptr inbounds [3 x double], [3 x double]* %160, i64 2
%162 = getelementptr inbounds [3 x double], [3 x double]* %161, i64 0, i64 1
%163 = load double, double* %162
%164 = load [3 x double]*, [3 x double]** %3
%165 = getelementptr inbounds [3 x double], [3 x double]* %164, i64 0
%166 = getelementptr inbounds [3 x double], [3 x double]* %165, i64 0, i64 2
%167 = load double, double* %166
%168 = load [3 x double]*, [3 x double]** %3
%169 = getelementptr inbounds [3 x double], [3 x double]* %168, i64 0
%170 = getelementptr inbounds [3 x double], [3 x double]* %169, i64 0, i64 1
%171 = load double, double* %170
%172 = load [3 x double]*, [3 x double]** %3
%173 = getelementptr inbounds [3 x double], [3 x double]* %172, i64 2
%174 = getelementptr inbounds [3 x double], [3 x double]* %173, i64 0, i64 2
%175 = load double, double* %174
%176 = fmul double %171, %175
%177 = fneg double %176
%178 = call double @llvm.fmuladd.f64(double %163, double %167, double %177)
%179 = load double, double* %6
%180 = fmul double %178, %179
%181 = load [3 x double]*, [3 x double]** %4
%182 = getelementptr inbounds [3 x double], [3 x double]* %181, i64 0
%183 = getelementptr inbounds [3 x double], [3 x double]* %182, i64 0, i64 1
store double %180, double* %183
%184 = load [3 x double]*, [3 x double]** %3
%185 = getelementptr inbounds [3 x double], [3 x double]* %184, i64 0
%186 = getelementptr inbounds [3 x double], [3 x double]* %185, i64 0, i64 0
%187 = load double, double* %186
%188 = load [3 x double]*, [3 x double]** %3
%189 = getelementptr inbounds [3 x double], [3 x double]* %188, i64 2
%190 = getelementptr inbounds [3 x double], [3 x double]* %189, i64 0, i64 2
%191 = load double, double* %190
%192 = load [3 x double]*, [3 x double]** %3
%193 = getelementptr inbounds [3 x double], [3 x double]* %192, i64 2
%194 = getelementptr inbounds [3 x double], [3 x double]* %193, i64 0, i64 0
%195 = load double, double* %194
%196 = load [3 x double]*, [3 x double]** %3
%197 = getelementptr inbounds [3 x double], [3 x double]* %196, i64 0
%198 = getelementptr inbounds [3 x double], [3 x double]* %197, i64 0, i64 2
%199 = load double, double* %198
%200 = fmul double %195, %199
%201 = fneg double %200
%202 = call double @llvm.fmuladd.f64(double %187, double %191, double %201)
%203 = load double, double* %6
%204 = fmul double %202, %203
%205 = load [3 x double]*, [3 x double]** %4
%206 = getelementptr inbounds [3 x double], [3 x double]* %205, i64 1
%207 = getelementptr inbounds [3 x double], [3 x double]* %206, i64 0, i64 1
store double %204, double* %207
%208 = load [3 x double]*, [3 x double]** %3
%209 = getelementptr inbounds [3 x double], [3 x double]* %208, i64 0
%210 = getelementptr inbounds [3 x double], [3 x double]* %209, i64 0, i64 1
%211 = load double, double* %210
%212 = load [3 x double]*, [3 x double]** %3
%213 = getelementptr inbounds [3 x double], [3 x double]* %212, i64 2
%214 = getelementptr inbounds [3 x double], [3 x double]* %213, i64 0, i64 0
%215 = load double, double* %214
%216 = load [3 x double]*, [3 x double]** %3
%217 = getelementptr inbounds [3 x double], [3 x double]* %216, i64 0
%218 = getelementptr inbounds [3 x double], [3 x double]* %217, i64 0, i64 0
%219 = load double, double* %218
%220 = load [3 x double]*, [3 x double]** %3
%221 = getelementptr inbounds [3 x double], [3 x double]* %220, i64 2
%222 = getelementptr inbounds [3 x double], [3 x double]* %221, i64 0, i64 1
%223 = load double, double* %222
%224 = fmul double %219, %223
%225 = fneg double %224
%226 = call double @llvm.fmuladd.f64(double %211, double %215, double %225)
%227 = load double, double* %6
%228 = fmul double %226, %227
%229 = load [3 x double]*, [3 x double]** %4
%230 = getelementptr inbounds [3 x double], [3 x double]* %229, i64 2
%231 = getelementptr inbounds [3 x double], [3 x double]* %230, i64 0, i64 1
store double %228, double* %231
%232 = load [3 x double]*, [3 x double]** %3
%233 = getelementptr inbounds [3 x double], [3 x double]* %232, i64 0
%234 = getelementptr inbounds [3 x double], [3 x double]* %233, i64 0, i64 1
%235 = load double, double* %234
%236 = load [3 x double]*, [3 x double]** %3
%237 = getelementptr inbounds [3 x double], [3 x double]* %236, i64 1
%238 = getelementptr inbounds [3 x double], [3 x double]* %237, i64 0, i64 2
%239 = load double, double* %238
%240 = load [3 x double]*, [3 x double]** %3
%241 = getelementptr inbounds [3 x double], [3 x double]* %240, i64 0
%242 = getelementptr inbounds [3 x double], [3 x double]* %241, i64 0, i64 2
%243 = load double, double* %242
%244 = load [3 x double]*, [3 x double]** %3
%245 = getelementptr inbounds [3 x double], [3 x double]* %244, i64 1
%246 = getelementptr inbounds [3 x double], [3 x double]* %245, i64 0, i64 1
%247 = load double, double* %246
%248 = fmul double %243, %247
%249 = fneg double %248
%250 = call double @llvm.fmuladd.f64(double %235, double %239, double %249)
%251 = load double, double* %6
%252 = fmul double %250, %251
%253 = load [3 x double]*, [3 x double]** %4
%254 = getelementptr inbounds [3 x double], [3 x double]* %253, i64 0
%255 = getelementptr inbounds [3 x double], [3 x double]* %254, i64 0, i64 2
store double %252, double* %255
%256 = load [3 x double]*, [3 x double]** %3
%257 = getelementptr inbounds [3 x double], [3 x double]* %256, i64 0
%258 = getelementptr inbounds [3 x double], [3 x double]* %257, i64 0, i64 2
%259 = load double, double* %258
%260 = load [3 x double]*, [3 x double]** %3
%261 = getelementptr inbounds [3 x double], [3 x double]* %260, i64 1
%262 = getelementptr inbounds [3 x double], [3 x double]* %261, i64 0, i64 0
%263 = load double, double* %262
%264 = load [3 x double]*, [3 x double]** %3
%265 = getelementptr inbounds [3 x double], [3 x double]* %264, i64 0
%266 = getelementptr inbounds [3 x double], [3 x double]* %265, i64 0, i64 0
%267 = load double, double* %266
%268 = load [3 x double]*, [3 x double]** %3
%269 = getelementptr inbounds [3 x double], [3 x double]* %268, i64 1
%270 = getelementptr inbounds [3 x double], [3 x double]* %269, i64 0, i64 2
%271 = load double, double* %270
%272 = fmul double %267, %271
%273 = fneg double %272
%274 = call double @llvm.fmuladd.f64(double %259, double %263, double %273)
%275 = load double, double* %6
%276 = fmul double %274, %275
%277 = load [3 x double]*, [3 x double]** %4
%278 = getelementptr inbounds [3 x double], [3 x double]* %277, i64 1
%279 = getelementptr inbounds [3 x double], [3 x double]* %278, i64 0, i64 2
store double %276, double* %279
%280 = load [3 x double]*, [3 x double]** %3
%281 = getelementptr inbounds [3 x double], [3 x double]* %280, i64 0
%282 = getelementptr inbounds [3 x double], [3 x double]* %281, i64 0, i64 0
%283 = load double, double* %282
%284 = load [3 x double]*, [3 x double]** %3
%285 = getelementptr inbounds [3 x double], [3 x double]* %284, i64 1
%286 = getelementptr inbounds [3 x double], [3 x double]* %285, i64 0, i64 1
%287 = load double, double* %286
%288 = load [3 x double]*, [3 x double]** %3
%289 = getelementptr inbounds [3 x double], [3 x double]* %288, i64 0
%290 = getelementptr inbounds [3 x double], [3 x double]* %289, i64 0, i64 1
%291 = load double, double* %290
%292 = load [3 x double]*, [3 x double]** %3
%293 = getelementptr inbounds [3 x double], [3 x double]* %292, i64 1
%294 = getelementptr inbounds [3 x double], [3 x double]* %293, i64 0, i64 0
%295 = load double, double* %294
%296 = fmul double %291, %295
%297 = fneg double %296
%298 = call double @llvm.fmuladd.f64(double %283, double %287, double %297)
%299 = load double, double* %6
%300 = fmul double %298, %299
%301 = load [3 x double]*, [3 x double]** %4
%302 = getelementptr inbounds [3 x double], [3 x double]* %301, i64 2
%303 = getelementptr inbounds [3 x double], [3 x double]* %302, i64 0, i64 2
store double %300, double* %303
ret void
}

LLVM IR (-O2):
define void @matrix3x3_inverse([3 x double]* noalias nocapture %0, [3 x double]* noalias nocapture writeonly %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 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 1, i64 2
%8 = load double, double* %7
%9 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 1
%10 = bitcast double* %9 to <2 x double>*
%11 = load <2 x double>, <2 x double>* %10
%12 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 1
%13 = load double, double* %12
%14 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 0, i64 2
%15 = bitcast double* %14 to <2 x double>*
%16 = load <2 x double>, <2 x double>* %15
%17 = extractelement <2 x double> %11, i64 0
%18 = fneg double %17
%19 = extractelement <2 x double> %16, i64 0
%20 = fmul double %19, %18
%21 = extractelement <2 x double> %11, i64 1
%22 = tail call double @llvm.fmuladd.f64(double %13, double %21, double %20)
%23 = fneg <2 x double> %16
%24 = extractelement <2 x double> %23, i64 1
%25 = fmul double %22, %24
%26 = insertelement <2 x double> poison, double %8, i64 0
%27 = insertelement <2 x double> %26, double %13, i64 1
%28 = fneg <2 x double> %27
%29 = fmul <2 x double> %11, %28
%30 = insertelement <2 x double> poison, double %6, i64 0
%31 = shufflevector <2 x double> %30, <2 x double> %11, <2 x i32> <i32 0, i32 2>
%32 = shufflevector <2 x double> %11, <2 x double> undef, <2 x i32> <i32 1, i32 undef>
%33 = shufflevector <2 x double> %32, <2 x double> %16, <2 x i32> <i32 0, i32 2>
%34 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %31, <2 x double> %33, <2 x double> %29)
%35 = extractelement <2 x double> %34, i64 0
%36 = tail call double @llvm.fmuladd.f64(double %4, double %35, double %25)
%37 = getelementptr inbounds [3 x double], [3 x double]* %0, i64 2, i64 0
%38 = load double, double* %37
%39 = fneg double %6
%40 = fmul double %19, %39
%41 = tail call double @llvm.fmuladd.f64(double %13, double %8, double %40)
%42 = tail call double @llvm.fmuladd.f64(double %38, double %41, double %36)
%43 = fcmp une double %42, 0.000000e+00
%44 = fdiv double 1.000000e+00, %42
%45 = select i1 %43, double %44, double 0.000000e+00
%46 = insertelement <2 x double> poison, double %38, i64 0
%47 = insertelement <2 x double> %46, double %4, i64 1
%48 = fneg <2 x double> %47
%49 = extractelement <2 x double> %16, i64 1
%50 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 2, i64 0
%51 = insertelement <2 x double> poison, double %45, i64 0
%52 = shufflevector <2 x double> %51, <2 x double> poison, <2 x i32> zeroinitializer
%53 = fmul <2 x double> %34, %52
%54 = bitcast [3 x double]* %1 to <2 x double>*
store <2 x double> %53, <2 x double>* %54
%55 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 1, i64 1
%56 = fmul <2 x double> %31, %48
%57 = insertelement <2 x double> poison, double %49, i64 0
%58 = insertelement <2 x double> %57, double %13, i64 1
%59 = insertelement <2 x double> %11, double %38, i64 1
%60 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %58, <2 x double> %59, <2 x double> %56)
%61 = fmul <2 x double> %60, %52
%62 = bitcast double* %50 to <2 x double>*
store <2 x double> %61, <2 x double>* %62
%63 = insertelement <2 x double> %11, double %6, i64 0
%64 = fmul <2 x double> %63, %23
%65 = insertelement <2 x double> poison, double %13, i64 0
%66 = insertelement <2 x double> %65, double %38, i64 1
%67 = shufflevector <2 x double> %26, <2 x double> poison, <2 x i32> zeroinitializer
%68 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %66, <2 x double> %67, <2 x double> %64)
%69 = fmul <2 x double> %68, %52
%70 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 0, i64 2
%71 = bitcast double* %70 to <2 x double>*
store <2 x double> %69, <2 x double>* %71
%72 = insertelement <2 x double> %16, double %8, i64 1
%73 = fmul <2 x double> %72, %48
%74 = insertelement <2 x double> poison, double %4, i64 0
%75 = shufflevector <2 x double> %74, <2 x double> %16, <2 x i32> <i32 0, i32 2>
%76 = shufflevector <2 x double> %32, <2 x double> %16, <2 x i32> <i32 0, i32 3>
%77 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %75, <2 x double> %76, <2 x double> %73)
%78 = fmul <2 x double> %77, %52
%79 = bitcast double* %55 to <2 x double>*
store <2 x double> %78, <2 x double>* %79
%80 = fmul <2 x double> %16, %28
%81 = extractelement <2 x double> %80, i64 1
%82 = tail call double @llvm.fmuladd.f64(double %4, double %6, double %81)
%83 = fmul double %82, %45
%84 = getelementptr inbounds [3 x double], [3 x double]* %1, i64 2, i64 2
store double %83, double* %84
ret void
}