#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*/ printf(char *, char *);
void generate_macro_minus_matrix() {
  char *macro =
      "void** minus_matrix(char const* param_type, void** mat_1, void**  "
      "mat_2, int rows, int columns) { \n 	int i, j; \n 	"
      "if(strcmp(\"int\", param_type) == 0) { \n 		int** mat; \n "
      "		int** mat1 = (int**) mat_1; \n 		int** mat2 = (int**) "
      "mat_2; \n  		mat = calloc(rows, sizeof(void*)); \n 	"
      "	for(i=0; i<rows; i++) {  \n 			mat[i] = "
      "calloc(columns, sizeof(int)); \n 			for(j=0; "
      "j<columns; j++) { \n 				mat[i][j] = mat1[i][j] "
      "- mat2[i][j]; \n 			} \n 		} \n 	"
      "	return mat; \n 	} \n 	else { \n 		double** mat; \n "
      "		double** mat1 = (double**)mat_1; \n 		double** mat2 "
      "= (double**)mat_2; \n 		mat = calloc(rows, sizeof(void*)); \n "
      "		for(i=0; i<rows; i++) { \n 			mat[i] = "
      "calloc(columns, sizeof(double)); \n 			for(j=0; "
      "j<columns; j++) { \n 				mat[i][j] = mat1[i][j] "
      "- mat2[i][j]; \n 			} \n 		} \n 	"
      "	return mat; \n 	} \n 	void** mat = 0; \n 	return mat; \n }\n";
  printf("%s", macro);
}


x86 assembly (clang, -O0):
<generate_macro_minus_matrix>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
lea    0xee1(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rsi
lea    0x1202(%rip),%rdi
call   1030 <printf@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<generate_macro_minus_matrix>:
lea    0x1219(%rip),%rdi
lea    0xee2(%rip),%rsi
jmp    1030 <printf@plt>

LLVM IR (-O0):
@.str = [816 x i8] c"void** minus_matrix(char const* param_type, void** mat_1, void** mat_2, int rows, int columns) { \0A \09int i, j; \0A \09if(strcmp(\22int\22, param_type) == 0) { \0A \09\09int** mat; \0A \09\09int** mat1 = (int**) mat_1; \0A \09\09int** mat2 = (int**) mat_2; \0A \09\09mat = calloc(rows, sizeof(void*)); \0A \09\09for(i=0; i<rows; i++) { \0A \09\09\09mat[i] = calloc(columns, sizeof(int)); \0A \09\09\09for(j=0; j<columns; j++) { \0A \09\09\09\09mat[i][j] = mat1[i][j] - mat2[i][j]; \0A \09\09\09} \0A \09\09} \0A \09\09return mat; \0A \09} \0A \09else { \0A \09\09double** mat; \0A \09\09double** mat1 = (double**)mat_1; \0A \09\09double** mat2 = (double**)mat_2; \0A \09\09mat = calloc(rows, sizeof(void*)); \0A \09\09for(i=0; i<rows; i++) { \0A \09\09\09mat[i] = calloc(columns, sizeof(double)); \0A \09\09\09for(j=0; j<columns; j++) { \0A \09\09\09\09mat[i][j] = mat1[i][j] - mat2[i][j]; \0A \09\09\09} \0A \09\09} \0A \09\09return mat; \0A \09} \0A \09void** mat = 0; \0A \09return mat; \0A }\0A\00"
@.str.1 = [3 x i8] c"%s\00"
define void @generate_macro_minus_matrix() {
%1 = alloca i8*
store i8* getelementptr inbounds ([816 x i8], [816 x i8]* @.str, i64 0, i64 0), i8** %1
%2 = load i8*, i8** %1
%3 = call i32 @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), i8* %2)
ret void
}

LLVM IR (-O2):
@.str = [816 x i8] c"void** minus_matrix(char const* param_type, void** mat_1, void** mat_2, int rows, int columns) { \0A \09int i, j; \0A \09if(strcmp(\22int\22, param_type) == 0) { \0A \09\09int** mat; \0A \09\09int** mat1 = (int**) mat_1; \0A \09\09int** mat2 = (int**) mat_2; \0A \09\09mat = calloc(rows, sizeof(void*)); \0A \09\09for(i=0; i<rows; i++) { \0A \09\09\09mat[i] = calloc(columns, sizeof(int)); \0A \09\09\09for(j=0; j<columns; j++) { \0A \09\09\09\09mat[i][j] = mat1[i][j] - mat2[i][j]; \0A \09\09\09} \0A \09\09} \0A \09\09return mat; \0A \09} \0A \09else { \0A \09\09double** mat; \0A \09\09double** mat1 = (double**)mat_1; \0A \09\09double** mat2 = (double**)mat_2; \0A \09\09mat = calloc(rows, sizeof(void*)); \0A \09\09for(i=0; i<rows; i++) { \0A \09\09\09mat[i] = calloc(columns, sizeof(double)); \0A \09\09\09for(j=0; j<columns; j++) { \0A \09\09\09\09mat[i][j] = mat1[i][j] - mat2[i][j]; \0A \09\09\09} \0A \09\09} \0A \09\09return mat; \0A \09} \0A \09void** mat = 0; \0A \09return mat; \0A }\0A\00"
@.str.1 = [3 x i8] c"%s\00"
define void @generate_macro_minus_matrix() {
%1 = tail call i32 @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([816 x i8], [816 x i8]* @.str, i64 0, i64 0))
ret void
}