#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*/ fail(char *, int);
int matrix_determinant(float *r, float *a, int n) {
  switch (n) {
  case 1:
    *r = *a;
    break;
  case 4:
    *r = a[0] * a[3] - a[1] * a[2];
    break;
  case 6:
    *r = a[0] * a[4] - a[1] * a[3];
    break;
  case 9:
    *r = a[0] * a[4] * a[8] + a[2] * a[3] * a[7] + a[1] * a[5] * a[6] -
         a[2] * a[4] * a[6] - a[1] * a[3] * a[8] - a[0] * a[5] * a[7];
    break;
  default:
    fail("can not compute determinant of object of size %d", n);
  }
  return 1;
}


x86 assembly (clang, -O0):
<matrix_determinant>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x20(%rbp)
sub    $0x8,%eax
ja     12e7 <matrix_determinant+0x1d7>
mov    -0x20(%rbp),%rax
lea    0xebd(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
jmp    12f6 <matrix_determinant+0x1e6>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
movss  0xc(%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x10(%rbp),%rax
mulss  0x8(%rax),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
jmp    12f6 <matrix_determinant+0x1e6>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
movss  0x10(%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x10(%rbp),%rax
mulss  0xc(%rax),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
jmp    12f6 <matrix_determinant+0x1e6>
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x10(%rax),%xmm0
mov    -0x10(%rbp),%rax
movss  0x20(%rax),%xmm2
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm1
mov    -0x10(%rbp),%rax
mulss  0xc(%rax),%xmm1
mov    -0x10(%rbp),%rax
mulss  0x1c(%rax),%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x10(%rbp),%rax
mulss  0x14(%rax),%xmm1
mov    -0x10(%rbp),%rax
movss  0x18(%rax),%xmm2
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x10(%rax),%xmm0
mov    -0x10(%rbp),%rax
movss  0x18(%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm1
mov    -0x10(%rbp),%rax
mulss  0xc(%rax),%xmm1
mov    -0x10(%rbp),%rax
movss  0x20(%rax),%xmm2
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x14(%rax),%xmm0
mov    -0x10(%rbp),%rax
movss  0x1c(%rax),%xmm2
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
jmp    12f6 <matrix_determinant+0x1e6>
mov    -0x14(%rbp),%esi
lea    0xd33(%rip),%rdi
call   1030 <fail@plt>
mov    $0x1,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<matrix_determinant>:
push   %rax
lea    -0x1(%rdx),%eax
cmp    $0x8,%eax
ja     1132 <matrix_determinant+0x22>
lea    0xee0(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movss  (%rsi),%xmm0
jmp    11e9 <matrix_determinant+0xd9>
lea    0xeeb(%rip),%rdi
mov    %edx,%esi
call   1030 <fail@plt>
jmp    11ed <matrix_determinant+0xdd>
movss  (%rsi),%xmm0
movss  0x8(%rsi),%xmm1
mulss  0x4(%rsi),%xmm1
mulss  0xc(%rsi),%xmm0
jmp    116d <matrix_determinant+0x5d>
movss  (%rsi),%xmm0
movss  0xc(%rsi),%xmm1
mulss  0x4(%rsi),%xmm1
mulss  0x10(%rsi),%xmm0
subss  %xmm1,%xmm0
jmp    11e9 <matrix_determinant+0xd9>
movss  0x10(%rsi),%xmm2
movss  (%rsi),%xmm8
movss  0x4(%rsi),%xmm0
movaps %xmm8,%xmm3
mulss  %xmm2,%xmm3
movss  0x20(%rsi),%xmm4
movss  0x8(%rsi),%xmm5
movss  0xc(%rsi),%xmm6
mulss  %xmm5,%xmm2
mulss  %xmm6,%xmm5
movss  0x1c(%rsi),%xmm7
mulss  %xmm7,%xmm5
mulss  %xmm4,%xmm3
addss  %xmm5,%xmm3
movss  0x14(%rsi),%xmm5
mulss  %xmm0,%xmm6
mulss  %xmm5,%xmm0
movss  0x18(%rsi),%xmm1
mulss  %xmm1,%xmm0
addss  %xmm3,%xmm0
mulss  %xmm1,%xmm2
subss  %xmm2,%xmm0
mulss  %xmm4,%xmm6
subss  %xmm6,%xmm0
mulss  %xmm8,%xmm5
mulss  %xmm7,%xmm5
subss  %xmm5,%xmm0
movss  %xmm0,(%rdi)
mov    $0x1,%eax
pop    %rcx
ret

LLVM IR (-O0):
@.str = [49 x i8] c"can not compute determinant of object of size %d\00"
define i32 @matrix_determinant(float* %0, float* %1, i32 %2) {
%4 = alloca float*
%5 = alloca float*
%6 = alloca i32
store float* %0, float** %4
store float* %1, float** %5
store i32 %2, i32* %6
%7 = load i32, i32* %6
switch i32 %7, label %117 [
i32 1, label %8
i32 4, label %12
i32 6, label %29
i32 9, label %46
]
8: ; preds = %3
%9 = load float*, float** %5
%10 = load float, float* %9
%11 = load float*, float** %4
store float %10, float* %11
br label %120
12: ; preds = %3
%13 = load float*, float** %5
%14 = getelementptr inbounds float, float* %13, i64 0
%15 = load float, float* %14
%16 = load float*, float** %5
%17 = getelementptr inbounds float, float* %16, i64 3
%18 = load float, float* %17
%19 = load float*, float** %5
%20 = getelementptr inbounds float, float* %19, i64 1
%21 = load float, float* %20
%22 = load float*, float** %5
%23 = getelementptr inbounds float, float* %22, i64 2
%24 = load float, float* %23
%25 = fmul float %21, %24
%26 = fneg float %25
%27 = call float @llvm.fmuladd.f32(float %15, float %18, float %26)
%28 = load float*, float** %4
store float %27, float* %28
br label %120
29: ; preds = %3
%30 = load float*, float** %5
%31 = getelementptr inbounds float, float* %30, i64 0
%32 = load float, float* %31
%33 = load float*, float** %5
%34 = getelementptr inbounds float, float* %33, i64 4
%35 = load float, float* %34
%36 = load float*, float** %5
%37 = getelementptr inbounds float, float* %36, i64 1
%38 = load float, float* %37
%39 = load float*, float** %5
%40 = getelementptr inbounds float, float* %39, i64 3
%41 = load float, float* %40
%42 = fmul float %38, %41
%43 = fneg float %42
%44 = call float @llvm.fmuladd.f32(float %32, float %35, float %43)
%45 = load float*, float** %4
store float %44, float* %45
br label %120
46: ; preds = %3
%47 = load float*, float** %5
%48 = getelementptr inbounds float, float* %47, i64 0
%49 = load float, float* %48
%50 = load float*, float** %5
%51 = getelementptr inbounds float, float* %50, i64 4
%52 = load float, float* %51
%53 = fmul float %49, %52
%54 = load float*, float** %5
%55 = getelementptr inbounds float, float* %54, i64 8
%56 = load float, float* %55
%57 = load float*, float** %5
%58 = getelementptr inbounds float, float* %57, i64 2
%59 = load float, float* %58
%60 = load float*, float** %5
%61 = getelementptr inbounds float, float* %60, i64 3
%62 = load float, float* %61
%63 = fmul float %59, %62
%64 = load float*, float** %5
%65 = getelementptr inbounds float, float* %64, i64 7
%66 = load float, float* %65
%67 = fmul float %63, %66
%68 = call float @llvm.fmuladd.f32(float %53, float %56, float %67)
%69 = load float*, float** %5
%70 = getelementptr inbounds float, float* %69, i64 1
%71 = load float, float* %70
%72 = load float*, float** %5
%73 = getelementptr inbounds float, float* %72, i64 5
%74 = load float, float* %73
%75 = fmul float %71, %74
%76 = load float*, float** %5
%77 = getelementptr inbounds float, float* %76, i64 6
%78 = load float, float* %77
%79 = call float @llvm.fmuladd.f32(float %75, float %78, float %68)
%80 = load float*, float** %5
%81 = getelementptr inbounds float, float* %80, i64 2
%82 = load float, float* %81
%83 = load float*, float** %5
%84 = getelementptr inbounds float, float* %83, i64 4
%85 = load float, float* %84
%86 = fmul float %82, %85
%87 = load float*, float** %5
%88 = getelementptr inbounds float, float* %87, i64 6
%89 = load float, float* %88
%90 = fneg float %86
%91 = call float @llvm.fmuladd.f32(float %90, float %89, float %79)
%92 = load float*, float** %5
%93 = getelementptr inbounds float, float* %92, i64 1
%94 = load float, float* %93
%95 = load float*, float** %5
%96 = getelementptr inbounds float, float* %95, i64 3
%97 = load float, float* %96
%98 = fmul float %94, %97
%99 = load float*, float** %5
%100 = getelementptr inbounds float, float* %99, i64 8
%101 = load float, float* %100
%102 = fneg float %98
%103 = call float @llvm.fmuladd.f32(float %102, float %101, float %91)
%104 = load float*, float** %5
%105 = getelementptr inbounds float, float* %104, i64 0
%106 = load float, float* %105
%107 = load float*, float** %5
%108 = getelementptr inbounds float, float* %107, i64 5
%109 = load float, float* %108
%110 = fmul float %106, %109
%111 = load float*, float** %5
%112 = getelementptr inbounds float, float* %111, i64 7
%113 = load float, float* %112
%114 = fneg float %110
%115 = call float @llvm.fmuladd.f32(float %114, float %113, float %103)
%116 = load float*, float** %4
store float %115, float* %116
br label %120
117: ; preds = %3
%118 = load i32, i32* %6
%119 = call i32 @fail(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0), i32 %118)
br label %120
120: ; preds = %117, %46, %29, %12, %8
ret i32 1
}

LLVM IR (-O2):
@.str = [49 x i8] c"can not compute determinant of object of size %d\00"
define i32 @matrix_determinant(float* nocapture writeonly %0, float* nocapture %1, i32 %2) {
switch i32 %2, label %61 [
i32 1, label %4
i32 4, label %6
i32 6, label %17
i32 9, label %28
]
4: ; preds = %3
%5 = load float, float* %1
store float %5, float* %0
br label %63
6: ; preds = %3
%7 = load float, float* %1
%8 = getelementptr inbounds float, float* %1, i64 3
%9 = load float, float* %8
%10 = getelementptr inbounds float, float* %1, i64 1
%11 = load float, float* %10
%12 = getelementptr inbounds float, float* %1, i64 2
%13 = load float, float* %12
%14 = fneg float %11
%15 = fmul float %13, %14
%16 = tail call float @llvm.fmuladd.f32(float %7, float %9, float %15)
store float %16, float* %0
br label %63
17: ; preds = %3
%18 = load float, float* %1
%19 = getelementptr inbounds float, float* %1, i64 4
%20 = load float, float* %19
%21 = getelementptr inbounds float, float* %1, i64 1
%22 = load float, float* %21
%23 = getelementptr inbounds float, float* %1, i64 3
%24 = load float, float* %23
%25 = fneg float %22
%26 = fmul float %24, %25
%27 = tail call float @llvm.fmuladd.f32(float %18, float %20, float %26)
store float %27, float* %0
br label %63
28: ; preds = %3
%29 = load float, float* %1
%30 = getelementptr inbounds float, float* %1, i64 4
%31 = load float, float* %30
%32 = fmul float %29, %31
%33 = getelementptr inbounds float, float* %1, i64 8
%34 = load float, float* %33
%35 = getelementptr inbounds float, float* %1, i64 2
%36 = load float, float* %35
%37 = getelementptr inbounds float, float* %1, i64 3
%38 = load float, float* %37
%39 = fmul float %36, %38
%40 = getelementptr inbounds float, float* %1, i64 7
%41 = load float, float* %40
%42 = fmul float %39, %41
%43 = tail call float @llvm.fmuladd.f32(float %32, float %34, float %42)
%44 = getelementptr inbounds float, float* %1, i64 1
%45 = load float, float* %44
%46 = getelementptr inbounds float, float* %1, i64 5
%47 = load float, float* %46
%48 = fmul float %45, %47
%49 = getelementptr inbounds float, float* %1, i64 6
%50 = load float, float* %49
%51 = tail call float @llvm.fmuladd.f32(float %48, float %50, float %43)
%52 = fneg float %36
%53 = fmul float %31, %52
%54 = tail call float @llvm.fmuladd.f32(float %53, float %50, float %51)
%55 = fneg float %45
%56 = fmul float %38, %55
%57 = tail call float @llvm.fmuladd.f32(float %56, float %34, float %54)
%58 = fneg float %29
%59 = fmul float %47, %58
%60 = tail call float @llvm.fmuladd.f32(float %59, float %41, float %57)
store float %60, float* %0
br label %63
61: ; preds = %3
%62 = tail call i32 @fail(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str, i64 0, i64 0), i32 %2)
br label %63
63: ; preds = %61, %28, %17, %6, %4
ret i32 1
}