#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 */
long double exp(double);
double pow(long double, int);
long double sqrt(long double);
long double get_single_gaussian_statescore(long double mu,
                                           long double sigma_square,
                                           long double letter) {
  long double res;
  if (sigma_square <= 0.0) {
    return 0.0;
  } else {
    res = exp(0.0 - (pow((letter - mu), 2) / (2.0 * sigma_square))) /
          sqrt(sigma_square * 2.0 * 3.141592655);
    return res;
  }
}


x86 assembly (clang, -O0):
<get_single_gaussian_statescore>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
fldt   0x30(%rbp)
fldt   0x20(%rbp)
fldt   0x10(%rbp)
fstpt  -0x20(%rbp)
fstpt  -0x30(%rbp)
fstpt  -0x40(%rbp)
fldt   -0x30(%rbp)
fldz
fucomip %st(1),%st
fstp   %st(0)
jb     116b <get_single_gaussian_statescore+0x3b>
jmp    1161 <get_single_gaussian_statescore+0x31>
fldz
fstpt  -0x10(%rbp)
jmp    11ca <get_single_gaussian_statescore+0x9a>
fldt   -0x40(%rbp)
fldt   -0x20(%rbp)
fsubrp %st,%st(1)
mov    %rsp,%rax
fstpt  (%rax)
mov    $0x2,%edi
call   1040 <pow@plt>
movsd  %xmm0,-0x58(%rbp)
fldl   -0x58(%rbp)
fldt   -0x30(%rbp)
fadd   %st,%st(0)
fdivrp %st,%st(1)
fldz
fsubp  %st,%st(1)
fstpl  -0x60(%rbp)
movsd  -0x60(%rbp),%xmm0
call   1030 <exp@plt>
fstpt  -0x6c(%rbp)
fldt   -0x30(%rbp)
fadd   %st,%st(0)
fldl   0xe50(%rip)
fmulp  %st,%st(1)
mov    %rsp,%rax
fstpt  (%rax)
call   1050 <sqrt@plt>
fldt   -0x6c(%rbp)
fdivp  %st,%st(1)
fstpt  -0x50(%rbp)
fldt   -0x50(%rbp)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_single_gaussian_statescore>:
sub    $0x48,%rsp
fldt   0x70(%rsp)
fldt   0x60(%rsp)
fldt   0x50(%rsp)
fldz
fucomi %st(2),%st
jae    11d0 <get_single_gaussian_statescore+0xa0>
fstp   %st(0)
fsubrp %st,%st(2)
fxch   %st(1)
fstpt  (%rsp)
mov    $0x2,%edi
fstpt  0x1c(%rsp)
call   1040 <pow@plt>
movsd  %xmm0,0x30(%rsp)
fldt   0x1c(%rsp)
fadd   %st,%st(0)
fld    %st(0)
fstpt  0x1c(%rsp)
fdivrl 0x30(%rsp)
fldz
fld    %st(0)
fstpt  0x3c(%rsp)
fsubp  %st,%st(1)
fstpl  0x28(%rsp)
movsd  0x28(%rsp),%xmm0
call   1030 <exp@plt>
fldt   0x1c(%rsp)
fmull  0xe66(%rip)
fld    %st(0)
fsqrt
fldt   0x3c(%rsp)
fxch   %st(2)
fucomi %st(2),%st
fstp   %st(2)
jae    11c2 <get_single_gaussian_statescore+0x92>
fstp   %st(0)
fstpt  (%rsp)
fstpt  0x1c(%rsp)
call   1050 <sqrt@plt>
fldt   0x1c(%rsp)
fldz
fxch   %st(1)
fxch   %st(2)
fstp   %st(1)
fdivrp %st,%st(1)
fldz
fldz
fldz
fxch   %st(2)
fxch   %st(3)
fstp   %st(3)
fstp   %st(0)
fstp   %st(0)
add    $0x48,%rsp
ret

LLVM IR (-O0):
define x86_fp80 @get_single_gaussian_statescore(x86_fp80 %0, x86_fp80 %1, x86_fp80 %2) {
%4 = alloca x86_fp80
%5 = alloca x86_fp80
%6 = alloca x86_fp80
%7 = alloca x86_fp80
%8 = alloca x86_fp80
store x86_fp80 %0, x86_fp80* %5
store x86_fp80 %1, x86_fp80* %6
store x86_fp80 %2, x86_fp80* %7
%9 = load x86_fp80, x86_fp80* %6
%10 = fcmp ole x86_fp80 %9, 0xK00000000000000000000
br i1 %10, label %11, label %12
11: ; preds = %3
store x86_fp80 0xK00000000000000000000, x86_fp80* %4
br label %30
12: ; preds = %3
%13 = load x86_fp80, x86_fp80* %7
%14 = load x86_fp80, x86_fp80* %5
%15 = fsub x86_fp80 %13, %14
%16 = call double @pow(x86_fp80 %15, i32 2)
%17 = fpext double %16 to x86_fp80
%18 = load x86_fp80, x86_fp80* %6
%19 = fmul x86_fp80 0xK40008000000000000000, %18
%20 = fdiv x86_fp80 %17, %19
%21 = fsub x86_fp80 0xK00000000000000000000, %20
%22 = fptrunc x86_fp80 %21 to double
%23 = call x86_fp80 @exp(double %22)
%24 = load x86_fp80, x86_fp80* %6
%25 = fmul x86_fp80 %24, 0xK40008000000000000000
%26 = fmul x86_fp80 %25, 0xK4000C90FDAA3A50B4000
%27 = call x86_fp80 @sqrt(x86_fp80 %26)
%28 = fdiv x86_fp80 %23, %27
store x86_fp80 %28, x86_fp80* %8
%29 = load x86_fp80, x86_fp80* %8
store x86_fp80 %29, x86_fp80* %4
br label %30
30: ; preds = %12, %11
%31 = load x86_fp80, x86_fp80* %4
ret x86_fp80 %31
}

LLVM IR (-O2):
define x86_fp80 @get_single_gaussian_statescore(x86_fp80 %0, x86_fp80 %1, x86_fp80 %2) {
%4 = fcmp ugt x86_fp80 %1, 0xK00000000000000000000
br i1 %4, label %5, label %17
5: ; preds = %3
%6 = fsub x86_fp80 %2, %0
%7 = tail call double @pow(x86_fp80 %6, i32 2)
%8 = fpext double %7 to x86_fp80
%9 = fmul x86_fp80 %1, 0xK40008000000000000000
%10 = fdiv x86_fp80 %8, %9
%11 = fsub x86_fp80 0xK00000000000000000000, %10
%12 = fptrunc x86_fp80 %11 to double
%13 = tail call x86_fp80 @exp(double %12)
%14 = fmul x86_fp80 %9, 0xK4000C90FDAA3A50B4000
%15 = tail call x86_fp80 @sqrt(x86_fp80 %14)
%16 = fdiv x86_fp80 %13, %15
br label %17
17: ; preds = %3, %5
%18 = phi x86_fp80 [ %16, %5 ], [ 0xK00000000000000000000, %3 ]
ret x86_fp80 %18
}