#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*/ fatoracao_lu(double **, int, double **, double **,
                                double **);
int /*<<< orphan*/ free(double **);
int /*<<< orphan*/ imprime_teste_fatoracao_lu(double **, double **, double **,
                                              double **, int);
double **matriz_quadrada_nula(int);
double **matriz_valores_quadrada(int, double *);
void teste_fatoracao_3x3() {
  int dim = 3;
  double a[3][3] = {{1, 3, 5}, {2, 4, 7}, {1, 1, 0}};
  double l[3][3] = {{1, 0, 0}, {0.5, 1, 0}, {0.5, -1, 1}};
  double u[3][3] = {{2, 4, 7}, {0, 1, 1.5}, {0, 0, -2}};
  double p[3][3] = {{0, 1, 0}, {1, 0, 0}, {0, 0, 1}};
  double **A, **P, **L, **U;
  double **P_correto, **L_correto, **U_correto;
  A = matriz_valores_quadrada(dim, &a[0][0]);
  P = matriz_quadrada_nula(dim);
  L = matriz_quadrada_nula(dim);
  U = matriz_quadrada_nula(dim);
  L_correto = matriz_valores_quadrada(dim, &l[0][0]);
  U_correto = matriz_valores_quadrada(dim, &u[0][0]);
  P_correto = matriz_valores_quadrada(dim, &p[0][0]);
  fatoracao_lu(A, dim, L, U, P);
  imprime_teste_fatoracao_lu(A, L_correto, U_correto, P_correto, dim);
  free(A);
  A = NULL;
  free(P);
  P = NULL;
  free(L);
  L = NULL;
  free(U);
  U = NULL;
  free(P_correto);
  P_correto = NULL;
  free(L_correto);
  L_correto = NULL;
  free(U_correto);
  U_correto = NULL;
}


