#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 *, float, float, ...);
float randWeight(int, int);
void teachNeuron(int selection, int truthTable[4][4], int statesArray[4][2],
                 int erasAmount, int reportFreq, float bias, float eta,
                 float threshold, int statesAmount) {
  int i, j, wartoscOczekiwana, x0, x1 = 0, min = -2, max = 2;
  float w0, w1, w2, dw0, dw1, dw2, max_err, min_err, adder, blad = 0.0;
  --selection;
  w0 = randWeight(min, max);
  w1 = randWeight(min, max);
  w2 = randWeight(min, max);
  printf("Wylosowane wagi poczatkowe to: w0 = %2.2f, w1 = %2.2f, w2 = %2.2f\n",
         w0, w1, w2);
  for (; i < erasAmount; i++) {
    for (; j < statesAmount; j++) {
      adder = 0;
      w0 = w0 + dw0;
      w1 = w1 + dw1;
      w2 = w2 + dw2;
      x0 = statesArray[j][0];
      x1 = statesArray[j][1];
      wartoscOczekiwana = truthTable[selection][j];
      adder = w0 * bias + w1 * x0 + w2 * x1;
      blad = wartoscOczekiwana - adder;
      dw0 = eta * blad * bias;
      dw1 = eta * blad * x0;
      dw2 = eta * blad * x1;
      if (blad > max_err) {
        max_err = blad;
      }
      if (blad < min_err) {
        min_err = blad;
      }
      if (i % reportFreq == 0) {
        printf("Zarejestrowany blad dla ostatnich %d epok to: %f\n", reportFreq,
               max_err - min_err);
        min_err = 0;
        max_err = 0;
      }
    }
    j = 0;
  }
  printf("Dobrane wagi koncowe to: w0 = %2.2f, w1 = %2.2f, w2 = %2.2f\n", w0,
         w1, w2);
}


