#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*/ imprimir_matriz(int **, int, int);
int /*<<< orphan*/ imprimir_matriz_2(int *, int, int);
int /*<<< orphan*/ imprimir_vetor(int *, int);
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ somar_matrizes(int **, int **, int **, int, int);
int main() {
  int matriz[3][3] = {{5, 4, 3}, {2, 3, 1}, {9, 9, 0}};
  printf("\n");
  imprimir_matriz(matriz, 3, 3);
  printf("\n");
  imprimir_matriz_2(&(matriz[0][0]), 3, 3);
  printf("\n");
  imprimir_vetor(&(matriz[0][0]), 3 * 3);
  printf("\n");
  somar_matrizes(matriz, matriz, matriz, 3, 3);
  imprimir_matriz(matriz, 3, 3);
  printf("\n");
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movl   $0x0,-0x4(%rbp)
lea    -0x30(%rbp),%rdi
lea    0xe86(%rip),%rsi
mov    $0x24,%edx
call   1060 <memcpy@plt>
lea    0xe99(%rip),%rdi
call   1030 <printf@plt>
lea    -0x30(%rbp),%rdi
mov    $0x3,%edx
mov    %edx,%esi
call   1050 <imprimir_matriz@plt>
lea    0xe7d(%rip),%rdi
call   1030 <printf@plt>
lea    -0x30(%rbp),%rdi
mov    $0x3,%edx
mov    %edx,%esi
call   1080 <imprimir_matriz_2@plt>
lea    0xe61(%rip),%rdi
call   1030 <printf@plt>
lea    -0x30(%rbp),%rdi
mov    $0x9,%esi
call   1040 <imprimir_vetor@plt>
lea    0xe47(%rip),%rdi
call   1030 <printf@plt>
lea    -0x30(%rbp),%rdi
lea    -0x30(%rbp),%rsi
lea    -0x30(%rbp),%rdx
mov    $0x3,%r8d
mov    %r8d,%ecx
call   1070 <somar_matrizes@plt>
lea    -0x30(%rbp),%rdi
mov    $0x3,%edx
mov    %edx,%esi
call   1050 <imprimir_matriz@plt>
lea    0xe11(%rip),%rdi
call   1030 <printf@plt>
xor    %eax,%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbx
sub    $0x30,%rsp
mov    0xec5(%rip),%eax
mov    %eax,0x20(%rsp)
movaps 0xeaa(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xe8e(%rip),%xmm0
movaps %xmm0,(%rsp)
mov    $0xa,%edi
call   1030 <putchar@plt>
mov    %rsp,%rbx
mov    %rbx,%rdi
mov    $0x3,%esi
mov    $0x3,%edx
call   1050 <imprimir_matriz@plt>
mov    $0xa,%edi
call   1030 <putchar@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
mov    $0x3,%edx
call   1070 <imprimir_matriz_2@plt>
mov    $0xa,%edi
call   1030 <putchar@plt>
mov    %rbx,%rdi
mov    $0x9,%esi
call   1040 <imprimir_vetor@plt>
mov    $0xa,%edi
call   1030 <putchar@plt>
mov    %rbx,%rdi
mov    %rbx,%rsi
mov    %rbx,%rdx
mov    $0x3,%ecx
mov    $0x3,%r8d
call   1060 <somar_matrizes@plt>
mov    %rbx,%rdi
mov    $0x3,%esi
mov    $0x3,%edx
call   1050 <imprimir_matriz@plt>
mov    $0xa,%edi
call   1030 <putchar@plt>
xor    %eax,%eax
add    $0x30,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@__const.main.matriz = [3 x [3 x i32]] [[3 x i32] [i32 5, i32 4, i32 3], [3 x i32] [i32 2, i32 3, i32 1], [3 x i32] [i32 9, i32 9, i32 0]]
@.str = [2 x i8] c"\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [3 x [3 x i32]]
store i32 0, i32* %1
%3 = bitcast [3 x [3 x i32]]* %2 to i8*
%4 = call i32 @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%5 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%6 = bitcast [3 x i32]* %5 to i32**
%7 = call i32 @imprimir_matriz(i32** %6, i32 3, i32 3)
%8 = call i32 @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%9 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%10 = getelementptr inbounds [3 x i32], [3 x i32]* %9, i64 0, i64 0
%11 = call i32 @imprimir_matriz_2(i32* %10, i32 3, i32 3)
%12 = call i32 @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%13 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%14 = getelementptr inbounds [3 x i32], [3 x i32]* %13, i64 0, i64 0
%15 = call i32 @imprimir_vetor(i32* %14, i32 9)
%16 = call i32 @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
%17 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%18 = bitcast [3 x i32]* %17 to i32**
%19 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%20 = bitcast [3 x i32]* %19 to i32**
%21 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%22 = bitcast [3 x i32]* %21 to i32**
%23 = call i32 @somar_matrizes(i32** %18, i32** %20, i32** %22, i32 3, i32 3)
%24 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %2, i64 0, i64 0
%25 = bitcast [3 x i32]* %24 to i32**
%26 = call i32 @imprimir_matriz(i32** %25, i32 3, i32 3)
%27 = call i32 @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
ret i32 0
}

LLVM IR (-O2):
@__const.main.matriz = [3 x [3 x i32]] [[3 x i32] [i32 5, i32 4, i32 3], [3 x i32] [i32 2, i32 3, i32 1], [3 x i32] [i32 9, i32 9, i32 0]]
define i32 @main() {
%1 = alloca [3 x [3 x i32]]
%2 = bitcast [3 x [3 x i32]]* %1 to i8*
%3 = tail call i32 @putchar(i32 10)
%4 = bitcast [3 x [3 x i32]]* %1 to i32**
%5 = call i32 @imprimir_matriz(i32** %4, i32 3, i32 3)
%6 = call i32 @putchar(i32 10)
%7 = getelementptr inbounds [3 x [3 x i32]], [3 x [3 x i32]]* %1, i64 0, i64 0, i64 0
%8 = call i32 @imprimir_matriz_2(i32* %7, i32 3, i32 3)
%9 = call i32 @putchar(i32 10)
%10 = call i32 @imprimir_vetor(i32* %7, i32 9)
%11 = call i32 @putchar(i32 10)
%12 = call i32 @somar_matrizes(i32** %4, i32** %4, i32** %4, i32 3, i32 3)
%13 = call i32 @imprimir_matriz(i32** %4, i32 3, i32 3)
%14 = call i32 @putchar(i32 10)
ret i32 0
}