x86 assembly (clang, -O0):
<teste_fatoracao_3x3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x180,%rsp
movl   $0x3,-0x4(%rbp)
lea    -0x50(%rbp),%rdi
lea    0xeb3(%rip),%rsi
mov    $0x48,%edx
call   1080 <memcpy@plt>
lea    -0xa0(%rbp),%rdi
xor    %esi,%esi
mov    $0x48,%edx
call   1050 <memset@plt>
movsd  0xe4e(%rip),%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  0xe76(%rip),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
movsd  0xe2e(%rip),%xmm0
movsd  %xmm0,-0x80(%rbp)
movsd  0xe59(%rip),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  0xe44(%rip),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  0xe07(%rip),%xmm0
movsd  %xmm0,-0x60(%rbp)
lea    -0xf0(%rbp),%rdi
xor    %esi,%esi
mov    $0x48,%edx
call   1050 <memset@plt>
movsd  0xe0f(%rip),%xmm0
movsd  %xmm0,-0xf0(%rbp)
ff
movsd  0xdf7(%rip),%xmm0
movsd  %xmm0,-0xe8(%rbp)
ff
movsd  0xddf(%rip),%xmm0
movsd  %xmm0,-0xe0(%rbp)
ff
movsd  0xdb7(%rip),%xmm0
movsd  %xmm0,-0xd0(%rbp)
ff
movsd  0xdb7(%rip),%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
movsd  0xd9f(%rip),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
lea    -0x140(%rbp),%rdi
xor    %esi,%esi
mov    $0x48,%edx
call   1050 <memset@plt>
movsd  0xd74(%rip),%xmm0
movsd  %xmm0,-0x138(%rbp)
ff
movsd  0xd64(%rip),%xmm0
movsd  %xmm0,-0x128(%rbp)
ff
movsd  0xd54(%rip),%xmm0
movsd  %xmm0,-0x100(%rbp)
ff
mov    -0x4(%rbp),%edi
lea    -0x50(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x148(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,-0x150(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,-0x158(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,-0x160(%rbp)
mov    -0x4(%rbp),%edi
lea    -0xa0(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x170(%rbp)
mov    -0x4(%rbp),%edi
lea    -0xf0(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x178(%rbp)
mov    -0x4(%rbp),%edi
lea    -0x140(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x168(%rbp)
mov    -0x148(%rbp),%rdi
mov    -0x4(%rbp),%esi
mov    -0x158(%rbp),%rdx
mov    -0x160(%rbp),%rcx
mov    -0x150(%rbp),%r8
call   1070 <fatoracao_lu@plt>
mov    -0x148(%rbp),%rdi
mov    -0x170(%rbp),%rsi
mov    -0x178(%rbp),%rdx
mov    -0x168(%rbp),%rcx
mov    -0x4(%rbp),%r8d
call   1090 <imprime_teste_fatoracao_lu@plt>
mov    -0x148(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x148(%rbp)
mov    -0x150(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x150(%rbp)
mov    -0x158(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x158(%rbp)
mov    -0x160(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x160(%rbp)
mov    -0x168(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x168(%rbp)
mov    -0x170(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x170(%rbp)
mov    -0x178(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x178(%rbp)
add    $0x180,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<teste_fatoracao_3x3>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x148,%rsp
mov    0xf18(%rip),%rax
mov    %rax,0x140(%rsp)
movaps 0xef9(%rip),%xmm0
movaps %xmm0,0x130(%rsp)
movaps 0xeda(%rip),%xmm0
movaps %xmm0,0x120(%rsp)
movaps 0xebb(%rip),%xmm0
movaps %xmm0,0x110(%rsp)
movaps 0xe9c(%rip),%xmm0
movaps %xmm0,0x100(%rsp)
xorps  %xmm0,%xmm0
movaps %xmm0,0x60(%rsp)
movaps %xmm0,0x80(%rsp)
movaps %xmm0,0x70(%rsp)
movabs $0x3ff0000000000000,%rax
mov    %rax,0x60(%rsp)
movaps 0xe29(%rip),%xmm1
movups %xmm1,0x78(%rsp)
movaps 0xe2d(%rip),%xmm1
movaps %xmm1,0x90(%rsp)
mov    %rax,0xa0(%rsp)
movaps %xmm0,0xc0(%rsp)
movaps %xmm0,0xe0(%rsp)
movaps 0xe16(%rip),%xmm1
movaps %xmm1,0xb0(%rsp)
movabs $0x401c000000000000,%rcx
mov    %rcx,0xc0(%rsp)
movaps 0xe05(%rip),%xmm1
movaps %xmm1,0xd0(%rsp)
movabs $0xc000000000000000,%rcx
mov    %rcx,0xf0(%rsp)
movaps %xmm0,0x10(%rsp)
movaps %xmm0,0x20(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x30(%rsp)
mov    %rax,0x18(%rsp)
mov    %rax,0x28(%rsp)
mov    %rax,0x50(%rsp)
lea    0x100(%rsp),%rsi
mov    $0x3,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r15
mov    $0x3,%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,0x8(%rsp)
mov    $0x3,%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,%rbp
mov    $0x3,%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,%rbx
mov    %rax,(%rsp)
lea    0x60(%rsp),%rsi
mov    $0x3,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r13
lea    0xb0(%rsp),%rsi
mov    $0x3,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r12
lea    0x10(%rsp),%rsi
mov    $0x3,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r14
mov    %r15,%rdi
mov    $0x3,%esi
mov    %rbp,%rdx
mov    %rbx,%rcx
mov    0x8(%rsp),%rbx
mov    %rbx,%r8
call   1060 <fatoracao_lu@plt>
mov    %r15,%rdi
mov    %r13,%rsi
mov    %r12,%rdx
mov    %r14,%rcx
mov    $0x3,%r8d
call   1070 <imprime_teste_fatoracao_lu@plt>
mov    %r15,%rdi
call   1030 <free@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %rbp,%rdi
call   1030 <free@plt>
mov    (%rsp),%rdi
call   1030 <free@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    %r13,%rdi
call   1030 <free@plt>
mov    %r12,%rdi
call   1030 <free@plt>
add    $0x148,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.teste_fatoracao_3x3.a = [3 x [3 x double]] [[3 x double] [double 1.000000e+00, double 3.000000e+00, double 5.000000e+00], [3 x double] [double 2.000000e+00, double 4.000000e+00, double 7.000000e+00], [3 x double] [double 1.000000e+00, double 1.000000e+00, double 0.000000e+00]]
define void @teste_fatoracao_3x3() {
%1 = alloca i32
%2 = alloca [3 x [3 x double]]
%3 = alloca [3 x [3 x double]]
%4 = alloca [3 x [3 x double]]
%5 = alloca [3 x [3 x double]]
%6 = alloca double**
%7 = alloca double**
%8 = alloca double**
%9 = alloca double**
%10 = alloca double**
%11 = alloca double**
%12 = alloca double**
store i32 3, i32* %1
%13 = bitcast [3 x [3 x double]]* %2 to i8*
%14 = bitcast [3 x [3 x double]]* %3 to i8*
%15 = bitcast i8* %14 to [3 x [3 x double]]*
%16 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %15, i32 0, i32 0
%17 = getelementptr inbounds [3 x double], [3 x double]* %16, i32 0, i32 0
store double 1.000000e+00, double* %17
%18 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %15, i32 0, i32 1
%19 = getelementptr inbounds [3 x double], [3 x double]* %18, i32 0, i32 0
store double 5.000000e-01, double* %19
%20 = getelementptr inbounds [3 x double], [3 x double]* %18, i32 0, i32 1
store double 1.000000e+00, double* %20
%21 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %15, i32 0, i32 2
%22 = getelementptr inbounds [3 x double], [3 x double]* %21, i32 0, i32 0
store double 5.000000e-01, double* %22
%23 = getelementptr inbounds [3 x double], [3 x double]* %21, i32 0, i32 1
store double -1.000000e+00, double* %23
%24 = getelementptr inbounds [3 x double], [3 x double]* %21, i32 0, i32 2
store double 1.000000e+00, double* %24
%25 = bitcast [3 x [3 x double]]* %4 to i8*
%26 = bitcast i8* %25 to [3 x [3 x double]]*
%27 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %26, i32 0, i32 0
%28 = getelementptr inbounds [3 x double], [3 x double]* %27, i32 0, i32 0
store double 2.000000e+00, double* %28
%29 = getelementptr inbounds [3 x double], [3 x double]* %27, i32 0, i32 1
store double 4.000000e+00, double* %29
%30 = getelementptr inbounds [3 x double], [3 x double]* %27, i32 0, i32 2
store double 7.000000e+00, double* %30
%31 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %26, i32 0, i32 1
%32 = getelementptr inbounds [3 x double], [3 x double]* %31, i32 0, i32 1
store double 1.000000e+00, double* %32
%33 = getelementptr inbounds [3 x double], [3 x double]* %31, i32 0, i32 2
store double 1.500000e+00, double* %33
%34 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %26, i32 0, i32 2
%35 = getelementptr inbounds [3 x double], [3 x double]* %34, i32 0, i32 2
store double -2.000000e+00, double* %35
%36 = bitcast [3 x [3 x double]]* %5 to i8*
%37 = bitcast i8* %36 to [3 x [3 x double]]*
%38 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %37, i32 0, i32 0
%39 = getelementptr inbounds [3 x double], [3 x double]* %38, i32 0, i32 1
store double 1.000000e+00, double* %39
%40 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %37, i32 0, i32 1
%41 = getelementptr inbounds [3 x double], [3 x double]* %40, i32 0, i32 0
store double 1.000000e+00, double* %41
%42 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %37, i32 0, i32 2
%43 = getelementptr inbounds [3 x double], [3 x double]* %42, i32 0, i32 2
store double 1.000000e+00, double* %43
%44 = load i32, i32* %1
%45 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %2, i64 0, i64 0
%46 = getelementptr inbounds [3 x double], [3 x double]* %45, i64 0, i64 0
%47 = call double** @matriz_valores_quadrada(i32 %44, double* %46)
store double** %47, double*** %6
%48 = load i32, i32* %1
%49 = call double** @matriz_quadrada_nula(i32 %48)
store double** %49, double*** %7
%50 = load i32, i32* %1
%51 = call double** @matriz_quadrada_nula(i32 %50)
store double** %51, double*** %8
%52 = load i32, i32* %1
%53 = call double** @matriz_quadrada_nula(i32 %52)
store double** %53, double*** %9
%54 = load i32, i32* %1
%55 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %3, i64 0, i64 0
%56 = getelementptr inbounds [3 x double], [3 x double]* %55, i64 0, i64 0
%57 = call double** @matriz_valores_quadrada(i32 %54, double* %56)
store double** %57, double*** %11
%58 = load i32, i32* %1
%59 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 0
%60 = getelementptr inbounds [3 x double], [3 x double]* %59, i64 0, i64 0
%61 = call double** @matriz_valores_quadrada(i32 %58, double* %60)
store double** %61, double*** %12
%62 = load i32, i32* %1
%63 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %5, i64 0, i64 0
%64 = getelementptr inbounds [3 x double], [3 x double]* %63, i64 0, i64 0
%65 = call double** @matriz_valores_quadrada(i32 %62, double* %64)
store double** %65, double*** %10
%66 = load double**, double*** %6
%67 = load i32, i32* %1
%68 = load double**, double*** %8
%69 = load double**, double*** %9
%70 = load double**, double*** %7
%71 = call i32 @fatoracao_lu(double** %66, i32 %67, double** %68, double** %69, double** %70)
%72 = load double**, double*** %6
%73 = load double**, double*** %11
%74 = load double**, double*** %12
%75 = load double**, double*** %10
%76 = load i32, i32* %1
%77 = call i32 @imprime_teste_fatoracao_lu(double** %72, double** %73, double** %74, double** %75, i32 %76)
%78 = load double**, double*** %6
%79 = call i32 @free(double** %78)
store double** null, double*** %6
%80 = load double**, double*** %7
%81 = call i32 @free(double** %80)
store double** null, double*** %7
%82 = load double**, double*** %8
%83 = call i32 @free(double** %82)
store double** null, double*** %8
%84 = load double**, double*** %9
%85 = call i32 @free(double** %84)
store double** null, double*** %9
%86 = load double**, double*** %10
%87 = call i32 @free(double** %86)
store double** null, double*** %10
%88 = load double**, double*** %11
%89 = call i32 @free(double** %88)
store double** null, double*** %11
%90 = load double**, double*** %12
%91 = call i32 @free(double** %90)
store double** null, double*** %12
ret void
}

LLVM IR (-O2):
@__const.teste_fatoracao_3x3.a = [3 x [3 x double]] [[3 x double] [double 1.000000e+00, double 3.000000e+00, double 5.000000e+00], [3 x double] [double 2.000000e+00, double 4.000000e+00, double 7.000000e+00], [3 x double] [double 1.000000e+00, double 1.000000e+00, double 0.000000e+00]]
define void @teste_fatoracao_3x3() {
%1 = alloca [3 x [3 x double]]
%2 = alloca [3 x [3 x double]]
%3 = alloca [3 x [3 x double]]
%4 = alloca [3 x [3 x double]]
%5 = bitcast [3 x [3 x double]]* %1 to i8*
%6 = bitcast [3 x [3 x double]]* %2 to i8*
%7 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %2, i64 0, i64 0, i64 0
store double 1.000000e+00, double* %7
%8 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %2, i64 0, i64 1, i64 0
%9 = bitcast double* %8 to <2 x double>*
store <2 x double> <double 5.000000e-01, double 1.000000e+00>, <2 x double>* %9
%10 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %2, i64 0, i64 2, i64 0
%11 = bitcast double* %10 to <2 x double>*
store <2 x double> <double 5.000000e-01, double -1.000000e+00>, <2 x double>* %11
%12 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %2, i64 0, i64 2, i64 2
store double 1.000000e+00, double* %12
%13 = bitcast [3 x [3 x double]]* %3 to i8*
%14 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %3, i64 0, i64 0, i64 2
%15 = bitcast double* %14 to i8*
%16 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %3, i64 0, i64 0, i64 0
%17 = bitcast [3 x [3 x double]]* %3 to <2 x double>*
store <2 x double> <double 2.000000e+00, double 4.000000e+00>, <2 x double>* %17
%18 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %3, i64 0, i64 0, i64 2
store double 7.000000e+00, double* %18
%19 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %3, i64 0, i64 1, i64 1
%20 = bitcast double* %19 to <2 x double>*
store <2 x double> <double 1.000000e+00, double 1.500000e+00>, <2 x double>* %20
%21 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %3, i64 0, i64 2, i64 2
store double -2.000000e+00, double* %21
%22 = bitcast [3 x [3 x double]]* %4 to i8*
%23 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 0, i64 1
store double 1.000000e+00, double* %23
%24 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 1, i64 0
store double 1.000000e+00, double* %24
%25 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 2, i64 2
store double 1.000000e+00, double* %25
%26 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %1, i64 0, i64 0, i64 0
%27 = call double** @matriz_valores_quadrada(i32 3, double* %26)
%28 = call double** @matriz_quadrada_nula(i32 3)
%29 = call double** @matriz_quadrada_nula(i32 3)
%30 = call double** @matriz_quadrada_nula(i32 3)
%31 = call double** @matriz_valores_quadrada(i32 3, double* %7)
%32 = call double** @matriz_valores_quadrada(i32 3, double* %16)
%33 = getelementptr inbounds [3 x [3 x double]], [3 x [3 x double]]* %4, i64 0, i64 0, i64 0
%34 = call double** @matriz_valores_quadrada(i32 3, double* %33)
%35 = call i32 @fatoracao_lu(double** %27, i32 3, double** %29, double** %30, double** %28)
%36 = call i32 @imprime_teste_fatoracao_lu(double** %27, double** %31, double** %32, double** %34, i32 3)
%37 = call i32 @free(double** %27)
%38 = call i32 @free(double** %28)
%39 = call i32 @free(double** %29)
%40 = call i32 @free(double** %30)
%41 = call i32 @free(double** %34)
%42 = call i32 @free(double** %31)
%43 = call i32 @free(double** %32)
ret void
}