x86 assembly (clang, -O0):
<teachNeuron>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
movss  %xmm0,-0x24(%rbp)
movss  %xmm1,-0x28(%rbp)
movss  %xmm2,-0x2c(%rbp)
mov    %r9d,-0x30(%rbp)
movl   $0x0,-0x44(%rbp)
movl   $0xfffffffe,-0x48(%rbp)
movl   $0x2,-0x4c(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x74(%rbp)
mov    -0x4(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
mov    -0x48(%rbp),%edi
mov    -0x4c(%rbp),%esi
call   1040 <randWeight@plt>
movss  %xmm0,-0x50(%rbp)
mov    -0x48(%rbp),%edi
mov    -0x4c(%rbp),%esi
call   1040 <randWeight@plt>
movss  %xmm0,-0x54(%rbp)
mov    -0x48(%rbp),%edi
mov    -0x4c(%rbp),%esi
call   1040 <randWeight@plt>
movss  %xmm0,-0x58(%rbp)
movss  -0x50(%rbp),%xmm0
movss  -0x54(%rbp),%xmm1
movss  -0x58(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
lea    0xe40(%rip),%rdi
mov    $0x3,%al
call   1030 <printf@plt>
mov    -0x34(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1374 <teachNeuron+0x254>
jmp    11d8 <teachNeuron+0xb8>
mov    -0x38(%rbp),%eax
cmp    -0x30(%rbp),%eax
jge    135f <teachNeuron+0x23f>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x70(%rbp)
movss  -0x50(%rbp),%xmm0
addss  -0x5c(%rbp),%xmm0
movss  %xmm0,-0x50(%rbp)
movss  -0x54(%rbp),%xmm0
addss  -0x60(%rbp),%xmm0
movss  %xmm0,-0x54(%rbp)
movss  -0x58(%rbp),%xmm0
addss  -0x64(%rbp),%xmm0
movss  %xmm0,-0x58(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,8),%eax
mov    %eax,-0x40(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x38(%rbp),%rcx
mov    0x4(%rax,%rcx,8),%eax
mov    %eax,-0x44(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x4(%rbp),%rcx
shl    $0x4,%rcx
add    %rcx,%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x3c(%rbp)
movss  -0x50(%rbp),%xmm1
movss  -0x24(%rbp),%xmm2
movss  -0x54(%rbp),%xmm0
cvtsi2ssl -0x40(%rbp),%xmm3
mulss  %xmm3,%xmm0
mulss  %xmm2,%xmm1
addss  %xmm0,%xmm1
movss  -0x58(%rbp),%xmm0
cvtsi2ssl -0x44(%rbp),%xmm2
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x70(%rbp)
cvtsi2ssl -0x3c(%rbp),%xmm0
subss  -0x70(%rbp),%xmm0
movss  %xmm0,-0x74(%rbp)
movss  -0x28(%rbp),%xmm0
mulss  -0x74(%rbp),%xmm0
mulss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x5c(%rbp)
movss  -0x28(%rbp),%xmm0
mulss  -0x74(%rbp),%xmm0
cvtsi2ssl -0x40(%rbp),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x60(%rbp)
movss  -0x28(%rbp),%xmm0
mulss  -0x74(%rbp),%xmm0
cvtsi2ssl -0x44(%rbp),%xmm1
mulss  %xmm1,%xmm0
movss  %xmm0,-0x64(%rbp)
movss  -0x74(%rbp),%xmm0
ucomiss -0x68(%rbp),%xmm0
jbe    12f2 <teachNeuron+0x1d2>
movss  -0x74(%rbp),%xmm0
movss  %xmm0,-0x68(%rbp)
movss  -0x74(%rbp),%xmm1
movss  -0x6c(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    130f <teachNeuron+0x1ef>
movss  -0x74(%rbp),%xmm0
movss  %xmm0,-0x6c(%rbp)
mov    -0x34(%rbp),%eax
cltd
idivl  -0x20(%rbp)
cmp    $0x0,%edx
jne    134c <teachNeuron+0x22c>
cvtsi2ssl -0x20(%rbp),%xmm0
movss  -0x68(%rbp),%xmm1
subss  -0x6c(%rbp),%xmm1
lea    0xd0e(%rip),%rdi
mov    $0x2,%al
call   1030 <printf@plt>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x6c(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x68(%rbp)
jmp    1351 <teachNeuron+0x231>
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    11d8 <teachNeuron+0xb8>
movl   $0x0,-0x38(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11c7 <teachNeuron+0xa7>
movss  -0x50(%rbp),%xmm0
movss  -0x54(%rbp),%xmm1
movss  -0x58(%rbp),%xmm2
cvtss2sd %xmm2,%xmm2
lea    0xce7(%rip),%rdi
mov    $0x3,%al
call   1030 <printf@plt>
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<teachNeuron>:
sub    $0x18,%rsp
mov    $0xfffffffe,%edi
mov    $0x2,%esi
call   1040 <randWeight@plt>
movss  %xmm0,0xc(%rsp)
mov    $0xfffffffe,%edi
mov    $0x2,%esi
call   1040 <randWeight@plt>
movss  %xmm0,0x8(%rsp)
mov    $0xfffffffe,%edi
mov    $0x2,%esi
call   1040 <randWeight@plt>
cvtss2sd %xmm0,%xmm2
movsd  %xmm2,0x10(%rsp)
lea    0xe92(%rip),%rdi
movss  0xc(%rsp),%xmm0
movss  0x8(%rsp),%xmm1
mov    $0x3,%al
call   1030 <printf@plt>
lea    0xebb(%rip),%rdi
movss  0xc(%rsp),%xmm0
movss  0x8(%rsp),%xmm1
movsd  0x10(%rsp),%xmm2
mov    $0x3,%al
add    $0x18,%rsp
jmp    1030 <printf@plt>

LLVM IR (-O0):
@.str = [67 x i8] c"Wylosowane wagi poczatkowe to: w0 = %2.2f, w1 = %2.2f, w2 = %2.2f\0A\00"
@.str.1 = [50 x i8] c"Zarejestrowany blad dla ostatnich %d epok to: %f\0A\00"
@.str.2 = [61 x i8] c"Dobrane wagi koncowe to: w0 = %2.2f, w1 = %2.2f, w2 = %2.2f\0A\00"
define void @teachNeuron(i32 %0, [4 x i32]* %1, [2 x i32]* %2, i32 %3, i32 %4, float %5, float %6, float %7, i32 %8) {
%10 = alloca i32
%11 = alloca [4 x i32]*
%12 = alloca [2 x i32]*
%13 = alloca i32
%14 = alloca i32
%15 = alloca float
%16 = alloca float
%17 = alloca float
%18 = alloca i32
%19 = alloca i32
%20 = alloca i32
%21 = alloca i32
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
%25 = alloca i32
%26 = alloca float
%27 = alloca float
%28 = alloca float
%29 = alloca float
%30 = alloca float
%31 = alloca float
%32 = alloca float
%33 = alloca float
%34 = alloca float
%35 = alloca float
store i32 %0, i32* %10
store [4 x i32]* %1, [4 x i32]** %11
store [2 x i32]* %2, [2 x i32]** %12
store i32 %3, i32* %13
store i32 %4, i32* %14
store float %5, float* %15
store float %6, float* %16
store float %7, float* %17
store i32 %8, i32* %18
store i32 0, i32* %23
store i32 -2, i32* %24
store i32 2, i32* %25
store float 0.000000e+00, float* %35
%36 = load i32, i32* %10
%37 = add nsw i32 %36, -1
store i32 %37, i32* %10
%38 = load i32, i32* %24
%39 = load i32, i32* %25
%40 = call float @randWeight(i32 %38, i32 %39)
store float %40, float* %26
%41 = load i32, i32* %24
%42 = load i32, i32* %25
%43 = call float @randWeight(i32 %41, i32 %42)
store float %43, float* %27
%44 = load i32, i32* %24
%45 = load i32, i32* %25
%46 = call float @randWeight(i32 %44, i32 %45)
store float %46, float* %28
%47 = load float, float* %26
%48 = load float, float* %27
%49 = load float, float* %28
%50 = fpext float %49 to double
%51 = call i32 (i8*, float, float, ...) @printf(i8* getelementptr inbounds ([67 x i8], [67 x i8]* @.str, i64 0, i64 0), float %47, float %48, double %50)
br label %52
52: ; preds = %151, %9
%53 = load i32, i32* %19
%54 = load i32, i32* %13
%55 = icmp slt i32 %53, %54
br i1 %55, label %56, label %154
56: ; preds = %52
br label %57
57: ; preds = %147, %56
%58 = load i32, i32* %20
%59 = load i32, i32* %18
%60 = icmp slt i32 %58, %59
br i1 %60, label %61, label %150
61: ; preds = %57
store float 0.000000e+00, float* %34
%62 = load float, float* %26
%63 = load float, float* %29
%64 = fadd float %62, %63
store float %64, float* %26
%65 = load float, float* %27
%66 = load float, float* %30
%67 = fadd float %65, %66
store float %67, float* %27
%68 = load float, float* %28
%69 = load float, float* %31
%70 = fadd float %68, %69
store float %70, float* %28
%71 = load [2 x i32]*, [2 x i32]** %12
%72 = load i32, i32* %20
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds [2 x i32], [2 x i32]* %71, i64 %73
%75 = getelementptr inbounds [2 x i32], [2 x i32]* %74, i64 0, i64 0
%76 = load i32, i32* %75
store i32 %76, i32* %22
%77 = load [2 x i32]*, [2 x i32]** %12
%78 = load i32, i32* %20
%79 = sext i32 %78 to i64
%80 = getelementptr inbounds [2 x i32], [2 x i32]* %77, i64 %79
%81 = getelementptr inbounds [2 x i32], [2 x i32]* %80, i64 0, i64 1
%82 = load i32, i32* %81
store i32 %82, i32* %23
%83 = load [4 x i32]*, [4 x i32]** %11
%84 = load i32, i32* %10
%85 = sext i32 %84 to i64
%86 = getelementptr inbounds [4 x i32], [4 x i32]* %83, i64 %85
%87 = load i32, i32* %20
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds [4 x i32], [4 x i32]* %86, i64 0, i64 %88
%90 = load i32, i32* %89
store i32 %90, i32* %21
%91 = load float, float* %26
%92 = load float, float* %15
%93 = load float, float* %27
%94 = load i32, i32* %22
%95 = sitofp i32 %94 to float
%96 = fmul float %93, %95
%97 = call float @llvm.fmuladd.f32(float %91, float %92, float %96)
%98 = load float, float* %28
%99 = load i32, i32* %23
%100 = sitofp i32 %99 to float
%101 = call float @llvm.fmuladd.f32(float %98, float %100, float %97)
store float %101, float* %34
%102 = load i32, i32* %21
%103 = sitofp i32 %102 to float
%104 = load float, float* %34
%105 = fsub float %103, %104
store float %105, float* %35
%106 = load float, float* %16
%107 = load float, float* %35
%108 = fmul float %106, %107
%109 = load float, float* %15
%110 = fmul float %108, %109
store float %110, float* %29
%111 = load float, float* %16
%112 = load float, float* %35
%113 = fmul float %111, %112
%114 = load i32, i32* %22
%115 = sitofp i32 %114 to float
%116 = fmul float %113, %115
store float %116, float* %30
%117 = load float, float* %16
%118 = load float, float* %35
%119 = fmul float %117, %118
%120 = load i32, i32* %23
%121 = sitofp i32 %120 to float
%122 = fmul float %119, %121
store float %122, float* %31
%123 = load float, float* %35
%124 = load float, float* %32
%125 = fcmp ogt float %123, %124
br i1 %125, label %126, label %128
126: ; preds = %61
%127 = load float, float* %35
store float %127, float* %32
br label %128
128: ; preds = %126, %61
%129 = load float, float* %35
%130 = load float, float* %33
%131 = fcmp olt float %129, %130
br i1 %131, label %132, label %134
132: ; preds = %128
%133 = load float, float* %35
store float %133, float* %33
br label %134
134: ; preds = %132, %128
%135 = load i32, i32* %19
%136 = load i32, i32* %14
%137 = srem i32 %135, %136
%138 = icmp eq i32 %137, 0
br i1 %138, label %139, label %146
139: ; preds = %134
%140 = load i32, i32* %14
%141 = sitofp i32 %140 to float
%142 = load float, float* %32
%143 = load float, float* %33
%144 = fsub float %142, %143
%145 = call i32 (i8*, float, float, ...) @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.1, i64 0, i64 0), float %141, float %144)
store float 0.000000e+00, float* %33
store float 0.000000e+00, float* %32
br label %146
146: ; preds = %139, %134
br label %147
147: ; preds = %146
%148 = load i32, i32* %20
%149 = add nsw i32 %148, 1
store i32 %149, i32* %20
br label %57
150: ; preds = %57
store i32 0, i32* %20
br label %151
151: ; preds = %150
%152 = load i32, i32* %19
%153 = add nsw i32 %152, 1
store i32 %153, i32* %19
br label %52
154: ; preds = %52
%155 = load float, float* %26
%156 = load float, float* %27
%157 = load float, float* %28
%158 = fpext float %157 to double
%159 = call i32 (i8*, float, float, ...) @printf(i8* getelementptr inbounds ([61 x i8], [61 x i8]* @.str.2, i64 0, i64 0), float %155, float %156, double %158)
ret void
}

LLVM IR (-O2):
@.str = [67 x i8] c"Wylosowane wagi poczatkowe to: w0 = %2.2f, w1 = %2.2f, w2 = %2.2f\0A\00"
@.str.2 = [61 x i8] c"Dobrane wagi koncowe to: w0 = %2.2f, w1 = %2.2f, w2 = %2.2f\0A\00"
define void @teachNeuron(i32 %0, [4 x i32]* nocapture %1, [2 x i32]* nocapture %2, i32 %3, i32 %4, float %5, float %6, float %7, i32 %8) {
%10 = tail call float @randWeight(i32 -2, i32 2)
%11 = tail call float @randWeight(i32 -2, i32 2)
%12 = tail call float @randWeight(i32 -2, i32 2)
%13 = fpext float %12 to double
%14 = tail call i32 (i8*, float, float, ...) @printf(i8* getelementptr inbounds ([67 x i8], [67 x i8]* @.str, i64 0, i64 0), float %10, float %11, double %13)
%15 = tail call i32 (i8*, float, float, ...) @printf(i8* getelementptr inbounds ([61 x i8], [61 x i8]* @.str.2, i64 0, i64 0), float %10, float %11, double %13)
ret void
}