#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 */
float cephes_lgamf(float);
float expf(float);
float log(float);
float cephes_igamf(float a, float x) {
  const float MAXLOGF = 88.72283905206835;
  const float MACHEPF = 5.9604644775390625E-8;
  float ans, ax, c, r;
  ax = a * log(x) - x - cephes_lgamf(a);
  if (ax < -MAXLOGF)
    return 0.0;
  ax = expf(ax);
  r = a;
  c = 1.0;
  ans = 1.0;
  do {
    r += 1.0;
    c *= x / r;
    ans += c;
  } while (c / ans > MACHEPF);
  return ans * ax / a;
}


x86 assembly (clang, -O0):
<cephes_igamf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  0xebe(%rip),%xmm0
movss  %xmm0,-0x10(%rbp)
movss  0xead(%rip),%xmm0
movss  %xmm0,-0x14(%rbp)
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0xc(%rbp),%xmm0
call   1050 <log@plt>
movaps %xmm0,%xmm2
movss  -0x2c(%rbp),%xmm0
movss  -0xc(%rbp),%xmm1
movd   %xmm1,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm1
mulss  %xmm2,%xmm0
addss  %xmm1,%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x8(%rbp),%xmm0
call   1040 <cephes_lgamf@plt>
movaps %xmm0,%xmm1
movss  -0x28(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  0xe46(%rip),%xmm0
ucomiss -0x1c(%rbp),%xmm0
jbe    11d1 <cephes_igamf+0xa1>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1274 <cephes_igamf+0x144>
movss  -0x1c(%rbp),%xmm0
call   1030 <expf@plt>
movss  %xmm0,-0x1c(%rbp)
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
movss  0xe1a(%rip),%xmm0
movss  %xmm0,-0x20(%rbp)
movss  0xe0d(%rip),%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x24(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xdfb(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0xc(%rbp),%xmm0
divss  -0x24(%rbp),%xmm0
mulss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm0
addss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x20(%rbp),%xmm0
divss  -0x18(%rbp),%xmm0
movss  0xdad(%rip),%xmm1
ucomiss %xmm1,%xmm0
ja     1204 <cephes_igamf+0xd4>
movss  -0x18(%rbp),%xmm0
mulss  -0x1c(%rbp),%xmm0
divss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<cephes_igamf>:
sub    $0x18,%rsp
movss  %xmm1,0x10(%rsp)
movss  %xmm0,0xc(%rsp)
movaps %xmm1,%xmm0
call   1050 <log@plt>
movaps %xmm0,%xmm1
movss  0xc(%rsp),%xmm0
mulss  %xmm0,%xmm1
subss  0x10(%rsp),%xmm1
movss  %xmm1,0x14(%rsp)
call   1040 <cephes_lgamf@plt>
movss  0x14(%rsp),%xmm2
subss  %xmm0,%xmm2
xorps  %xmm0,%xmm0
movss  0xe85(%rip),%xmm1
ucomiss %xmm2,%xmm1
ja     11d8 <cephes_igamf+0xa8>
movaps %xmm2,%xmm0
call   1030 <expf@plt>
movss  0xe74(%rip),%xmm2
movss  0xe70(%rip),%xmm3
movaps %xmm2,%xmm1
movaps %xmm2,%xmm4
movss  0xc(%rsp),%xmm8
movaps %xmm8,%xmm5
movss  0x10(%rsp),%xmm7
nop
addss  %xmm2,%xmm5
movaps %xmm7,%xmm6
divss  %xmm5,%xmm6
mulss  %xmm6,%xmm4
addss  %xmm4,%xmm1
movaps %xmm4,%xmm6
divss  %xmm1,%xmm6
ucomiss %xmm3,%xmm6
ja     11b0 <cephes_igamf+0x80>
mulss  %xmm1,%xmm0
divss  %xmm8,%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
define float @cephes_igamf(float %0, float %1) {
%3 = alloca float
%4 = alloca float
%5 = alloca float
%6 = alloca float
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca float
store float %0, float* %4
store float %1, float* %5
store float 0x40562E4300000000, float* %6
store float 0x3E70000000000000, float* %7
%12 = load float, float* %4
%13 = load float, float* %5
%14 = call float @log(float %13)
%15 = load float, float* %5
%16 = fneg float %15
%17 = call float @llvm.fmuladd.f32(float %12, float %14, float %16)
%18 = load float, float* %4
%19 = call float @cephes_lgamf(float %18)
%20 = fsub float %17, %19
store float %20, float* %9
%21 = load float, float* %9
%22 = fcmp olt float %21, 0xC0562E4300000000
br i1 %22, label %23, label %24
23: ; preds = %2
store float 0.000000e+00, float* %3
br label %52
24: ; preds = %2
%25 = load float, float* %9
%26 = call float @expf(float %25)
store float %26, float* %9
%27 = load float, float* %4
store float %27, float* %11
store float 1.000000e+00, float* %10
store float 1.000000e+00, float* %8
br label %28
28: ; preds = %41, %24
%29 = load float, float* %11
%30 = fpext float %29 to double
%31 = fadd double %30, 1.000000e+00
%32 = fptrunc double %31 to float
store float %32, float* %11
%33 = load float, float* %5
%34 = load float, float* %11
%35 = fdiv float %33, %34
%36 = load float, float* %10
%37 = fmul float %36, %35
store float %37, float* %10
%38 = load float, float* %10
%39 = load float, float* %8
%40 = fadd float %39, %38
store float %40, float* %8
br label %41
41: ; preds = %28
%42 = load float, float* %10
%43 = load float, float* %8
%44 = fdiv float %42, %43
%45 = fcmp ogt float %44, 0x3E70000000000000
br i1 %45, label %28, label %46
46: ; preds = %41
%47 = load float, float* %8
%48 = load float, float* %9
%49 = fmul float %47, %48
%50 = load float, float* %4
%51 = fdiv float %49, %50
store float %51, float* %3
br label %52
52: ; preds = %46, %23
%53 = load float, float* %3
ret float %53
}

LLVM IR (-O2):
define float @cephes_igamf(float %0, float %1) {
%3 = tail call float @log(float %1)
%4 = fneg float %1
%5 = tail call float @llvm.fmuladd.f32(float %0, float %3, float %4)
%6 = tail call float @cephes_lgamf(float %0)
%7 = fsub float %5, %6
%8 = fcmp olt float %7, 0xC0562E4300000000
br i1 %8, label %24, label %9
9: ; preds = %2
%10 = tail call float @expf(float %7)
br label %11
11: ; preds = %11, %9
%12 = phi float [ 1.000000e+00, %9 ], [ %18, %11 ]
%13 = phi float [ 1.000000e+00, %9 ], [ %17, %11 ]
%14 = phi float [ %0, %9 ], [ %15, %11 ]
%15 = fadd float %14, 1.000000e+00
%16 = fdiv float %1, %15
%17 = fmul float %13, %16
%18 = fadd float %12, %17
%19 = fdiv float %17, %18
%20 = fcmp ogt float %19, 0x3E70000000000000
br i1 %20, label %11, label %21
21: ; preds = %11
%22 = fmul float %10, %18
%23 = fdiv float %22, %0
br label %24
24: ; preds = %2, %21
%25 = phi float [ %23, %21 ], [ 0.000000e+00, %2 ]
ret float %25
}