#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 */
struct ruspma_nn {
  int dummy;
};
struct ruspma_matrix {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ backpropagate(struct ruspma_nn *, struct ruspma_matrix *,
                                 struct ruspma_matrix *, double);
int /*<<< orphan*/ feedforward(struct ruspma_nn *, struct ruspma_matrix *);
int /*<<< orphan*/ free_network(struct ruspma_nn *);
struct ruspma_matrix *new_matrix_from(int, int, double *);
struct ruspma_nn *new_network(int, int, int, int);
int /*<<< orphan*/ print_out_matrix(int /*<<< orphan*/);
int /*<<< orphan*/ ruspma_rand_init();
int main(int args, char **argv) {
  ruspma_rand_init();
  double in1[2] = {(double)0.5, (double)0.4};
  double in2[2] = {(double)0.2, (double)0.9};
  double out1[2] = {(double)1.0, (double)0.0};
  double out2[2] = {(double)0.0, (double)1.0};
  struct ruspma_matrix *in1_m = new_matrix_from(1, 2, in1);
  struct ruspma_matrix *in2_m = new_matrix_from(1, 2, in2);
  struct ruspma_matrix *out1_m = new_matrix_from(1, 2, out1);
  struct ruspma_matrix *out2_m = new_matrix_from(1, 2, out2);
  struct ruspma_nn *k = new_network(2, 11, 2, 1);
  int mm;
  for (mm = 0; mm != 1500; ++mm) {
    backpropagate(k, in1_m, out1_m, 6.5);
    backpropagate(k, in2_m, out2_m, 6.5);
  }
  print_out_matrix(feedforward(k, in1_m));
  print_out_matrix(feedforward(k, in2_m));
  free_network(k);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    $0x0,%al
call   1040 <ruspma_rand_init@plt>
mov    0xe79(%rip),%rax
mov    %rax,-0x20(%rbp)
mov    0xe76(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    0xe73(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xe70(%rip),%rax
mov    %rax,-0x28(%rbp)
mov    0xe6d(%rip),%rax
mov    %rax,-0x40(%rbp)
mov    0xe6a(%rip),%rax
mov    %rax,-0x38(%rbp)
mov    0xe67(%rip),%rax
mov    %rax,-0x50(%rbp)
mov    0xe64(%rip),%rax
mov    %rax,-0x48(%rbp)
lea    -0x20(%rbp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,-0x58(%rbp)
lea    -0x30(%rbp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,-0x60(%rbp)
lea    -0x40(%rbp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,-0x68(%rbp)
lea    -0x50(%rbp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,-0x70(%rbp)
mov    $0x2,%edx
mov    $0xb,%esi
mov    $0x1,%ecx
mov    %edx,%edi
call   1050 <new_network@plt>
mov    %rax,-0x78(%rbp)
movl   $0x0,-0x7c(%rbp)
cmpl   $0x5dc,-0x7c(%rbp)
je     12b2 <main+0x142>
mov    -0x78(%rbp),%rdi
mov    -0x58(%rbp),%rsi
mov    -0x68(%rbp),%rdx
movsd  0xd7a(%rip),%xmm0
call   1080 <backpropagate@plt>
mov    -0x78(%rbp),%rdi
mov    -0x60(%rbp),%rsi
mov    -0x70(%rbp),%rdx
movsd  0xd61(%rip),%xmm0
call   1080 <backpropagate@plt>
mov    -0x7c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x7c(%rbp)
jmp    1265 <main+0xf5>
mov    -0x78(%rbp),%rdi
mov    -0x58(%rbp),%rsi
call   1060 <feedforward@plt>
mov    %eax,%edi
call   1030 <print_out_matrix@plt>
mov    -0x78(%rbp),%rdi
mov    -0x60(%rbp),%rsi
call   1060 <feedforward@plt>
mov    %eax,%edi
call   1030 <print_out_matrix@plt>
mov    -0x78(%rbp),%rdi
call   1070 <free_network@plt>
mov    -0x4(%rbp),%eax
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x48,%rsp
xor    %eax,%eax
call   1040 <ruspma_rand_init@plt>
movaps 0xe84(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xe88(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xe8c(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xe90(%rip),%xmm0
movaps %xmm0,(%rsp)
lea    0x30(%rsp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,%r15
lea    0x20(%rsp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,%r14
lea    0x10(%rsp),%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,%r12
mov    %rsp,%rdx
mov    $0x1,%edi
mov    $0x2,%esi
call   1090 <new_matrix_from@plt>
mov    %rax,%r13
mov    $0x2,%edi
mov    $0xb,%esi
mov    $0x2,%edx
mov    $0x1,%ecx
call   1050 <new_network@plt>
mov    %rax,%rbx
mov    $0x5dc,%ebp
nop
mov    %rbx,%rdi
mov    %r15,%rsi
mov    %r12,%rdx
movsd  0xdbf(%rip),%xmm0
call   1080 <backpropagate@plt>
mov    %rbx,%rdi
mov    %r14,%rsi
mov    %r13,%rdx
movsd  0xda9(%rip),%xmm0
call   1080 <backpropagate@plt>
add    $0xffffffff,%ebp
jne    1230 <main+0xc0>
mov    %rbx,%rdi
mov    %r15,%rsi
call   1060 <feedforward@plt>
mov    %eax,%edi
call   1030 <print_out_matrix@plt>
mov    %rbx,%rdi
mov    %r14,%rsi
call   1060 <feedforward@plt>
mov    %eax,%edi
call   1030 <print_out_matrix@plt>
mov    %rbx,%rdi
call   1070 <free_network@plt>
xor    %eax,%eax
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.ruspma_matrix = type { i32 }
%struct.ruspma_nn = type { i32 }
@__const.main.in1 = [2 x double] [double 5.000000e-01, double 4.000000e-01]
@__const.main.in2 = [2 x double] [double 2.000000e-01, double 9.000000e-01]
@__const.main.out1 = [2 x double] [double 1.000000e+00, double 0.000000e+00]
@__const.main.out2 = [2 x double] [double 0.000000e+00, double 1.000000e+00]
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca [2 x double]
%7 = alloca [2 x double]
%8 = alloca [2 x double]
%9 = alloca [2 x double]
%10 = alloca %struct.ruspma_matrix*
%11 = alloca %struct.ruspma_matrix*
%12 = alloca %struct.ruspma_matrix*
%13 = alloca %struct.ruspma_matrix*
%14 = alloca %struct.ruspma_nn*
%15 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%16 = call i32 (...) @ruspma_rand_init()
%17 = bitcast [2 x double]* %6 to i8*
%18 = bitcast [2 x double]* %7 to i8*
%19 = bitcast [2 x double]* %8 to i8*
%20 = bitcast [2 x double]* %9 to i8*
%21 = getelementptr inbounds [2 x double], [2 x double]* %6, i64 0, i64 0
%22 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %21)
store %struct.ruspma_matrix* %22, %struct.ruspma_matrix** %10
%23 = getelementptr inbounds [2 x double], [2 x double]* %7, i64 0, i64 0
%24 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %23)
store %struct.ruspma_matrix* %24, %struct.ruspma_matrix** %11
%25 = getelementptr inbounds [2 x double], [2 x double]* %8, i64 0, i64 0
%26 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %25)
store %struct.ruspma_matrix* %26, %struct.ruspma_matrix** %12
%27 = getelementptr inbounds [2 x double], [2 x double]* %9, i64 0, i64 0
%28 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %27)
store %struct.ruspma_matrix* %28, %struct.ruspma_matrix** %13
%29 = call %struct.ruspma_nn* @new_network(i32 2, i32 11, i32 2, i32 1)
store %struct.ruspma_nn* %29, %struct.ruspma_nn** %14
store i32 0, i32* %15
br label %30
30: ; preds = %42, %2
%31 = load i32, i32* %15
%32 = icmp ne i32 %31, 1500
br i1 %32, label %33, label %45
33: ; preds = %30
%34 = load %struct.ruspma_nn*, %struct.ruspma_nn** %14
%35 = load %struct.ruspma_matrix*, %struct.ruspma_matrix** %10
%36 = load %struct.ruspma_matrix*, %struct.ruspma_matrix** %12
%37 = call i32 @backpropagate(%struct.ruspma_nn* %34, %struct.ruspma_matrix* %35, %struct.ruspma_matrix* %36, double 6.500000e+00)
%38 = load %struct.ruspma_nn*, %struct.ruspma_nn** %14
%39 = load %struct.ruspma_matrix*, %struct.ruspma_matrix** %11
%40 = load %struct.ruspma_matrix*, %struct.ruspma_matrix** %13
%41 = call i32 @backpropagate(%struct.ruspma_nn* %38, %struct.ruspma_matrix* %39, %struct.ruspma_matrix* %40, double 6.500000e+00)
br label %42
42: ; preds = %33
%43 = load i32, i32* %15
%44 = add nsw i32 %43, 1
store i32 %44, i32* %15
br label %30
45: ; preds = %30
%46 = load %struct.ruspma_nn*, %struct.ruspma_nn** %14
%47 = load %struct.ruspma_matrix*, %struct.ruspma_matrix** %10
%48 = call i32 @feedforward(%struct.ruspma_nn* %46, %struct.ruspma_matrix* %47)
%49 = call i32 @print_out_matrix(i32 %48)
%50 = load %struct.ruspma_nn*, %struct.ruspma_nn** %14
%51 = load %struct.ruspma_matrix*, %struct.ruspma_matrix** %11
%52 = call i32 @feedforward(%struct.ruspma_nn* %50, %struct.ruspma_matrix* %51)
%53 = call i32 @print_out_matrix(i32 %52)
%54 = load %struct.ruspma_nn*, %struct.ruspma_nn** %14
%55 = call i32 @free_network(%struct.ruspma_nn* %54)
%56 = load i32, i32* %3
ret i32 %56
}

LLVM IR (-O2):
%struct.ruspma_matrix = type { i32 }
%struct.ruspma_nn = type { i32 }
@__const.main.in1 = [2 x double] [double 5.000000e-01, double 4.000000e-01]
@__const.main.in2 = [2 x double] [double 2.000000e-01, double 9.000000e-01]
@__const.main.out1 = [2 x double] [double 1.000000e+00, double 0.000000e+00]
@__const.main.out2 = [2 x double] [double 0.000000e+00, double 1.000000e+00]
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = alloca [2 x double]
%4 = alloca [2 x double]
%5 = alloca [2 x double]
%6 = alloca [2 x double]
%7 = tail call i32 (...) @ruspma_rand_init()
%8 = bitcast [2 x double]* %3 to i8*
%9 = bitcast [2 x double]* %4 to i8*
%10 = bitcast [2 x double]* %5 to i8*
%11 = bitcast [2 x double]* %6 to i8*
%12 = getelementptr inbounds [2 x double], [2 x double]* %3, i64 0, i64 0
%13 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %12)
%14 = getelementptr inbounds [2 x double], [2 x double]* %4, i64 0, i64 0
%15 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %14)
%16 = getelementptr inbounds [2 x double], [2 x double]* %5, i64 0, i64 0
%17 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %16)
%18 = getelementptr inbounds [2 x double], [2 x double]* %6, i64 0, i64 0
%19 = call %struct.ruspma_matrix* @new_matrix_from(i32 1, i32 2, double* %18)
%20 = call %struct.ruspma_nn* @new_network(i32 2, i32 11, i32 2, i32 1)
br label %21
21: ; preds = %2, %21
%22 = phi i32 [ 0, %2 ], [ %25, %21 ]
%23 = call i32 @backpropagate(%struct.ruspma_nn* %20, %struct.ruspma_matrix* %13, %struct.ruspma_matrix* %17, double 6.500000e+00)
%24 = call i32 @backpropagate(%struct.ruspma_nn* %20, %struct.ruspma_matrix* %15, %struct.ruspma_matrix* %19, double 6.500000e+00)
%25 = add nuw nsw i32 %22, 1
%26 = icmp eq i32 %25, 1500
br i1 %26, label %27, label %21
27: ; preds = %21
%28 = call i32 @feedforward(%struct.ruspma_nn* %20, %struct.ruspma_matrix* %13)
%29 = call i32 @print_out_matrix(i32 %28)
%30 = call i32 @feedforward(%struct.ruspma_nn* %20, %struct.ruspma_matrix* %15)
%31 = call i32 @print_out_matrix(i32 %30)
%32 = call i32 @free_network(%struct.ruspma_nn* %20)
ret i32 0
}