#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 */
double nx_dmat3_inv(double *, double *);
double nx_sdmat3_inv(float *M3i, const float *M3) {
  double M3d[9];
  double M3di[9];
  double detM3d;
  for (int i = 0; i < 9; ++i)
    M3d[i] = M3[i];
  detM3d = nx_dmat3_inv(M3di, M3d);
  for (int i = 0; i < 9; ++i)
    M3i[i] = M3di[i];
  return detM3d;
}


x86 assembly (clang, -O0):
<nx_sdmat3_inv>:
push   %rbp
mov    %rsp,%rbp
sub    $0xc0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0xbc(%rbp)
cmpl   $0x9,-0xbc(%rbp)
jge    116f <nx_sdmat3_inv+0x5f>
mov    -0x10(%rbp),%rax
movslq -0xbc(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
movslq -0xbc(%rbp),%rax
movsd  %xmm0,-0x60(%rbp,%rax,8)
mov    -0xbc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xbc(%rbp)
jmp    112d <nx_sdmat3_inv+0x1d>
lea    -0xb0(%rbp),%rdi
lea    -0x60(%rbp),%rsi
call   1030 <nx_dmat3_inv@plt>
movsd  %xmm0,-0xb8(%rbp)
ff
movl   $0x0,-0xc0(%rbp)
cmpl   $0x9,-0xc0(%rbp)
jge    11d6 <nx_sdmat3_inv+0xc6>
movslq -0xc0(%rbp),%rax
movsd  -0xb0(%rbp,%rax,8),%xmm0
ff ff
cvtsd2ss %xmm0,%xmm0
mov    -0x8(%rbp),%rax
movslq -0xc0(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0xc0(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc0(%rbp)
jmp    1191 <nx_sdmat3_inv+0x81>
movsd  -0xb8(%rbp),%xmm0
ff
add    $0xc0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<nx_sdmat3_inv>:
push   %rbx
sub    $0xa0,%rsp
cvtps2pd (%rsi),%xmm0
movaps %xmm0,0x50(%rsp)
cvtps2pd 0x8(%rsi),%xmm0
movaps %xmm0,0x60(%rsp)
cvtps2pd 0x10(%rsi),%xmm0
mov    %rdi,%rbx
movaps %xmm0,0x70(%rsp)
cvtps2pd 0x18(%rsi),%xmm0
movaps %xmm0,0x80(%rsp)
movss  0x20(%rsi),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x90(%rsp)
mov    %rsp,%rdi
lea    0x50(%rsp),%rsi
call   1030 <nx_dmat3_inv@plt>
cvtpd2ps 0x10(%rsp),%xmm1
cvtpd2ps (%rsp),%xmm2
unpcklpd %xmm1,%xmm2
movupd %xmm2,(%rbx)
cvtpd2ps 0x30(%rsp),%xmm1
cvtpd2ps 0x20(%rsp),%xmm2
unpcklpd %xmm1,%xmm2
movupd %xmm2,0x10(%rbx)
movsd  0x40(%rsp),%xmm1
cvtsd2ss %xmm1,%xmm1
movss  %xmm1,0x20(%rbx)
add    $0xa0,%rsp
pop    %rbx
ret

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

LLVM IR (-O2):
define double @nx_sdmat3_inv(float* nocapture writeonly %0, float* nocapture %1) {
%3 = alloca [9 x double]
%4 = alloca [9 x double]
%5 = bitcast [9 x double]* %3 to i8*
%6 = bitcast [9 x double]* %4 to i8*
%7 = getelementptr inbounds [9 x double], [9 x double]* %3, i64 0, i64 0
%8 = bitcast float* %1 to <2 x float>*
%9 = load <2 x float>, <2 x float>* %8
%10 = fpext <2 x float> %9 to <2 x double>
%11 = bitcast [9 x double]* %3 to <2 x double>*
store <2 x double> %10, <2 x double>* %11
%12 = getelementptr inbounds float, float* %1, i64 2
%13 = getelementptr inbounds [9 x double], [9 x double]* %3, i64 0, i64 2
%14 = bitcast float* %12 to <2 x float>*
%15 = load <2 x float>, <2 x float>* %14
%16 = fpext <2 x float> %15 to <2 x double>
%17 = bitcast double* %13 to <2 x double>*
store <2 x double> %16, <2 x double>* %17
%18 = getelementptr inbounds float, float* %1, i64 4
%19 = getelementptr inbounds [9 x double], [9 x double]* %3, i64 0, i64 4
%20 = bitcast float* %18 to <2 x float>*
%21 = load <2 x float>, <2 x float>* %20
%22 = fpext <2 x float> %21 to <2 x double>
%23 = bitcast double* %19 to <2 x double>*
store <2 x double> %22, <2 x double>* %23
%24 = getelementptr inbounds float, float* %1, i64 6
%25 = getelementptr inbounds [9 x double], [9 x double]* %3, i64 0, i64 6
%26 = bitcast float* %24 to <2 x float>*
%27 = load <2 x float>, <2 x float>* %26
%28 = fpext <2 x float> %27 to <2 x double>
%29 = bitcast double* %25 to <2 x double>*
store <2 x double> %28, <2 x double>* %29
%30 = getelementptr inbounds float, float* %1, i64 8
%31 = load float, float* %30
%32 = fpext float %31 to double
%33 = getelementptr inbounds [9 x double], [9 x double]* %3, i64 0, i64 8
store double %32, double* %33
%34 = getelementptr inbounds [9 x double], [9 x double]* %4, i64 0, i64 0
%35 = call double @nx_dmat3_inv(double* %34, double* %7)
%36 = bitcast [9 x double]* %4 to <4 x double>*
%37 = load <4 x double>, <4 x double>* %36
%38 = fptrunc <4 x double> %37 to <4 x float>
%39 = bitcast float* %0 to <4 x float>*
store <4 x float> %38, <4 x float>* %39
%40 = getelementptr inbounds [9 x double], [9 x double]* %4, i64 0, i64 4
%41 = getelementptr inbounds float, float* %0, i64 4
%42 = bitcast double* %40 to <4 x double>*
%43 = load <4 x double>, <4 x double>* %42
%44 = fptrunc <4 x double> %43 to <4 x float>
%45 = bitcast float* %41 to <4 x float>*
store <4 x float> %44, <4 x float>* %45
%46 = getelementptr inbounds [9 x double], [9 x double]* %4, i64 0, i64 8
%47 = load double, double* %46
%48 = fptrunc double %47 to float
%49 = getelementptr inbounds float, float* %0, i64 8
store float %48, float* %49
ret double %35
}