#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_4x4() {
  int dim = 4;
  double a[4][4] = {{11, 9, 24, 2}, {1, 5, 2, 6}, {3, 17, 18, 1}, {2, 5, 7, 1}};
  double l[4][4] = {{1.00000, 0.00000, 0.00000, 0.00000},
                    {0.27273, 1.00000, 0.00000, 0.00000},
                    {0.09091, 0.28750, 1.00000, 0.00000},
                    {0.18182, 0.23125, 0.00360, 1.00000}};
  double u[4][4] = {{11.00000, 9.00000, 24.00000, 2.00000},
                    {0.00000, 14.54545, 11.45455, 0.45455},
                    {0.00000, 0.00000, -3.47500, 5.68750},
                    {0.00000, 0.00000, 0.00000, 0.51079}};
  double p[4][4] = {{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 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_4x4>:
push   %rbp
mov    %rsp,%rbp
sub    $0x250,%rsp
movl   $0x4,-0x4(%rbp)
lea    -0x90(%rbp),%rdi
lea    0xe80(%rip),%rsi
mov    $0x80,%edx
call   1080 <memcpy@plt>
lea    -0x110(%rbp),%rdi
lea    0xee8(%rip),%rsi
mov    $0x80,%edx
call   1080 <memcpy@plt>
lea    -0x190(%rbp),%rdi
lea    0xf50(%rip),%rsi
mov    $0x80,%edx
call   1080 <memcpy@plt>
lea    -0x210(%rbp),%rdi
xor    %esi,%esi
mov    $0x80,%edx
call   1050 <memset@plt>
movsd  0xe1b(%rip),%xmm0
movsd  %xmm0,-0x210(%rbp)
ff
movsd  0xe0b(%rip),%xmm0
movsd  %xmm0,-0x1e0(%rbp)
ff
movsd  0xdfb(%rip),%xmm0
movsd  %xmm0,-0x1c8(%rbp)
ff
movsd  0xdeb(%rip),%xmm0
movsd  %xmm0,-0x198(%rbp)
ff
mov    -0x4(%rbp),%edi
lea    -0x90(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x218(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,-0x220(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,-0x228(%rbp)
mov    -0x4(%rbp),%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,-0x230(%rbp)
mov    -0x4(%rbp),%edi
lea    -0x110(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x240(%rbp)
mov    -0x4(%rbp),%edi
lea    -0x190(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x248(%rbp)
mov    -0x4(%rbp),%edi
lea    -0x210(%rbp),%rsi
call   1060 <matriz_valores_quadrada@plt>
mov    %rax,-0x238(%rbp)
mov    -0x218(%rbp),%rdi
mov    -0x4(%rbp),%esi
mov    -0x228(%rbp),%rdx
mov    -0x230(%rbp),%rcx
mov    -0x220(%rbp),%r8
call   1070 <fatoracao_lu@plt>
mov    -0x218(%rbp),%rdi
mov    -0x240(%rbp),%rsi
mov    -0x248(%rbp),%rdx
mov    -0x238(%rbp),%rcx
mov    -0x4(%rbp),%r8d
call   1090 <imprime_teste_fatoracao_lu@plt>
mov    -0x218(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x218(%rbp)
mov    -0x220(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x220(%rbp)
mov    -0x228(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x228(%rbp)
mov    -0x230(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x230(%rbp)
mov    -0x238(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x238(%rbp)
mov    -0x240(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x240(%rbp)
mov    -0x248(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x248(%rbp)
add    $0x250,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<teste_fatoracao_4x4>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x218,%rsp
movaps 0xf08(%rip),%xmm0
movaps %xmm0,0x200(%rsp)
movaps 0xee9(%rip),%xmm0
movaps %xmm0,0x1f0(%rsp)
movaps 0xeca(%rip),%xmm0
movaps %xmm0,0x1e0(%rsp)
movaps 0xeab(%rip),%xmm0
movaps %xmm0,0x1d0(%rsp)
movaps 0xe8c(%rip),%xmm0
movaps %xmm0,0x1c0(%rsp)
movaps 0xe6d(%rip),%xmm0
movaps %xmm0,0x1b0(%rsp)
movaps 0xe4e(%rip),%xmm0
movaps %xmm0,0x1a0(%rsp)
movaps 0xe2f(%rip),%xmm0
movaps %xmm0,0x190(%rsp)
movaps 0xf10(%rip),%xmm0
movaps %xmm0,0x180(%rsp)
movaps 0xef1(%rip),%xmm0
movaps %xmm0,0x170(%rsp)
movaps 0xed2(%rip),%xmm0
movaps %xmm0,0x160(%rsp)
movaps 0xeb3(%rip),%xmm0
movaps %xmm0,0x150(%rsp)
movaps 0xe94(%rip),%xmm0
movaps %xmm0,0x140(%rsp)
movaps 0xe75(%rip),%xmm0
movaps %xmm0,0x130(%rsp)
movaps 0xe56(%rip),%xmm0
movaps %xmm0,0x120(%rsp)
movaps 0xe37(%rip),%xmm0
movaps %xmm0,0x110(%rsp)
movaps 0xf18(%rip),%xmm0
movaps %xmm0,0x100(%rsp)
movaps 0xef9(%rip),%xmm0
movaps %xmm0,0xf0(%rsp)
movaps 0xeda(%rip),%xmm0
movaps %xmm0,0xe0(%rsp)
movaps 0xebb(%rip),%xmm0
movaps %xmm0,0xd0(%rsp)
movaps 0xe9c(%rip),%xmm0
movaps %xmm0,0xc0(%rsp)
movaps 0xe7d(%rip),%xmm0
movaps %xmm0,0xb0(%rsp)
movaps 0xe5e(%rip),%xmm0
movaps %xmm0,0xa0(%rsp)
movaps 0xe3f(%rip),%xmm0
movaps %xmm0,0x90(%rsp)
xorps  %xmm0,%xmm0
movaps %xmm0,0x10(%rsp)
movaps %xmm0,0x40(%rsp)
movaps %xmm0,0x50(%rsp)
movaps %xmm0,0x80(%rsp)
movaps %xmm0,0x70(%rsp)
movaps %xmm0,0x60(%rsp)
movaps %xmm0,0x30(%rsp)
movaps %xmm0,0x20(%rsp)
movabs $0x3ff0000000000000,%rax
mov    %rax,0x10(%rsp)
mov    %rax,0x40(%rsp)
mov    %rax,0x58(%rsp)
mov    %rax,0x88(%rsp)
lea    0x190(%rsp),%rsi
mov    $0x4,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r15
mov    $0x4,%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,0x8(%rsp)
mov    $0x4,%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,%rbp
mov    $0x4,%edi
call   1040 <matriz_quadrada_nula@plt>
mov    %rax,%rbx
mov    %rax,(%rsp)
lea    0x110(%rsp),%rsi
mov    $0x4,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r13
lea    0x90(%rsp),%rsi
mov    $0x4,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r12
lea    0x10(%rsp),%rsi
mov    $0x4,%edi
call   1050 <matriz_valores_quadrada@plt>
mov    %rax,%r14
mov    %r15,%rdi
mov    $0x4,%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    $0x4,%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    $0x218,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.teste_fatoracao_4x4.a = [4 x [4 x double]] [[4 x double] [double 1.100000e+01, double 9.000000e+00, double 2.400000e+01, double 2.000000e+00], [4 x double] [double 1.000000e+00, double 5.000000e+00, double 2.000000e+00, double 6.000000e+00], [4 x double] [double 3.000000e+00, double 1.700000e+01, double 1.800000e+01, double 1.000000e+00], [4 x double] [double 2.000000e+00, double 5.000000e+00, double 7.000000e+00, double 1.000000e+00]]
@__const.teste_fatoracao_4x4.l = [4 x [4 x double]] [[4 x double] [double 1.000000e+00, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00], [4 x double] [double 2.727300e-01, double 1.000000e+00, double 0.000000e+00, double 0.000000e+00], [4 x double] [double 9.091000e-02, double 2.875000e-01, double 1.000000e+00, double 0.000000e+00], [4 x double] [double 1.818200e-01, double 2.312500e-01, double 3.600000e-03, double 1.000000e+00]]
@__const.teste_fatoracao_4x4.u = [4 x [4 x double]] [[4 x double] [double 1.100000e+01, double 9.000000e+00, double 2.400000e+01, double 2.000000e+00], [4 x double] [double 0.000000e+00, double 0x402D174538EF34D7, double 0x4026E8BAC710CB29, double 4.545500e-01], [4 x double] [double 0.000000e+00, double 0.000000e+00, double -3.475000e+00, double 5.687500e+00], [4 x double] [double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double 5.107900e-01]]
define void @teste_fatoracao_4x4() {
%1 = alloca i32
%2 = alloca [4 x [4 x double]]
%3 = alloca [4 x [4 x double]]
%4 = alloca [4 x [4 x double]]
%5 = alloca [4 x [4 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 4, i32* %1
%13 = bitcast [4 x [4 x double]]* %2 to i8*
%14 = bitcast [4 x [4 x double]]* %3 to i8*
%15 = bitcast [4 x [4 x double]]* %4 to i8*
%16 = bitcast [4 x [4 x double]]* %5 to i8*
%17 = bitcast i8* %16 to [4 x [4 x double]]*
%18 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %17, i32 0, i32 0
%19 = getelementptr inbounds [4 x double], [4 x double]* %18, i32 0, i32 0
store double 1.000000e+00, double* %19
%20 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %17, i32 0, i32 1
%21 = getelementptr inbounds [4 x double], [4 x double]* %20, i32 0, i32 2
store double 1.000000e+00, double* %21
%22 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %17, i32 0, i32 2
%23 = getelementptr inbounds [4 x double], [4 x double]* %22, i32 0, i32 1
store double 1.000000e+00, double* %23
%24 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %17, i32 0, i32 3
%25 = getelementptr inbounds [4 x double], [4 x double]* %24, i32 0, i32 3
store double 1.000000e+00, double* %25
%26 = load i32, i32* %1
%27 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %2, i64 0, i64 0
%28 = getelementptr inbounds [4 x double], [4 x double]* %27, i64 0, i64 0
%29 = call double** @matriz_valores_quadrada(i32 %26, double* %28)
store double** %29, double*** %6
%30 = load i32, i32* %1
%31 = call double** @matriz_quadrada_nula(i32 %30)
store double** %31, double*** %7
%32 = load i32, i32* %1
%33 = call double** @matriz_quadrada_nula(i32 %32)
store double** %33, double*** %8
%34 = load i32, i32* %1
%35 = call double** @matriz_quadrada_nula(i32 %34)
store double** %35, double*** %9
%36 = load i32, i32* %1
%37 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %3, i64 0, i64 0
%38 = getelementptr inbounds [4 x double], [4 x double]* %37, i64 0, i64 0
%39 = call double** @matriz_valores_quadrada(i32 %36, double* %38)
store double** %39, double*** %11
%40 = load i32, i32* %1
%41 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %4, i64 0, i64 0
%42 = getelementptr inbounds [4 x double], [4 x double]* %41, i64 0, i64 0
%43 = call double** @matriz_valores_quadrada(i32 %40, double* %42)
store double** %43, double*** %12
%44 = load i32, i32* %1
%45 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %5, i64 0, i64 0
%46 = getelementptr inbounds [4 x double], [4 x double]* %45, i64 0, i64 0
%47 = call double** @matriz_valores_quadrada(i32 %44, double* %46)
store double** %47, double*** %10
%48 = load double**, double*** %6
%49 = load i32, i32* %1
%50 = load double**, double*** %8
%51 = load double**, double*** %9
%52 = load double**, double*** %7
%53 = call i32 @fatoracao_lu(double** %48, i32 %49, double** %50, double** %51, double** %52)
%54 = load double**, double*** %6
%55 = load double**, double*** %11
%56 = load double**, double*** %12
%57 = load double**, double*** %10
%58 = load i32, i32* %1
%59 = call i32 @imprime_teste_fatoracao_lu(double** %54, double** %55, double** %56, double** %57, i32 %58)
%60 = load double**, double*** %6
%61 = call i32 @free(double** %60)
store double** null, double*** %6
%62 = load double**, double*** %7
%63 = call i32 @free(double** %62)
store double** null, double*** %7
%64 = load double**, double*** %8
%65 = call i32 @free(double** %64)
store double** null, double*** %8
%66 = load double**, double*** %9
%67 = call i32 @free(double** %66)
store double** null, double*** %9
%68 = load double**, double*** %10
%69 = call i32 @free(double** %68)
store double** null, double*** %10
%70 = load double**, double*** %11
%71 = call i32 @free(double** %70)
store double** null, double*** %11
%72 = load double**, double*** %12
%73 = call i32 @free(double** %72)
store double** null, double*** %12
ret void
}

LLVM IR (-O2):
@__const.teste_fatoracao_4x4.a = [4 x [4 x double]] [[4 x double] [double 1.100000e+01, double 9.000000e+00, double 2.400000e+01, double 2.000000e+00], [4 x double] [double 1.000000e+00, double 5.000000e+00, double 2.000000e+00, double 6.000000e+00], [4 x double] [double 3.000000e+00, double 1.700000e+01, double 1.800000e+01, double 1.000000e+00], [4 x double] [double 2.000000e+00, double 5.000000e+00, double 7.000000e+00, double 1.000000e+00]]
@__const.teste_fatoracao_4x4.l = [4 x [4 x double]] [[4 x double] [double 1.000000e+00, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00], [4 x double] [double 2.727300e-01, double 1.000000e+00, double 0.000000e+00, double 0.000000e+00], [4 x double] [double 9.091000e-02, double 2.875000e-01, double 1.000000e+00, double 0.000000e+00], [4 x double] [double 1.818200e-01, double 2.312500e-01, double 3.600000e-03, double 1.000000e+00]]
@__const.teste_fatoracao_4x4.u = [4 x [4 x double]] [[4 x double] [double 1.100000e+01, double 9.000000e+00, double 2.400000e+01, double 2.000000e+00], [4 x double] [double 0.000000e+00, double 0x402D174538EF34D7, double 0x4026E8BAC710CB29, double 4.545500e-01], [4 x double] [double 0.000000e+00, double 0.000000e+00, double -3.475000e+00, double 5.687500e+00], [4 x double] [double 0.000000e+00, double 0.000000e+00, double 0.000000e+00, double 5.107900e-01]]
define void @teste_fatoracao_4x4() {
%1 = alloca [4 x [4 x double]]
%2 = alloca [4 x [4 x double]]
%3 = alloca [4 x [4 x double]]
%4 = alloca [4 x [4 x double]]
%5 = bitcast [4 x [4 x double]]* %1 to i8*
%6 = bitcast [4 x [4 x double]]* %2 to i8*
%7 = bitcast [4 x [4 x double]]* %3 to i8*
%8 = bitcast [4 x [4 x double]]* %4 to i8*
%9 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %4, i64 0, i64 0, i64 0
store double 1.000000e+00, double* %9
%10 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %4, i64 0, i64 1, i64 2
store double 1.000000e+00, double* %10
%11 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %4, i64 0, i64 2, i64 1
store double 1.000000e+00, double* %11
%12 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %4, i64 0, i64 3, i64 3
store double 1.000000e+00, double* %12
%13 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %1, i64 0, i64 0, i64 0
%14 = call double** @matriz_valores_quadrada(i32 4, double* %13)
%15 = call double** @matriz_quadrada_nula(i32 4)
%16 = call double** @matriz_quadrada_nula(i32 4)
%17 = call double** @matriz_quadrada_nula(i32 4)
%18 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %2, i64 0, i64 0, i64 0
%19 = call double** @matriz_valores_quadrada(i32 4, double* %18)
%20 = getelementptr inbounds [4 x [4 x double]], [4 x [4 x double]]* %3, i64 0, i64 0, i64 0
%21 = call double** @matriz_valores_quadrada(i32 4, double* %20)
%22 = call double** @matriz_valores_quadrada(i32 4, double* %9)
%23 = call i32 @fatoracao_lu(double** %14, i32 4, double** %16, double** %17, double** %15)
%24 = call i32 @imprime_teste_fatoracao_lu(double** %14, double** %19, double** %21, double** %22, i32 4)
%25 = call i32 @free(double** %14)
%26 = call i32 @free(double** %15)
%27 = call i32 @free(double** %16)
%28 = call i32 @free(double** %17)
%29 = call i32 @free(double** %22)
%30 = call i32 @free(double** %19)
%31 = call i32 @free(double** %21)
ret void
}