float factln(int n) {
  float gammln(float xx);
  void nrerror(char error_text[]);
  static float a[101];
  if (n < 0)
    nrerror("Negative factorial in routine factln");
  if (n <= 1)
    return 0.0;
  if (n <= 100)
    return a[n] ? a[n] : (a[n] = gammln(n + 1.0));
  else
    return gammln(n + 1.0);
}


x86 assembly (clang, -O0):
<factln>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %edi,-0x8(%rbp)
cmpl   $0x0,-0x8(%rbp)
jge    1141 <factln+0x21>
lea    0xecc(%rip),%rdi
call   1030 <nrerror@plt>
cmpl   $0x1,-0x8(%rbp)
jg     1158 <factln+0x38>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1200 <factln+0xe0>
cmpl   $0x64,-0x8(%rbp)
jg     11e1 <factln+0xc1>
movslq -0x8(%rbp),%rcx
lea    0x2ed3(%rip),%rax
movss  (%rax,%rcx,4),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    1189 <factln+0x69>
jp     1189 <factln+0x69>
jmp    11a3 <factln+0x83>
movslq -0x8(%rbp),%rcx
lea    0x2eac(%rip),%rax
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0xc(%rbp)
jmp    11d2 <factln+0xb2>
cvtsi2sdl -0x8(%rbp),%xmm0
movsd  0xe50(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
call   1040 <gammln@plt>
movslq -0x8(%rbp),%rcx
lea    0x2e78(%rip),%rax
movss  %xmm0,(%rax,%rcx,4)
movss  %xmm0,-0xc(%rbp)
movss  -0xc(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    1200 <factln+0xe0>
cvtsi2sdl -0x8(%rbp),%xmm0
movsd  0xe12(%rip),%xmm1
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
call   1040 <gammln@plt>
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<factln>:
push   %r14
push   %rbx
push   %rax
test   %edi,%edi
js     116e <factln+0x4e>
xorps  %xmm0,%xmm0
cmp    $0x2,%edi
jb     117d <factln+0x5d>
cmp    $0x64,%edi
ja     1185 <factln+0x65>
mov    %edi,%ebx
lea    0x2f02(%rip),%r14
movss  (%r14,%rbx,4),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    117d <factln+0x5d>
jp     117d <factln+0x5d>
xorps  %xmm0,%xmm0
cvtsi2sd %edi,%xmm0
addsd  0xea3(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
call   1040 <gammln@plt>
movss  %xmm0,(%r14,%rbx,4)
jmp    117d <factln+0x5d>
lea    0xe93(%rip),%rdi
call   1030 <nrerror@plt>
xorps  %xmm0,%xmm0
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
xorps  %xmm0,%xmm0
cvtsi2sd %edi,%xmm0
addsd  0xe6c(%rip),%xmm0
cvtsd2ss %xmm0,%xmm0
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1040 <gammln@plt>

LLVM IR (-O0):
@factln.a = internal global [101 x float] zeroinitializer
@.str = [37 x i8] c"Negative factorial in routine factln\00"
define float @factln(i32 %0) {
%2 = alloca float
%3 = alloca i32
store i32 %0, i32* %3
%4 = load i32, i32* %3
%5 = icmp slt i32 %4, 0
br i1 %5, label %6, label %7
6: ; preds = %1
br label %7
7: ; preds = %6, %1
%8 = load i32, i32* %3
%9 = icmp sle i32 %8, 1
br i1 %9, label %10, label %11
10: ; preds = %7
store float 0.000000e+00, float* %2
br label %42
11: ; preds = %7
%12 = load i32, i32* %3
%13 = icmp sle i32 %12, 100
br i1 %13, label %14, label %36
14: ; preds = %11
%15 = load i32, i32* %3
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds [101 x float], [101 x float]* @factln.a, i64 0, i64 %16
%18 = load float, float* %17
%19 = fcmp une float %18, 0.000000e+00
br i1 %19, label %20, label %25
20: ; preds = %14
%21 = load i32, i32* %3
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds [101 x float], [101 x float]* @factln.a, i64 0, i64 %22
%24 = load float, float* %23
br label %34
25: ; preds = %14
%26 = load i32, i32* %3
%27 = sitofp i32 %26 to double
%28 = fadd double %27, 1.000000e+00
%29 = fptrunc double %28 to float
%30 = call float @gammln(float %29)
%31 = load i32, i32* %3
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds [101 x float], [101 x float]* @factln.a, i64 0, i64 %32
store float %30, float* %33
br label %34
34: ; preds = %25, %20
%35 = phi float [ %24, %20 ], [ %30, %25 ]
store float %35, float* %2
br label %42
36: ; preds = %11
%37 = load i32, i32* %3
%38 = sitofp i32 %37 to double
%39 = fadd double %38, 1.000000e+00
%40 = fptrunc double %39 to float
%41 = call float @gammln(float %40)
store float %41, float* %2
br label %42
42: ; preds = %36, %34, %10
%43 = load float, float* %2
ret float %43
}

LLVM IR (-O2):
@factln.a = internal unnamed_addr global [101 x float] zeroinitializer
@.str = [37 x i8] c"Negative factorial in routine factln\00"
define float @factln(i32 %0) {
%2 = icmp slt i32 %0, 0
br i1 %2, label %3, label %4
3: ; preds = %1
tail call void @nrerror(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str, i64 0, i64 0))
br label %23
4: ; preds = %1
%5 = icmp ult i32 %0, 2
br i1 %5, label %23, label %6
6: ; preds = %4
%7 = icmp ult i32 %0, 101
br i1 %7, label %8, label %18
8: ; preds = %6
%9 = zext i32 %0 to i64
%10 = getelementptr inbounds [101 x float], [101 x float]* @factln.a, i64 0, i64 %9
%11 = load float, float* %10
%12 = fcmp une float %11, 0.000000e+00
br i1 %12, label %23, label %13
13: ; preds = %8
%14 = sitofp i32 %0 to double
%15 = fadd double %14, 1.000000e+00
%16 = fptrunc double %15 to float
%17 = tail call float @gammln(float %16)
store float %17, float* %10
br label %23
18: ; preds = %6
%19 = sitofp i32 %0 to double
%20 = fadd double %19, 1.000000e+00
%21 = fptrunc double %20 to float
%22 = tail call float @gammln(float %21)
br label %23
23: ; preds = %3, %13, %8, %4, %18
%24 = phi float [ %22, %18 ], [ 0.000000e+00, %4 ], [ %17, %13 ], [ %11, %8 ], [ 0.000000e+00, %3 ]
ret float %24
}